mirror of
https://github.com/vrana/adminer.git
synced 2026-03-25 14:00:05 +01:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7679701ce | ||
|
|
b7258d2e95 | ||
|
|
c51d9919fe | ||
|
|
78c431ab20 | ||
|
|
916889bb8e | ||
|
|
e8b15c99f4 | ||
|
|
a460019535 | ||
|
|
ea5a7453fb | ||
|
|
587f6a5375 | ||
|
|
2bb74e7467 | ||
|
|
a684044bb3 | ||
|
|
36a3465a64 | ||
|
|
223aee70d5 | ||
|
|
c02a7d6abe | ||
|
|
22a3efe4ed | ||
|
|
dd47df9b9c | ||
|
|
0b0e8940e0 | ||
|
|
fa8339c8c2 | ||
|
|
f0ee812b29 | ||
|
|
f093cb6db2 | ||
|
|
68d4a5a650 | ||
|
|
6576fa6a73 | ||
|
|
28535bf384 | ||
|
|
43e3fe375d | ||
|
|
d8a9a3db8d | ||
|
|
777d5dca0e | ||
|
|
6d71cd678e | ||
|
|
30714d98f9 | ||
|
|
8353bd48de | ||
|
|
0762c761ac | ||
|
|
529197f403 | ||
|
|
d20cbf14e7 | ||
|
|
517f63835d | ||
|
|
4fee062b73 | ||
|
|
26769b2357 | ||
|
|
42bf7b9ca0 | ||
|
|
d8755c903d | ||
|
|
a391fcb6c4 | ||
|
|
c99ca863ce | ||
|
|
e0283543f3 | ||
|
|
a72e053520 | ||
|
|
de654712d5 | ||
|
|
9c1d5484a2 | ||
|
|
1fd8aa885b | ||
|
|
08882c6a8e | ||
|
|
fd199ec156 | ||
|
|
e3515fd63f | ||
|
|
be0a485b14 | ||
|
|
94c04712d6 | ||
|
|
caea0b7f68 | ||
|
|
134301b3ff | ||
|
|
d14f3dd2d8 | ||
|
|
67c313c86d | ||
|
|
5eaa73583a | ||
|
|
68b6af6fce | ||
|
|
e65fdba5d1 | ||
|
|
8f336cd0b3 | ||
|
|
5f3bfe8451 | ||
|
|
1a3d58e74e | ||
|
|
af9a851c5e | ||
|
|
3a40a855ea |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -4,3 +4,6 @@
|
||||
[submodule "JsShrink"]
|
||||
path = externals/JsShrink
|
||||
url = https://github.com/vrana/JsShrink
|
||||
[submodule "PhpShrink"]
|
||||
path = externals/PhpShrink
|
||||
url = https://github.com/vrana/PhpShrink
|
||||
|
||||
@@ -30,7 +30,7 @@ if ($row["auto_increment_col"]) {
|
||||
}
|
||||
|
||||
if ($_POST) {
|
||||
set_adminer_settings(array("comments" => $_POST["comments"], "defaults" => $_POST["defaults"]));
|
||||
save_settings(array("comments" => $_POST["comments"], "defaults" => $_POST["defaults"]));
|
||||
}
|
||||
|
||||
if ($_POST && !process_fields($row["fields"]) && !$error) {
|
||||
@@ -180,32 +180,27 @@ foreach ($engines as $engine) {
|
||||
|
||||
<form action="" method="post" id="form">
|
||||
<p>
|
||||
<?php if (support("columns") || $TABLE == "") { ?>
|
||||
<?php echo lang('Table name'); ?>: <input name="name"<?php echo ($TABLE == "" && !$_POST ? " autofocus" : ""); ?> data-maxlength="64" value="<?php echo h($row["name"]); ?>" autocapitalize="off">
|
||||
<?php echo ($engines ? html_select("Engine", array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . on_help("getTarget(event).value", 1) . script("qsl('select').onchange = helpClose;") : ""); ?>
|
||||
<?php
|
||||
<?php
|
||||
if (support("columns") || $TABLE == "") {
|
||||
echo lang('Table name') . "<input name='name'" . ($TABLE == "" && !$_POST ? " autofocus" : "") . " data-maxlength='64' value='" . h($row["name"]) . "' autocapitalize='off'>\n";
|
||||
echo ($engines ? html_select("Engine", array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . on_help("getTarget(event).value", 1) . script("qsl('select').onchange = helpClose;") . "\n" : "");
|
||||
if ($collations) {
|
||||
echo "<datalist id='collations'>" . optionlist($collations) . "</datalist>";
|
||||
echo (preg_match("~sqlite|mssql~", JUSH) ? "" : "<input list='collations' name='Collation' value='" . h($row["Collation"]) . "' placeholder='(" . lang('collation') . ")'>");
|
||||
}
|
||||
?>
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
<?php } ?>
|
||||
echo "<input type='submit' value='" . lang('Save') . "'>\n";
|
||||
}
|
||||
|
||||
<?php if (support("columns")) { ?>
|
||||
<div class="scrollable">
|
||||
<table id="edit-fields" class="nowrap">
|
||||
<?php
|
||||
if (support("columns")) {
|
||||
echo "<div class='scrollable'>\n";
|
||||
echo "<table id='edit-fields' class='nowrap'>\n";
|
||||
edit_fields($row["fields"], $collations, "TABLE", $foreign_keys);
|
||||
?>
|
||||
</table>
|
||||
<?php echo script("editFields();"); ?>
|
||||
</div>
|
||||
<p>
|
||||
<?php echo lang('Auto Increment'); ?>: <input type="number" name="Auto_increment" class="size" value="<?php echo h($row["Auto_increment"]); ?>">
|
||||
<?php echo checkbox("defaults", 1, ($_POST ? $_POST["defaults"] : adminer_setting("defaults")), lang('Default values'), "columnShow(this.checked, 5)", "jsonly"); ?>
|
||||
<?php
|
||||
$comments = ($_POST ? $_POST["comments"] : adminer_setting("comments"));
|
||||
echo "</table>\n";
|
||||
echo script("editFields();");
|
||||
echo "</div>\n<p>\n";
|
||||
echo lang('Auto Increment') . ": <input type='number' name='Auto_increment' class='size' value='" . h($row["Auto_increment"]) . "'>\n";
|
||||
echo checkbox("defaults", 1, ($_POST ? $_POST["defaults"] : get_setting("defaults")), lang('Default values'), "columnShow(this.checked, 5)", "jsonly");
|
||||
$comments = ($_POST ? $_POST["comments"] : get_setting("comments"));
|
||||
echo (support("comment")
|
||||
? checkbox("comments", 1, $comments, lang('Comment'), "editingCommentsClick(this, true);", "jsonly")
|
||||
. ' ' . (preg_match('~\n~', $row["Comment"])
|
||||
@@ -226,24 +221,18 @@ foreach ($engines as $engine) {
|
||||
if (support("partitioning")) {
|
||||
$partition_table = preg_match('~RANGE|LIST~', $row["partition_by"]);
|
||||
print_fieldset("partition", lang('Partition by'), $row["partition_by"]);
|
||||
?>
|
||||
<p>
|
||||
<?php echo html_select("partition_by", array("" => "") + $partition_by, $row["partition_by"]) . on_help("getTarget(event).value.replace(/./, 'PARTITION BY \$&')", 1) . script("qsl('select').onchange = partitionByChange;"); ?>
|
||||
(<input name="partition" value="<?php echo h($row["partition"]); ?>">)
|
||||
<?php echo lang('Partitions'); ?>: <input type="number" name="partitions" class="size<?php echo ($partition_table || !$row["partition_by"] ? " hidden" : ""); ?>" value="<?php echo h($row["partitions"]); ?>">
|
||||
<table id="partition-table"<?php echo ($partition_table ? "" : " class='hidden'"); ?>>
|
||||
<thead><tr><th><?php echo lang('Partition name'); ?><th><?php echo lang('Values'); ?></thead>
|
||||
<?php
|
||||
echo "<p>" . html_select("partition_by", array("" => "") + $partition_by, $row["partition_by"]) . on_help("getTarget(event).value.replace(/./, 'PARTITION BY \$&')", 1) . script("qsl('select').onchange = partitionByChange;");
|
||||
echo "(<input name='partition' value='" . h($row["partition"]) . "'>)\n";
|
||||
echo lang('Partitions') . ": <input type='number' name='partitions' class='size" . ($partition_table || !$row["partition_by"] ? " hidden" : "") . "' value='" . h($row["partitions"]) . "'>\n";
|
||||
echo "<table id='partition-table'" . ($partition_table ? "" : " class='hidden'") . ">\n";
|
||||
echo "<thead><tr><th>" . lang('Partition name') . "<th>" . lang('Values') . "</thead>\n";
|
||||
foreach ($row["partition_names"] as $key => $val) {
|
||||
echo '<tr>';
|
||||
echo '<td><input name="partition_names[]" value="' . h($val) . '" autocapitalize="off">';
|
||||
echo ($key == count($row["partition_names"]) - 1 ? script("qsl('input').oninput = partitionNameChange;") : '');
|
||||
echo '<td><input name="partition_values[]" value="' . h($row["partition_values"][$key]) . '">';
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
</div></fieldset>
|
||||
<?php
|
||||
echo "</table>\n</div></fieldset>\n";
|
||||
}
|
||||
?>
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
|
||||
@@ -3,8 +3,13 @@ function adminer_object() {
|
||||
include_once "../plugins/plugin.php";
|
||||
include_once "../plugins/designs.php";
|
||||
$designs = array();
|
||||
foreach (glob("../designs/*", GLOB_ONLYDIR) as $filename) {
|
||||
$designs["$filename/adminer.css"] = basename($filename);
|
||||
foreach (glob("../designs/*", GLOB_ONLYDIR) as $dirname) {
|
||||
foreach (array("", "-dark") as $mode) {
|
||||
$filename = "$dirname/adminer$mode.css";
|
||||
if (file_exists($filename)) {
|
||||
$designs[$filename] = basename($dirname);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new AdminerPlugin(array(
|
||||
new AdminerDesigns($designs),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
$drivers = array("server" => "MySQL") + $drivers;
|
||||
$drivers = array("server" => "MySQL / MariaDB") + $drivers;
|
||||
|
||||
if (!defined('Adminer\DRIVER')) {
|
||||
define('Adminer\DRIVER', "server"); // server - backwards compatibility
|
||||
@@ -435,11 +435,13 @@ if (!defined('Adminer\DRIVER')) {
|
||||
* @return mixed Db or string for error
|
||||
*/
|
||||
function connect($credentials) {
|
||||
global $drivers;
|
||||
$connection = new Db;
|
||||
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
|
||||
$connection->set_charset(charset($connection)); // available in MySQLi since PHP 5.0.5
|
||||
$connection->set_charset(charset($connection));
|
||||
$connection->query("SET sql_quote_show_create = 1, autocommit = 1");
|
||||
$connection->maria = preg_match('~MariaDB~', $connection->server_info);
|
||||
$drivers[DRIVER] = ($connection->maria ? "MariaDB" : "MySQL");
|
||||
return $connection;
|
||||
}
|
||||
$return = $connection->error;
|
||||
|
||||
@@ -321,6 +321,7 @@ if (isset($_GET["pgsql"])) {
|
||||
}
|
||||
|
||||
function connect($credentials) {
|
||||
global $drivers;
|
||||
$connection = new Db;
|
||||
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
|
||||
if (min_version(9, 0, $connection)) {
|
||||
@@ -328,6 +329,10 @@ if (isset($_GET["pgsql"])) {
|
||||
}
|
||||
$crdb_version = $connection->result("SHOW crdb_version");
|
||||
$connection->server_info .= ($crdb_version ? "-" . preg_replace('~ \(.*~', '', $crdb_version) : "");
|
||||
$connection->cockroach = preg_match('~CockroachDB~', $connection->server_info);
|
||||
if ($connection->cockroach) { // we don't use "PostgreSQL / CockroachDB" by default because it's too long
|
||||
$drivers[DRIVER] = "CockroachDB";
|
||||
}
|
||||
return $connection;
|
||||
}
|
||||
return $connection->error;
|
||||
@@ -954,10 +959,10 @@ AND typelem = 0"
|
||||
|
||||
function support($feature) {
|
||||
global $connection;
|
||||
return ($feature == "processlist"
|
||||
? !preg_match('~CockroachDB~', $connection->server_info) // https://github.com/cockroachdb/cockroach/issues/24745
|
||||
: preg_match('~^(check|database|table|columns|sql|indexes|descidx|comment|view|' . (min_version(9.3) ? 'materializedview|' : '') . 'scheme|routine|sequence|trigger|type|variables|drop_col|kill|dump)$~', $feature)
|
||||
);
|
||||
return preg_match('~^(check|database|table|columns|sql|indexes|descidx|comment|view|' . (min_version(9.3) ? 'materializedview|' : '') . 'scheme|routine|sequence|trigger|type|variables|drop_col'
|
||||
. ($connection->cockroach ? '' : '|processlist') // https://github.com/cockroachdb/cockroach/issues/24745
|
||||
. '|kill|dump)$~', $feature)
|
||||
;
|
||||
}
|
||||
|
||||
function kill_process($val) {
|
||||
|
||||
@@ -4,11 +4,10 @@ namespace Adminer;
|
||||
$TABLE = $_GET["dump"];
|
||||
|
||||
if ($_POST && !$error) {
|
||||
$cookie = "";
|
||||
foreach (array("output", "format", "db_style", "types", "routines", "events", "table_style", "auto_increment", "triggers", "data_style") as $key) {
|
||||
$cookie .= "&$key=" . urlencode($_POST[$key]);
|
||||
}
|
||||
cookie("adminer_export", substr($cookie, 1));
|
||||
save_settings(
|
||||
array_intersect_key($_POST, array_flip(array("output", "format", "db_style", "types", "routines", "events", "table_style", "auto_increment", "triggers", "data_style"))),
|
||||
"adminer_export"
|
||||
);
|
||||
$tables = array_flip((array) $_POST["tables"]) + array_flip((array) $_POST["data"]);
|
||||
$ext = dump_headers(
|
||||
(count($tables) == 1 ? key($tables) : DB),
|
||||
@@ -156,7 +155,7 @@ $data_style = array('', 'TRUNCATE+INSERT', 'INSERT');
|
||||
if (JUSH == "sql") { //! use insertUpdate() in all drivers
|
||||
$data_style[] = 'INSERT+UPDATE';
|
||||
}
|
||||
parse_str($_COOKIE["adminer_export"], $row);
|
||||
$row = get_settings("adminer_export");
|
||||
if (!$row) {
|
||||
$row = array("output" => "text", "format" => "sql", "db_style" => (DB != "" ? "" : "CREATE"), "table_style" => "DROP+CREATE", "data_style" => "INSERT");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
// caching headers added in compile.php
|
||||
if (substr($VERSION, -4) != '-dev') {
|
||||
if ($_SERVER["HTTP_IF_MODIFIED_SINCE"]) {
|
||||
header("HTTP/1.1 304 Not Modified");
|
||||
exit;
|
||||
}
|
||||
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 365*24*60*60) . " GMT");
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
||||
header("Cache-Control: immutable");
|
||||
}
|
||||
|
||||
if ($_GET["file"] == "favicon.ico") {
|
||||
header("Content-Type: image/x-icon");
|
||||
@@ -11,7 +19,7 @@ if ($_GET["file"] == "favicon.ico") {
|
||||
echo lzw_decompress(compile_file('../adminer/static/default.css;../externals/jush/jush.css', 'minify_css'));
|
||||
} elseif ($_GET["file"] == "dark.css") {
|
||||
header("Content-Type: text/css; charset=utf-8");
|
||||
echo lzw_decompress(compile_file('../adminer/static/dark.css', 'minify_css'));
|
||||
echo lzw_decompress(compile_file('../adminer/static/dark.css;../externals/jush/jush-dark.css', 'minify_css'));
|
||||
} elseif ($_GET["file"] == "functions.js") {
|
||||
header("Content-Type: text/javascript; charset=utf-8");
|
||||
echo lzw_decompress(compile_file('../adminer/static/functions.js;static/editing.js', 'minify_js'));
|
||||
|
||||
@@ -94,12 +94,13 @@ class Adminer {
|
||||
}
|
||||
|
||||
/** Print HTML code inside <head>
|
||||
* @return bool true to link favicon.ico and adminer.css if exists
|
||||
* @param bool dark CSS: false to disable, true to force, null to base on user preferences
|
||||
* @return bool true to link favicon.ico
|
||||
*/
|
||||
function head() {
|
||||
?>
|
||||
<link rel="stylesheet" href="../externals/jush/jush.css">
|
||||
<?php
|
||||
function head($dark = null) {
|
||||
// this is matched by compile.php
|
||||
echo "<link rel='stylesheet' href='../externals/jush/jush.css'>\n";
|
||||
echo ($dark !== false ? "<link rel='stylesheet'" . ($dark ? "" : " media='(prefers-color-scheme: dark)'") . " href='../externals/jush/jush-dark.css'>\n" : "");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -108,9 +109,11 @@ class Adminer {
|
||||
*/
|
||||
function css() {
|
||||
$return = array();
|
||||
$filename = "adminer.css";
|
||||
if (file_exists($filename)) {
|
||||
$return[] = "$filename?v=" . crc32(file_get_contents($filename));
|
||||
foreach (array("", "-dark") as $mode) {
|
||||
$filename = "adminer$mode.css";
|
||||
if (file_exists($filename)) {
|
||||
$return[] = "$filename?v=" . crc32(file_get_contents($filename));
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
@@ -121,8 +124,10 @@ class Adminer {
|
||||
function loginForm() {
|
||||
global $drivers;
|
||||
echo "<table class='layout'>\n";
|
||||
// this is matched by compile.php
|
||||
echo $this->loginFormField('driver', '<tr><th>' . lang('System') . '<td>', html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);"));
|
||||
echo $this->loginFormField('server', '<tr><th>' . lang('Server') . '<td>', '<input name="auth[server]" value="' . h(SERVER) . '" title="hostname[:port]" placeholder="localhost" autocapitalize="off">');
|
||||
// this is matched by compile.php
|
||||
echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input name="auth[username]" id="username" autofocus value="' . h($_GET["username"]) . '" autocomplete="username" autocapitalize="off">' . script("qs('#username').form['auth[driver]'].onchange();"));
|
||||
echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td>', '<input type="password" name="auth[password]" autocomplete="current-password">');
|
||||
echo $this->loginFormField('db', '<tr><th>' . lang('Database') . '<td>', '<input name="auth[db]" value="' . h($_GET["db"]) . '" autocapitalize="off">');
|
||||
@@ -167,7 +172,7 @@ class Adminer {
|
||||
* @return string HTML code, "" to ignore field
|
||||
*/
|
||||
function fieldName($field, $order = 0) {
|
||||
return '<span title="' . h($field["full_type"]) . '">' . h($field["field"]) . '</span>';
|
||||
return '<span title="' . h($field["full_type"] . ($field["comment"] != "" ? " : $field[comment]" : '')) . '">' . h($field["field"]) . '</span>';
|
||||
}
|
||||
|
||||
/** Print links after select heading
|
||||
@@ -988,16 +993,18 @@ class Adminer {
|
||||
</span>
|
||||
</h1>
|
||||
<?php
|
||||
// this is matched by compile.php
|
||||
switch_lang();
|
||||
if ($missing == "auth") {
|
||||
$output = "";
|
||||
foreach ((array) $_SESSION["pwds"] as $vendor => $servers) {
|
||||
foreach ($servers as $server => $usernames) {
|
||||
$name = h(get_setting("vendor-$server") ?: $drivers[$vendor]);
|
||||
foreach ($usernames as $username => $password) {
|
||||
if ($password !== null) {
|
||||
$dbs = $_SESSION["db"][$vendor][$server][$username];
|
||||
foreach (($dbs ? array_keys($dbs) : array("")) as $db) {
|
||||
$output .= "<li><a href='" . h(auth_url($vendor, $server, $username, $db)) . "'>($drivers[$vendor]) " . h($username . ($server != "" ? "@" . $this->serverName($server) : "") . ($db != "" ? " - $db" : "")) . "</a>\n";
|
||||
$output .= "<li><a href='" . h(auth_url($vendor, $server, $username, $db)) . "'>($name) " . h($username . ($server != "" ? "@" . $this->serverName($server) : "") . ($db != "" ? " - $db" : "")) . "</a>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1012,30 +1019,7 @@ class Adminer {
|
||||
$connection->select_db(DB);
|
||||
$tables = table_status('', true);
|
||||
}
|
||||
echo script_src("../externals/jush/modules/jush.js");
|
||||
echo script_src("../externals/jush/modules/jush-textarea.js");
|
||||
echo script_src("../externals/jush/modules/jush-txt.js");
|
||||
echo script_src("../externals/jush/modules/jush-js.js");
|
||||
if (support("sql")) {
|
||||
echo script_src("../externals/jush/modules/jush-" . JUSH . ".js");
|
||||
?>
|
||||
<script<?php echo nonce(); ?>>
|
||||
<?php
|
||||
if ($tables) {
|
||||
$links = array();
|
||||
foreach ($tables as $table => $type) {
|
||||
$links[] = preg_quote($table, '/');
|
||||
}
|
||||
echo "var jushLinks = { " . JUSH . ": [ '" . js_escape(ME) . (support("table") ? "table=" : "select=") . "\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n";
|
||||
foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) {
|
||||
echo "jushLinks.$val = jushLinks." . JUSH . ";\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '\1', $connection->server_info) : ""); ?>'<?php echo ($connection->maria ? ", true" : ""); ?>);
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
$this->syntaxHighlighting($tables);
|
||||
$this->databasesPrint($missing);
|
||||
$actions = array();
|
||||
if (DB == "" || !$missing) {
|
||||
@@ -1060,6 +1044,34 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
|
||||
}
|
||||
}
|
||||
|
||||
/** Set up syntax highlight for code and <textarea>
|
||||
* @param array result of table_status()
|
||||
*/
|
||||
function syntaxHighlighting($tables) {
|
||||
global $connection;
|
||||
// this is matched by compile.php
|
||||
echo script_src("../externals/jush/modules/jush.js");
|
||||
echo script_src("../externals/jush/modules/jush-textarea.js");
|
||||
echo script_src("../externals/jush/modules/jush-txt.js");
|
||||
echo script_src("../externals/jush/modules/jush-js.js");
|
||||
if (support("sql")) {
|
||||
echo script_src("../externals/jush/modules/jush-" . JUSH . ".js");
|
||||
echo "<script" . nonce() . ">\n";
|
||||
if ($tables) {
|
||||
$links = array();
|
||||
foreach ($tables as $table => $type) {
|
||||
$links[] = preg_quote($table, '/');
|
||||
}
|
||||
echo "var jushLinks = { " . JUSH . ": [ '" . js_escape(ME) . (support("table") ? "table=" : "select=") . "\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n";
|
||||
foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) {
|
||||
echo "jushLinks.$val = jushLinks." . JUSH . ";\n";
|
||||
}
|
||||
}
|
||||
echo "</script>\n";
|
||||
}
|
||||
echo script("bodyLoad('" . (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '\1', $connection->server_info) : "") . "'" . ($connection->maria ? ", true" : "") . ");");
|
||||
}
|
||||
|
||||
/** Prints databases list in menu
|
||||
* @param string
|
||||
* @return null
|
||||
|
||||
@@ -19,7 +19,17 @@ if ($_COOKIE["adminer_permanent"]) {
|
||||
|
||||
function add_invalid_login() {
|
||||
global $adminer;
|
||||
$fp = file_open_lock(get_temp_dir() . "/adminer.invalid");
|
||||
$base = get_temp_dir() . "/adminer.invalid";
|
||||
// adminer.invalid may not be writable by us, try the files with random suffixes
|
||||
foreach (glob("$base*") ?: array($base) as $filename) {
|
||||
$fp = file_open_lock($filename);
|
||||
if ($fp) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$fp) {
|
||||
$fp = file_open_lock("$base-" . rand_string());
|
||||
}
|
||||
if (!$fp) {
|
||||
return;
|
||||
}
|
||||
@@ -42,7 +52,15 @@ function add_invalid_login() {
|
||||
|
||||
function check_invalid_login() {
|
||||
global $adminer;
|
||||
$invalids = unserialize(@file_get_contents(get_temp_dir() . "/adminer.invalid")); // @ - may not exist
|
||||
$invalids = array();
|
||||
foreach (glob(get_temp_dir() . "/adminer.invalid*") as $filename) {
|
||||
$fp = file_open_lock($filename);
|
||||
if ($fp) {
|
||||
$invalids = unserialize(stream_get_contents($fp));
|
||||
file_unlock($fp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$invalid = ($invalids ? $invalids[$adminer->bruteForceKey()] : array());
|
||||
$next_attempt = ($invalid[1] > 29 ? $invalid[0] - time() : 0); // allow 30 invalid attempts
|
||||
if ($next_attempt > 0) { //! do the same with permanent login
|
||||
@@ -61,7 +79,7 @@ if ($auth) {
|
||||
set_password($vendor, $server, $username, $password);
|
||||
$_SESSION["db"][$vendor][$server][$username][$db] = true;
|
||||
if ($auth["permanent"]) {
|
||||
$key = base64_encode($vendor) . "-" . base64_encode($server) . "-" . base64_encode($username) . "-" . base64_encode($db);
|
||||
$key = implode("-", array_map('base64_encode', array($vendor, $server, $username, $db)));
|
||||
$private = $adminer->permanentLogin(true);
|
||||
$permanent[$key] = "$key:" . base64_encode($private ? encrypt_string($password, $private) : "");
|
||||
cookie("adminer_permanent", implode(" ", $permanent));
|
||||
@@ -169,6 +187,9 @@ if (isset($_GET["username"]) && is_string(get_password())) {
|
||||
if ($adminer->operators === null) {
|
||||
$adminer->operators = $driver->operators;
|
||||
}
|
||||
if (isset($connection->maria) || $connection->cockroach) {
|
||||
save_settings(array("vendor-" . SERVER => $drivers[DRIVER]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace Adminer;
|
||||
|
||||
include "../adminer/include/version.inc.php";
|
||||
include "../adminer/include/errors.inc.php";
|
||||
// this is matched by compile.php
|
||||
include "../adminer/include/coverage.inc.php";
|
||||
|
||||
// disable filter.default
|
||||
@@ -21,6 +22,7 @@ if (function_exists("mb_internal_encoding")) {
|
||||
}
|
||||
|
||||
include "../adminer/include/functions.inc.php";
|
||||
include "../adminer/include/html.inc.php";
|
||||
|
||||
// used only in compiled file
|
||||
if (isset($_GET["file"])) {
|
||||
@@ -28,7 +30,9 @@ if (isset($_GET["file"])) {
|
||||
}
|
||||
|
||||
if ($_GET["script"] == "version") {
|
||||
$fp = file_open_lock(get_temp_dir() . "/adminer.version");
|
||||
$filename = get_temp_dir() . "/adminer.version";
|
||||
unlink($filename); // it may not be writable by us
|
||||
$fp = file_open_lock($filename);
|
||||
if ($fp) {
|
||||
file_write_unlock($fp, serialize(array("signature" => $_POST["signature"], "version" => $_POST["version"])));
|
||||
}
|
||||
@@ -74,6 +78,7 @@ include "../adminer/drivers/oracle.inc.php";
|
||||
include "../adminer/drivers/mssql.inc.php";
|
||||
include "./include/adminer.inc.php";
|
||||
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
|
||||
// this is matched by compile.php
|
||||
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver
|
||||
|
||||
define('Adminer\JUSH', Driver::$jush);
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
namespace Adminer;
|
||||
|
||||
// coverage is used in tests and removed in compilation
|
||||
if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer_coverage.ser")) {
|
||||
if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer.coverage")) {
|
||||
function save_coverage() {
|
||||
$coverage_filename = sys_get_temp_dir() . "/adminer_coverage.ser";
|
||||
$coverage_filename = sys_get_temp_dir() . "/adminer.coverage";
|
||||
$coverage = unserialize(file_get_contents($coverage_filename));
|
||||
foreach (xdebug_get_code_coverage() as $filename => $lines) {
|
||||
foreach ($lines as $l => $val) {
|
||||
|
||||
@@ -31,23 +31,22 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
|
||||
<link rel="stylesheet" href="../adminer/static/default.css">
|
||||
<?php
|
||||
$css = $adminer->css();
|
||||
if ($css) {
|
||||
foreach ($css as $val) {
|
||||
echo "<link rel='stylesheet' href='" . h($val) . "'>\n";
|
||||
}
|
||||
} else {
|
||||
echo "<link rel='stylesheet' media='(prefers-color-scheme: dark)' href='../adminer/static/dark.css'>\n";
|
||||
$dark = (count($css) == 1 ? !!preg_match('~-dark~', $css[0]) : null);
|
||||
if ($dark !== false) {
|
||||
echo "<link rel='stylesheet'" . ($dark ? "" : " media='(prefers-color-scheme: dark)'") . " href='../adminer/static/dark.css'>\n";
|
||||
}
|
||||
echo "<meta name='color-scheme' content='" . ($dark === null ? "light dark" : ($dark ? "dark" : "light")) . "'>\n";
|
||||
// this is matched by compile.php
|
||||
echo script_src("../adminer/static/functions.js");
|
||||
echo script_src("static/editing.js");
|
||||
?>
|
||||
<?php if ($adminer->head()) { ?>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="../adminer/static/favicon.ico">
|
||||
<link rel="apple-touch-icon" href="../adminer/static/favicon.ico">
|
||||
<?php } ?>
|
||||
|
||||
<body class="<?php echo lang('ltr'); ?> nojs">
|
||||
<?php
|
||||
if ($adminer->head($dark)) {
|
||||
echo "<link rel='shortcut icon' type='image/x-icon' href='../adminer/static/favicon.ico'>\n";
|
||||
echo "<link rel='apple-touch-icon' href='../adminer/static/favicon.ico'>\n";
|
||||
}
|
||||
foreach ($css as $val) {
|
||||
echo "<link rel='stylesheet'" . (preg_match('~-dark~', $val) && !$dark ? " media='(prefers-color-scheme: dark)'" : "") . " href='" . h($val) . "'>\n";
|
||||
}
|
||||
echo "\n<body class='" . lang('ltr') . " nojs'>\n";
|
||||
$filename = get_temp_dir() . "/adminer.version";
|
||||
if (!$_COOKIE["adminer_version"] && function_exists('openssl_verify') && file_exists($filename) && filemtime($filename) + 86400 > time()) { // 86400 - 1 day in seconds
|
||||
$version = unserialize(file_get_contents($filename));
|
||||
@@ -65,21 +64,16 @@ fQIDAQAB
|
||||
$_COOKIE["adminer_version"] = $version["version"]; // doesn't need to send to the browser
|
||||
}
|
||||
}
|
||||
?>
|
||||
<script<?php echo nonce(); ?>>
|
||||
mixin(document.body, {onkeydown: bodyKeydown, onclick: bodyClick<?php
|
||||
echo (isset($_COOKIE["adminer_version"]) ? "" : ", onload: partial(verifyVersion, '$VERSION', '" . js_escape(ME) . "', '" . get_token() . "')"); // $token may be empty in auth.inc.php
|
||||
?>});
|
||||
echo script("mixin(document.body, {onkeydown: bodyKeydown, onclick: bodyClick"
|
||||
. (isset($_COOKIE["adminer_version"]) ? "" : ", onload: partial(verifyVersion, '$VERSION', '" . js_escape(ME) . "', '" . get_token() . "')") // $token may be empty in auth.inc.php
|
||||
. "});
|
||||
document.body.className = document.body.className.replace(/ nojs/, ' js');
|
||||
var offlineMessage = '<?php echo js_escape(lang('You are offline.')); ?>';
|
||||
var thousandsSeparator = '<?php echo js_escape(lang(',')); ?>';
|
||||
</script>
|
||||
|
||||
<div id="help" class="jush-<?php echo JUSH; ?> jsonly hidden"></div>
|
||||
<?php echo script("mixin(qs('#help'), {onmouseover: function () { helpOpen = 1; }, onmouseout: helpMouseout});"); ?>
|
||||
|
||||
<div id="content">
|
||||
<?php
|
||||
var offlineMessage = '" . js_escape(lang('You are offline.')) . "';
|
||||
var thousandsSeparator = '" . js_escape(lang(',')) . "';")
|
||||
;
|
||||
echo "<div id='help' class='jush-" . JUSH . " jsonly hidden'></div>\n";
|
||||
echo script("mixin(qs('#help'), {onmouseover: function () { helpOpen = 1; }, onmouseout: helpMouseout});");
|
||||
echo "<div id='content'>\n";
|
||||
if ($breadcrumb !== null) {
|
||||
$link = substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1);
|
||||
echo '<p id="breadcrumb"><a href="' . h($link ?: ".") . '">' . $drivers[DRIVER] . '</a> » ';
|
||||
|
||||
@@ -13,12 +13,13 @@ function add_driver($id, $name) {
|
||||
$drivers[$id] = $name;
|
||||
}
|
||||
|
||||
/** Get driver
|
||||
* @return Driver
|
||||
/** Get driver name
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function get_driver() {
|
||||
global $driver;
|
||||
return $driver;
|
||||
function get_driver($id) {
|
||||
global $drivers;
|
||||
return $drivers[$id];
|
||||
}
|
||||
|
||||
abstract class SqlDriver {
|
||||
|
||||
@@ -90,7 +90,8 @@ function select($result, $connection2 = null, $orgtables = array(), $limit = 0)
|
||||
if ($link) {
|
||||
$val = "<a href='" . h($link) . "'" . (is_url($link) ? target_blank() : '') . ">$val</a>";
|
||||
}
|
||||
echo "<td>$val";
|
||||
// https://dev.mysql.com/doc/dev/mysql-server/latest/field__types_8h.html
|
||||
echo "<td" . ($types[$key] <= 9 || $types[$key] == 246 ? " class='number'" : "") . ">$val";
|
||||
}
|
||||
}
|
||||
echo ($i ? "</table>\n</div>" : "<p class='message'>" . lang('No rows.')) . "\n";
|
||||
@@ -119,31 +120,6 @@ function referencable_primary($self) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Get settings stored in a cookie
|
||||
* @return array
|
||||
*/
|
||||
function adminer_settings() {
|
||||
parse_str($_COOKIE["adminer_settings"], $settings);
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/** Get setting stored in a cookie
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
function adminer_setting($key) {
|
||||
$settings = adminer_settings();
|
||||
return $settings[$key];
|
||||
}
|
||||
|
||||
/** Store settings to a cookie
|
||||
* @param array
|
||||
* @return bool
|
||||
*/
|
||||
function set_adminer_settings($settings) {
|
||||
return cookie("adminer_settings", http_build_query($settings + adminer_settings()));
|
||||
}
|
||||
|
||||
/** Print SQL <textarea> tag
|
||||
* @param string
|
||||
* @param string or array in which case [0] of every element is used
|
||||
@@ -209,7 +185,7 @@ function json_row($key, $val = null) {
|
||||
function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_types = array()) {
|
||||
global $driver;
|
||||
$type = $field["type"];
|
||||
?><td><select name="<?php echo h($key); ?>[type]" class="type" aria-labelledby="label-type"><?php
|
||||
echo "<td><select name='" . h($key) . "[type]' class='type' aria-labelledby='label-type'>";
|
||||
if ($type && !array_key_exists($type, $driver->types()) && !isset($foreign_keys[$type]) && !in_array($type, $extra_types)) {
|
||||
$extra_types[] = $type;
|
||||
}
|
||||
@@ -218,12 +194,11 @@ function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_ty
|
||||
$structured_types[lang('Foreign keys')] = $foreign_keys;
|
||||
}
|
||||
echo optionlist(array_merge($extra_types, $structured_types), $type);
|
||||
?></select><td><input
|
||||
name="<?php echo h($key); ?>[length]"
|
||||
value="<?php echo h($field["length"]); ?>"
|
||||
size="3"
|
||||
<?php echo (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : ""); //! type="number" with enabled JavaScript ?>
|
||||
aria-labelledby="label-length"><td class="options"><?php
|
||||
echo "</select><td>";
|
||||
echo "<input name='" . h($key) . "[length]' value='" . h($field["length"]) . "' size='3'"
|
||||
. (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : "") //! type="number" with enabled JavaScript
|
||||
. " aria-labelledby='label-length'>";
|
||||
echo "<td class='options'>";
|
||||
echo ($collations
|
||||
? "<input list='collations' name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . " value='" . h($field["collation"]) . "' placeholder='(" . lang('collation') . ")'>"
|
||||
: ''
|
||||
@@ -349,54 +324,51 @@ function type_class($type) {
|
||||
function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = array()) {
|
||||
global $driver;
|
||||
$fields = array_values($fields);
|
||||
$default_class = (($_POST ? $_POST["defaults"] : adminer_setting("defaults")) ? "" : " class='hidden'");
|
||||
$comment_class = (($_POST ? $_POST["comments"] : adminer_setting("comments")) ? "" : " class='hidden'");
|
||||
$default_class = (($_POST ? $_POST["defaults"] : get_setting("defaults")) ? "" : " class='hidden'");
|
||||
$comment_class = (($_POST ? $_POST["comments"] : get_setting("comments")) ? "" : " class='hidden'");
|
||||
?>
|
||||
<thead><tr>
|
||||
<?php echo ($type == "PROCEDURE" ? "<td>" : ""); ?>
|
||||
<th id="label-name"><?php echo ($type == "TABLE" ? lang('Column name') : lang('Parameter name')); ?>
|
||||
<td id="label-type"><?php echo lang('Type'); ?><textarea id="enum-edit" rows="4" cols="12" wrap="off" style="display: none;"></textarea><?php echo script("qs('#enum-edit').onblur = editingLengthBlur;"); ?>
|
||||
<td id="label-length"><?php echo lang('Length'); ?>
|
||||
<td><?php echo lang('Options'); /* no label required, options have their own label */ ?>
|
||||
<?php if ($type == "TABLE") { ?>
|
||||
<td id="label-null">NULL
|
||||
<td><input type="radio" name="auto_increment_col" value=""><abbr id="label-ai" title="<?php echo lang('Auto Increment'); ?>">AI</abbr><?php echo doc_link(array(
|
||||
'sql' => "example-auto-increment.html",
|
||||
'mariadb' => "auto_increment/",
|
||||
'sqlite' => "autoinc.html",
|
||||
'pgsql' => "datatype-numeric.html#DATATYPE-SERIAL",
|
||||
'mssql' => "t-sql/statements/create-table-transact-sql-identity-property",
|
||||
)); ?>
|
||||
<td id="label-default"<?php echo $default_class; ?>><?php echo lang('Default value'); ?>
|
||||
<?php echo (support("comment") ? "<td id='label-comment'$comment_class>" . lang('Comment') : ""); ?>
|
||||
<?php } ?>
|
||||
<td><?php echo "<input type='image' class='icon' name='add[" . (support("move_col") ? 0 : count($fields)) . "]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>" . script("row_count = " . count($fields) . ";"); ?>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
<td><?php
|
||||
echo lang('Options'); // no label required, options have their own label
|
||||
if ($type == "TABLE") {
|
||||
echo "<td id='label-null'>NULL\n";
|
||||
echo "<td><input type='radio' name='auto_increment_col' value=''><abbr id='label-ai' title='" . lang('Auto Increment') . "'>AI</abbr>";
|
||||
echo doc_link(array(
|
||||
'sql' => "example-auto-increment.html",
|
||||
'mariadb' => "auto_increment/",
|
||||
'sqlite' => "autoinc.html",
|
||||
'pgsql' => "datatype-numeric.html#DATATYPE-SERIAL",
|
||||
'mssql' => "t-sql/statements/create-table-transact-sql-identity-property",
|
||||
));
|
||||
echo "<td id='label-default'$default_class>" . lang('Default value');
|
||||
echo (support("comment") ? "<td id='label-comment'$comment_class>" . lang('Comment') : "");
|
||||
}
|
||||
echo "<td><input type='image' class='icon' name='add[" . (support("move_col") ? 0 : count($fields)) . "]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>" . script("row_count = " . count($fields) . ";");
|
||||
echo "</thead>\n<tbody>\n";
|
||||
echo script("mixin(qsl('tbody'), {onclick: editingClick, onkeydown: editingKeydown, oninput: editingInput});");
|
||||
foreach ($fields as $i => $field) {
|
||||
$i++;
|
||||
$orig = $field[($_POST ? "orig" : "field")];
|
||||
$display = (isset($_POST["add"][$i-1]) || (isset($field["field"]) && !$_POST["drop_col"][$i])) && (support("drop_col") || $orig == "");
|
||||
?>
|
||||
<tr<?php echo ($display ? "" : " style='display: none;'"); ?>>
|
||||
<?php echo ($type == "PROCEDURE" ? "<td>" . html_select("fields[$i][inout]", explode("|", $driver->inout), $field["inout"]) : "") . "<th>"; ?>
|
||||
<?php if ($display) { ?>
|
||||
<input name="fields[<?php echo $i; ?>][field]" value="<?php echo h($field["field"]); ?>" data-maxlength="64" autocapitalize="off" aria-labelledby="label-name">
|
||||
<?php } ?>
|
||||
<input type="hidden" name="fields[<?php echo $i; ?>][orig]" value="<?php echo h($orig); ?>"><?php edit_type("fields[$i]", $field, $collations, $foreign_keys); ?>
|
||||
<?php
|
||||
echo "<tr" . ($display ? "" : " style='display: none;'") . ">\n";
|
||||
echo ($type == "PROCEDURE" ? "<td>" . html_select("fields[$i][inout]", explode("|", $driver->inout), $field["inout"]) : "") . "<th>";
|
||||
if ($display) {
|
||||
echo "<input name='fields[$i][field]' value='" . h($field["field"]) . "' data-maxlength='64' autocapitalize='off' aria-labelledby='label-name'>\n";
|
||||
}
|
||||
echo "<input type='hidden' name='fields[$i][orig]' value='" . h($orig) . "'>";
|
||||
edit_type("fields[$i]", $field, $collations, $foreign_keys);
|
||||
if ($type == "TABLE") {
|
||||
?>
|
||||
<td><?php echo checkbox("fields[$i][null]", 1, $field["null"], "", "", "block", "label-null"); ?>
|
||||
<td><label class="block"><input type="radio" name="auto_increment_col" value="<?php echo $i; ?>"<?php echo ($field["auto_increment"] ? " checked" : ""); ?> aria-labelledby="label-ai"></label><td<?php echo $default_class; ?>><?php
|
||||
echo ($driver->generated
|
||||
echo "<td>" . checkbox("fields[$i][null]", 1, $field["null"], "", "", "block", "label-null");
|
||||
echo "<td><label class='block'><input type='radio' name='auto_increment_col' value='$i'" . ($field["auto_increment"] ? " checked" : "") . " aria-labelledby='label-ai'></label>";
|
||||
echo "<td$default_class>" . ($driver->generated
|
||||
? html_select("fields[$i][generated]", array_merge(array("", "DEFAULT"), $driver->generated), $field["generated"]) . " "
|
||||
: checkbox("fields[$i][generated]", 1, $field["generated"], "", "", "", "label-default")
|
||||
);
|
||||
?>
|
||||
<input name="fields[<?php echo $i; ?>][default]" value="<?php echo h($field["default"]); ?>" aria-labelledby="label-default"><?php
|
||||
echo "<input name='fields[$i][default]' value='" . h($field["default"]) . "' aria-labelledby='label-default'>";
|
||||
echo (support("comment") ? "<td$comment_class><input name='fields[$i][comment]' value='" . h($field["comment"]) . "' data-maxlength='" . (min_version(5.5) ? 1024 : 255) . "' aria-labelledby='label-comment'>" : "");
|
||||
}
|
||||
echo "<td>";
|
||||
|
||||
@@ -20,6 +20,14 @@ function adminer() {
|
||||
return $adminer;
|
||||
}
|
||||
|
||||
/** Get Driver object
|
||||
* @return Driver
|
||||
*/
|
||||
function driver() {
|
||||
global $driver;
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/** Get Adminer version
|
||||
* @return string
|
||||
*/
|
||||
@@ -40,6 +48,15 @@ function idf_unescape($idf) {
|
||||
return str_replace($last . $last, $last, substr($idf, 1, -1));
|
||||
}
|
||||
|
||||
/** Shortcut for $connection->quote($string)
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function q($string) {
|
||||
global $connection;
|
||||
return $connection->quote($string);
|
||||
}
|
||||
|
||||
/** Escape string to use inside ''
|
||||
* @param string
|
||||
* @return string
|
||||
@@ -122,171 +139,6 @@ function charset($connection) {
|
||||
return (min_version("5.5.3", 0, $connection) ? "utf8mb4" : "utf8"); // SHOW CHARSET would require an extra query
|
||||
}
|
||||
|
||||
/** Return <script> element
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function script($source, $trailing = "\n") {
|
||||
return "<script" . nonce() . ">$source</script>$trailing";
|
||||
}
|
||||
|
||||
/** Return <script src> element
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function script_src($url) {
|
||||
return "<script src='" . h($url) . "'" . nonce() . "></script>\n";
|
||||
}
|
||||
|
||||
/** Get a nonce="" attribute with CSP nonce
|
||||
* @return string
|
||||
*/
|
||||
function nonce() {
|
||||
return ' nonce="' . get_nonce() . '"';
|
||||
}
|
||||
|
||||
/** Get a target="_blank" attribute
|
||||
* @return string
|
||||
*/
|
||||
function target_blank() {
|
||||
return ' target="_blank" rel="noreferrer noopener"';
|
||||
}
|
||||
|
||||
/** Escape for HTML
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function h($string) {
|
||||
return str_replace("\0", "�", htmlspecialchars($string, ENT_QUOTES, 'utf-8'));
|
||||
}
|
||||
|
||||
/** Convert \n to <br>
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function nl_br($string) {
|
||||
return str_replace("\n", "<br>", $string); // nl2br() uses XHTML before PHP 5.3
|
||||
}
|
||||
|
||||
/** Generate HTML checkbox
|
||||
* @param string
|
||||
* @param string
|
||||
* @param bool
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function checkbox($name, $value, $checked, $label = "", $onclick = "", $class = "", $labelled_by = "") {
|
||||
$return = "<input type='checkbox' name='$name' value='" . h($value) . "'"
|
||||
. ($checked ? " checked" : "")
|
||||
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
|
||||
. ">"
|
||||
. ($onclick ? script("qsl('input').onclick = function () { $onclick };", "") : "")
|
||||
;
|
||||
return ($label != "" || $class ? "<label" . ($class ? " class='$class'" : "") . ">$return" . h($label) . "</label>" : $return);
|
||||
}
|
||||
|
||||
/** Generate list of HTML options
|
||||
* @param array array of strings or arrays (creates optgroup)
|
||||
* @param mixed
|
||||
* @param bool always use array keys for value="", otherwise only string keys are used
|
||||
* @return string
|
||||
*/
|
||||
function optionlist($options, $selected = null, $use_keys = false) {
|
||||
$return = "";
|
||||
foreach ($options as $k => $v) {
|
||||
$opts = array($k => $v);
|
||||
if (is_array($v)) {
|
||||
$return .= '<optgroup label="' . h($k) . '">';
|
||||
$opts = $v;
|
||||
}
|
||||
foreach ($opts as $key => $val) {
|
||||
$return .= '<option'
|
||||
. ($use_keys || is_string($key) ? ' value="' . h($key) . '"' : '')
|
||||
. ($selected !== null && ($use_keys || is_string($key) ? (string) $key : $val) === $selected ? ' selected' : '')
|
||||
. '>' . h($val)
|
||||
;
|
||||
}
|
||||
if (is_array($v)) {
|
||||
$return .= '</optgroup>';
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Generate HTML <select>
|
||||
* @param string
|
||||
* @param array
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function html_select($name, $options, $value = "", $onchange = "", $labelled_by = "") {
|
||||
return "<select name='" . h($name) . "'"
|
||||
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
|
||||
. ">" . optionlist($options, $value) . "</select>"
|
||||
. ($onchange ? script("qsl('select').onchange = function () { $onchange };", "") : "")
|
||||
;
|
||||
}
|
||||
|
||||
/** Generate HTML radio list
|
||||
* @param string
|
||||
* @param array
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function html_radios($name, $options, $value = "") {
|
||||
$return = "";
|
||||
foreach ($options as $key => $val) {
|
||||
$return .= "<label><input type='radio' name='" . h($name) . "' value='" . h($key) . "'" . ($key == $value ? " checked" : "") . ">" . h($val) . "</label>";
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Get onclick confirmation
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function confirm($message = "", $selector = "qsl('input')") {
|
||||
return script("$selector.onclick = function () { return confirm('" . ($message ? js_escape($message) : lang('Are you sure?')) . "'); };", "");
|
||||
}
|
||||
|
||||
/** Print header for hidden fieldset (close by </div></fieldset>)
|
||||
* @param string
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return null
|
||||
*/
|
||||
function print_fieldset($id, $legend, $visible = false) {
|
||||
echo "<fieldset><legend>";
|
||||
echo "<a href='#fieldset-$id'>$legend</a>";
|
||||
echo script("qsl('a').onclick = partial(toggle, 'fieldset-$id');", "");
|
||||
echo "</legend>";
|
||||
echo "<div id='fieldset-$id'" . ($visible ? "" : " class='hidden'") . ">\n";
|
||||
}
|
||||
|
||||
/** Return class='active' if $bold is true
|
||||
* @param bool
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function bold($bold, $class = "") {
|
||||
return ($bold ? " class='active $class'" : ($class ? " class='$class'" : ""));
|
||||
}
|
||||
|
||||
/** Escape string for JavaScript apostrophes
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function js_escape($string) {
|
||||
return addcslashes($string, "\r\n'\\/"); // slash for <script>
|
||||
}
|
||||
|
||||
/** Get INI boolean value
|
||||
* @param string
|
||||
* @return bool
|
||||
@@ -335,15 +187,6 @@ function get_password() {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Shortcut for $connection->quote($string)
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function q($string) {
|
||||
global $connection;
|
||||
return $connection->quote($string);
|
||||
}
|
||||
|
||||
/** Get single value from database
|
||||
* @param string
|
||||
* @param int
|
||||
@@ -464,8 +307,7 @@ function where($where, $fields = array()) {
|
||||
. (JUSH == "sql" && $field_type == "json" ? " = CAST(" . q($val) . " AS JSON)"
|
||||
: (JUSH == "sql" && is_numeric($val) && preg_match('~\.~', $val) ? " LIKE " . q($val) // LIKE because of floats but slow with ints
|
||||
: (JUSH == "mssql" && strpos($field_type, "datetime") === false ? " LIKE " . q(preg_replace('~[_%[]~', '[\0]', $val)) // LIKE because of text but it does not work with datetime
|
||||
: " = " . unconvert_field($fields[$key], q($val))
|
||||
)))
|
||||
: " = " . unconvert_field($fields[$key], q($val)))))
|
||||
; //! enum and set
|
||||
if (JUSH == "sql" && preg_match('~char|text~', $field_type) && preg_match("~[^ -@]~", $val)) { // not just [a-z] to catch non-ASCII characters
|
||||
$return[] = "$column = " . q($val) . " COLLATE " . charset($connection) . "_bin";
|
||||
@@ -537,6 +379,34 @@ function cookie($name, $value, $lifetime = 2592000) {
|
||||
);
|
||||
}
|
||||
|
||||
/** Get settings stored in a cookie
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
function get_settings($cookie) {
|
||||
parse_str($_COOKIE[$cookie], $settings);
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/** Get setting stored in a cookie
|
||||
* @param string
|
||||
* @param string
|
||||
* @return mixed
|
||||
*/
|
||||
function get_setting($key, $cookie = "adminer_settings") {
|
||||
$settings = get_settings($cookie);
|
||||
return $settings[$key];
|
||||
}
|
||||
|
||||
/** Store settings to a cookie
|
||||
* @param array
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
function save_settings($settings, $cookie = "adminer_settings") {
|
||||
return cookie($cookie, http_build_query($settings + get_settings($cookie)));
|
||||
}
|
||||
|
||||
/** Restart stopped session
|
||||
* @return null
|
||||
*/
|
||||
@@ -721,18 +591,6 @@ function remove_from_uri($param = "") {
|
||||
return substr(preg_replace("~(?<=[?&])($param" . (SID ? "" : "|" . session_name()) . ")=[^&]*&~", '', relative_uri() . "&"), 0, -1);
|
||||
}
|
||||
|
||||
/** Generate page number for pagination
|
||||
* @param int
|
||||
* @param int
|
||||
* @return string
|
||||
*/
|
||||
function pagination($page, $current) {
|
||||
return " " . ($page == $current
|
||||
? $page + 1
|
||||
: '<a href="' . h(remove_from_uri("page") . ($page ? "&page=$page" . ($_GET["next"] ? "&next=" . urlencode($_GET["next"]) : "") : "")) . '">' . ($page + 1) . "</a>"
|
||||
);
|
||||
}
|
||||
|
||||
/** Get file contents from $_FILES
|
||||
* @param string
|
||||
* @param bool
|
||||
@@ -833,36 +691,6 @@ function friendly_url($val) {
|
||||
return preg_replace('~\W~i', '-', $val);
|
||||
}
|
||||
|
||||
/** Print hidden fields
|
||||
* @param array
|
||||
* @param array
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
function hidden_fields($process, $ignore = array(), $prefix = '') {
|
||||
$return = false;
|
||||
foreach ($process as $key => $val) {
|
||||
if (!in_array($key, $ignore)) {
|
||||
if (is_array($val)) {
|
||||
hidden_fields($val, array(), $key);
|
||||
} else {
|
||||
$return = true;
|
||||
echo '<input type="hidden" name="' . h($prefix ? $prefix . "[$key]" : $key) . '" value="' . h($val) . '">';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Print hidden fields for GET forms
|
||||
* @return null
|
||||
*/
|
||||
function hidden_fields_get() {
|
||||
echo (sid() ? '<input type="hidden" name="' . session_name() . '" value="' . h(session_id()) . '">' : '');
|
||||
echo (SERVER !== null ? '<input type="hidden" name="' . DRIVER . '" value="' . h(SERVER) . '">' : "");
|
||||
echo '<input type="hidden" name="username" value="' . h($_GET["username"]) . '">';
|
||||
}
|
||||
|
||||
/** Get status of a single table and fall back to name on error
|
||||
* @param string
|
||||
* @param bool
|
||||
@@ -888,173 +716,6 @@ function column_foreign_keys($table) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Print enum input field
|
||||
* @param string "radio"|"checkbox"
|
||||
* @param string
|
||||
* @param array
|
||||
* @param mixed string|array
|
||||
* @param string
|
||||
* @return null
|
||||
*/
|
||||
function enum_input($type, $attrs, $field, $value, $empty = null) {
|
||||
global $adminer;
|
||||
preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
|
||||
$return = ($empty !== null ? "<label><input type='$type'$attrs value='$empty'" . ((is_array($value) ? in_array($empty, $value) : $value === $empty) ? " checked" : "") . "><i>" . lang('empty') . "</i></label>" : "");
|
||||
foreach ($matches[1] as $i => $val) {
|
||||
$val = stripcslashes(str_replace("''", "'", $val));
|
||||
$checked = (is_array($value) ? in_array($val, $value) : $value === $val);
|
||||
$return .= " <label><input type='$type'$attrs value='" . h($val) . "'" . ($checked ? ' checked' : '') . '>' . h($adminer->editVal($val, $field)) . '</label>';
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Print edit input field
|
||||
* @param array one field from fields()
|
||||
* @param mixed
|
||||
* @param string
|
||||
* @return null
|
||||
*/
|
||||
function input($field, $value, $function) {
|
||||
global $driver, $adminer;
|
||||
$name = h(bracket_escape($field["field"]));
|
||||
echo "<td class='function'>";
|
||||
if (is_array($value) && !$function) {
|
||||
$value = json_encode($value, 128); // 128 - JSON_PRETTY_PRINT available since PHP 5.4
|
||||
$function = "json";
|
||||
}
|
||||
$reset = (JUSH == "mssql" && $field["auto_increment"]);
|
||||
if ($reset && !$_POST["save"]) {
|
||||
$function = null;
|
||||
}
|
||||
$functions = (isset($_GET["select"]) || $reset ? array("orig" => lang('original')) : array()) + $adminer->editFunctions($field);
|
||||
$disabled = stripos($field["default"], "GENERATED ALWAYS AS ") === 0 ? " disabled=''" : "";
|
||||
$attrs = " name='fields[$name]'$disabled";
|
||||
$enums = $driver->enumLength($field);
|
||||
if ($enums) {
|
||||
$field["type"] = "enum";
|
||||
$field["length"] = $enums;
|
||||
}
|
||||
echo $driver->unconvertFunction($field) . " ";
|
||||
if ($field["type"] == "enum") {
|
||||
echo h($functions[""]) . "<td>" . $adminer->editInput($_GET["edit"], $field, $attrs, $value);
|
||||
} else {
|
||||
$has_function = (in_array($function, $functions) || isset($functions[$function]));
|
||||
echo (count($functions) > 1
|
||||
? "<select name='function[$name]'$disabled>" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>"
|
||||
. on_help("getTarget(event).value.replace(/^SQL\$/, '')", 1)
|
||||
. script("qsl('select').onchange = functionChange;", "")
|
||||
: h(reset($functions))
|
||||
) . '<td>';
|
||||
$input = $adminer->editInput($_GET["edit"], $field, $attrs, $value); // usage in call is without a table
|
||||
if ($input != "") {
|
||||
echo $input;
|
||||
} elseif (preg_match('~bool~', $field["type"])) {
|
||||
echo "<input type='hidden'$attrs value='0'>"
|
||||
. "<input type='checkbox'" . (preg_match('~^(1|t|true|y|yes|on)$~i', $value) ? " checked='checked'" : "") . "$attrs value='1'>";
|
||||
} elseif ($field["type"] == "set") {
|
||||
preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
|
||||
foreach ($matches[1] as $i => $val) {
|
||||
$val = stripcslashes(str_replace("''", "'", $val));
|
||||
$checked = in_array($val, explode(",", $value), true);
|
||||
echo " <label><input type='checkbox' name='fields[$name][$i]' value='" . h($val) . "'" . ($checked ? ' checked' : '') . ">" . h($adminer->editVal($val, $field)) . '</label>';
|
||||
}
|
||||
} elseif (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
|
||||
echo "<input type='file' name='fields-$name'>";
|
||||
} elseif (($text = preg_match('~text|lob|memo~i', $field["type"])) || preg_match("~\n~", $value)) {
|
||||
if ($text && JUSH != "sqlite") {
|
||||
$attrs .= " cols='50' rows='12'";
|
||||
} else {
|
||||
$rows = min(12, substr_count($value, "\n") + 1);
|
||||
$attrs .= " cols='30' rows='$rows'" . ($rows == 1 ? " style='height: 1.2em;'" : ""); // 1.2em - line-height
|
||||
}
|
||||
echo "<textarea$attrs>" . h($value) . '</textarea>';
|
||||
} elseif ($function == "json" || preg_match('~^jsonb?$~', $field["type"])) {
|
||||
echo "<textarea$attrs cols='50' rows='12' class='jush-js'>" . h($value) . '</textarea>';
|
||||
} else {
|
||||
// int(3) is only a display hint
|
||||
$types = $driver->types();
|
||||
$maxlength = (!preg_match('~int~', $field["type"]) && preg_match('~^(\d+)(,(\d+))?$~', $field["length"], $match)
|
||||
? ((preg_match("~binary~", $field["type"]) ? 2 : 1) * $match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0))
|
||||
: ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0)
|
||||
);
|
||||
if (JUSH == 'sql' && min_version(5.6) && preg_match('~time~', $field["type"])) {
|
||||
$maxlength += 7; // microtime
|
||||
}
|
||||
// type='date' and type='time' display localized value which may be confusing, type='datetime' uses 'T' as date and time separator
|
||||
echo "<input"
|
||||
. ((!$has_function || $function === "") && preg_match('~(?<!o)int(?!er)~', $field["type"]) && !preg_match('~\[\]~', $field["full_type"]) ? " type='number'" : "")
|
||||
. " value='" . h($value) . "'" . ($maxlength ? " data-maxlength='$maxlength'" : "")
|
||||
. (preg_match('~char|binary~', $field["type"]) && $maxlength > 20 ? " size='40'" : "")
|
||||
. "$attrs>"
|
||||
;
|
||||
}
|
||||
echo $adminer->editHint($_GET["edit"], $field, $value);
|
||||
// skip 'original'
|
||||
$first = 0;
|
||||
foreach ($functions as $key => $val) {
|
||||
if ($key === "" || !$val) {
|
||||
break;
|
||||
}
|
||||
$first++;
|
||||
}
|
||||
if ($first) {
|
||||
echo script("mixin(qsl('td'), {onchange: partial(skipOriginal, $first), oninput: function () { this.onchange(); }});");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Process edit input field
|
||||
* @param one field from fields()
|
||||
* @return string or false to leave the original value
|
||||
*/
|
||||
function process_input($field) {
|
||||
global $adminer, $driver;
|
||||
|
||||
if (stripos($field["default"], "GENERATED ALWAYS AS ") === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$idf = bracket_escape($field["field"]);
|
||||
$function = $_POST["function"][$idf];
|
||||
$value = $_POST["fields"][$idf];
|
||||
if ($field["type"] == "enum" || $driver->enumLength($field)) {
|
||||
if ($value == -1) {
|
||||
return false;
|
||||
}
|
||||
if ($value == "") {
|
||||
return "NULL";
|
||||
}
|
||||
}
|
||||
if ($field["auto_increment"] && $value == "") {
|
||||
return null;
|
||||
}
|
||||
if ($function == "orig") {
|
||||
return (preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"]) ? idf_escape($field["field"]) : false);
|
||||
}
|
||||
if ($function == "NULL") {
|
||||
return "NULL";
|
||||
}
|
||||
if ($field["type"] == "set") {
|
||||
$value = implode(",", (array) $value);
|
||||
}
|
||||
if ($function == "json") {
|
||||
$function = "";
|
||||
$value = json_decode($value, true);
|
||||
if (!is_array($value)) {
|
||||
return false; //! report errors
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
if (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
|
||||
$file = get_file("fields-$idf");
|
||||
if (!is_string($file)) {
|
||||
return false; //! report errors
|
||||
}
|
||||
return $driver->quoteBinary($file);
|
||||
}
|
||||
return $adminer->processInput($field, $value, $function);
|
||||
}
|
||||
|
||||
/** Compute fields() from $_POST edit data
|
||||
* @return array
|
||||
*/
|
||||
@@ -1080,29 +741,6 @@ function fields_from_edit() {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Print results of search in all tables
|
||||
* @uses $_GET["where"][0]
|
||||
* @uses $_POST["tables"]
|
||||
* @return null
|
||||
*/
|
||||
function search_tables() {
|
||||
global $adminer, $connection;
|
||||
$_GET["where"][0]["val"] = $_POST["query"];
|
||||
$sep = "<ul>\n";
|
||||
foreach (table_status('', true) as $table => $table_status) {
|
||||
$name = $adminer->tableName($table_status);
|
||||
if (isset($table_status["Engine"]) && $name != "" && (!$_POST["tables"] || in_array($table, $_POST["tables"]))) {
|
||||
$result = $connection->query("SELECT" . limit("1 FROM " . table($table), " WHERE " . implode(" AND ", $adminer->selectSearchProcess(fields($table), array())), 1));
|
||||
if (!$result || $result->fetch_row()) {
|
||||
$print = "<a href='" . h(ME . "select=" . urlencode($table) . "&where[0][op]=" . urlencode($_GET["where"][0]["op"]) . "&where[0][val]=" . urlencode($_GET["where"][0]["val"])) . "'>$name</a>";
|
||||
echo "$sep<li>" . ($result ? $print : "<p class='error'>$print: " . error()) . "\n";
|
||||
$sep = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
echo ($sep ? "<p class='message'>" . lang('No tables.') : "</ul>") . "\n";
|
||||
}
|
||||
|
||||
/** Send headers for export
|
||||
* @param string
|
||||
* @param bool
|
||||
@@ -1168,15 +806,18 @@ function get_temp_dir() {
|
||||
* @return resource or null for error
|
||||
*/
|
||||
function file_open_lock($filename) {
|
||||
$fp = @fopen($filename, "r+"); // @ - may not exist
|
||||
if (!$fp) { // c+ is available since PHP 5.2.6
|
||||
$fp = @fopen($filename, "w"); // @ - may not be writable
|
||||
if (!$fp) {
|
||||
return;
|
||||
}
|
||||
chmod($filename, 0660);
|
||||
if (is_link($filename)) {
|
||||
return; // https://cwe.mitre.org/data/definitions/61.html
|
||||
}
|
||||
$fp = @fopen($filename, "c+"); // @ - may not be writable
|
||||
if (!$fp) {
|
||||
return;
|
||||
}
|
||||
chmod($filename, 0660);
|
||||
if (!flock($fp, LOCK_EX)) {
|
||||
fclose($fp);
|
||||
return;
|
||||
}
|
||||
flock($fp, LOCK_EX);
|
||||
return $fp;
|
||||
}
|
||||
|
||||
@@ -1188,6 +829,13 @@ function file_write_unlock($fp, $data) {
|
||||
rewind($fp);
|
||||
fwrite($fp, $data);
|
||||
ftruncate($fp, strlen($data));
|
||||
file_unlock($fp);
|
||||
}
|
||||
|
||||
/** Unlock and close a file
|
||||
* @param resource
|
||||
*/
|
||||
function file_unlock($fp) {
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
}
|
||||
@@ -1198,16 +846,19 @@ function file_write_unlock($fp, $data) {
|
||||
*/
|
||||
function password_file($create) {
|
||||
$filename = get_temp_dir() . "/adminer.key";
|
||||
$return = @file_get_contents($filename); // @ - may not exist
|
||||
if ($return || !$create) {
|
||||
return $return;
|
||||
if (!$create && !file_exists($filename)) {
|
||||
return false;
|
||||
}
|
||||
$fp = @fopen($filename, "w"); // @ - can have insufficient rights //! is not atomic
|
||||
if ($fp) {
|
||||
chmod($filename, 0660);
|
||||
$fp = file_open_lock($filename);
|
||||
if (!$fp) {
|
||||
return false;
|
||||
}
|
||||
$return = stream_get_contents($fp);
|
||||
if (!$return) {
|
||||
$return = rand_string();
|
||||
fwrite($fp, $return);
|
||||
fclose($fp);
|
||||
file_write_unlock($fp, $return);
|
||||
} else {
|
||||
file_unlock($fp);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
@@ -1317,14 +968,7 @@ function slow_query($query) {
|
||||
$connection2 = null;
|
||||
if (!$slow_query && support("kill") && is_object($connection2 = connect($adminer->credentials())) && ($db == "" || $connection2->select_db($db))) {
|
||||
$kill = $connection2->result(connection_id()); // MySQL and MySQLi can use thread_id but it's not in PDO_MySQL
|
||||
?>
|
||||
<script<?php echo nonce(); ?>>
|
||||
var timeout = setTimeout(function () {
|
||||
ajax('<?php echo js_escape(ME); ?>script=kill', function () {
|
||||
}, 'kill=<?php echo $kill; ?>&token=<?php echo $token; ?>');
|
||||
}, <?php echo 1000 * $timeout; ?>);
|
||||
</script>
|
||||
<?php
|
||||
echo script("var timeout = setTimeout(function () { ajax('" . js_escape(ME) . "script=kill', function () {}, 'kill=$kill&token=$token'); }, 1000 * $timeout);");
|
||||
}
|
||||
ob_flush();
|
||||
flush();
|
||||
@@ -1390,129 +1034,3 @@ function lzw_decompress($binary) {
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Return events to display help on mouse over
|
||||
* @param string JS expression
|
||||
* @param bool JS expression
|
||||
* @return string
|
||||
*/
|
||||
function on_help($command, $side = 0) {
|
||||
return script("mixin(qsl('select, input'), {onmouseover: function (event) { helpMouseover.call(this, event, $command, $side) }, onmouseout: helpMouseout});", "");
|
||||
}
|
||||
|
||||
/** Print edit data form
|
||||
* @param string
|
||||
* @param array
|
||||
* @param mixed
|
||||
* @param bool
|
||||
* @return null
|
||||
*/
|
||||
function edit_form($table, $fields, $row, $update) {
|
||||
global $adminer, $token, $error;
|
||||
$table_name = $adminer->tableName(table_status1($table, true));
|
||||
page_header(
|
||||
($update ? lang('Edit') : lang('Insert')),
|
||||
$error,
|
||||
array("select" => array($table, $table_name)),
|
||||
$table_name
|
||||
);
|
||||
$adminer->editRowPrint($table, $fields, $row, $update);
|
||||
if ($row === false) {
|
||||
echo "<p class='error'>" . lang('No rows.') . "\n";
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<form action="" method="post" enctype="multipart/form-data" id="form">
|
||||
<?php
|
||||
$first = 0;
|
||||
$is_first = true;
|
||||
if (!$fields) {
|
||||
echo "<p class='error'>" . lang('You have no privileges to update this table.') . "\n";
|
||||
} else {
|
||||
echo "<table class='layout'>" . script("qsl('table').onkeydown = editingKeydown;");
|
||||
foreach ($fields as $name => $field) {
|
||||
echo "<tr><th>" . $adminer->fieldName($field);
|
||||
$default = $_GET["set"][bracket_escape($name)];
|
||||
if ($default === null) {
|
||||
$default = $field["default"];
|
||||
if ($field["type"] == "bit" && preg_match("~^b'([01]*)'\$~", $default, $regs)) {
|
||||
$default = $regs[1];
|
||||
}
|
||||
if (JUSH == "sql" && preg_match('~binary~', $field["type"])) {
|
||||
$default = bin2hex($default); // same as UNHEX
|
||||
}
|
||||
}
|
||||
$value = ($row !== null
|
||||
? ($row[$name] != "" && JUSH == "sql" && preg_match("~enum|set~", $field["type"]) && is_array($row[$name])
|
||||
? implode(",", $row[$name])
|
||||
: (is_bool($row[$name]) ? +$row[$name] : $row[$name])
|
||||
)
|
||||
: (!$update && $field["auto_increment"]
|
||||
? ""
|
||||
: (isset($_GET["select"]) ? false : $default)
|
||||
)
|
||||
);
|
||||
if (!$_POST["save"] && is_string($value)) {
|
||||
$value = $adminer->editVal($value, $field);
|
||||
}
|
||||
$function = ($_POST["save"]
|
||||
? (string) $_POST["function"][$name]
|
||||
: ($update && preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"])
|
||||
? "now"
|
||||
: ($value === false ? null : ($value !== null ? '' : 'NULL'))
|
||||
)
|
||||
);
|
||||
if (!$_POST && !$update && $value == $field["default"] && preg_match('~^[\w.]+\(~', $value)) {
|
||||
$function = "SQL";
|
||||
}
|
||||
if (preg_match("~time~", $field["type"]) && preg_match('~^CURRENT_TIMESTAMP~i', $value)) {
|
||||
$value = "";
|
||||
$function = "now";
|
||||
}
|
||||
if ($field["type"] == "uuid" && $value == "uuid()") {
|
||||
$value = "";
|
||||
$function = "uuid";
|
||||
}
|
||||
if ($is_first && ($field["auto_increment"] || $function == "now" || $function == "uuid")) {
|
||||
$first++;
|
||||
} else {
|
||||
$is_first = false;
|
||||
}
|
||||
input($field, $value, $function);
|
||||
echo "\n";
|
||||
}
|
||||
if (!support("table")) {
|
||||
echo "<tr>"
|
||||
. "<th><input name='field_keys[]'>"
|
||||
. script("qsl('input').oninput = fieldChange;")
|
||||
. "<td class='function'>" . html_select("field_funs[]", $adminer->editFunctions(array("null" => isset($_GET["select"]))))
|
||||
. "<td><input name='field_vals[]'>"
|
||||
. "\n"
|
||||
;
|
||||
}
|
||||
echo "</table>\n";
|
||||
}
|
||||
echo "<p>\n";
|
||||
if ($fields) {
|
||||
echo "<input type='submit' value='" . lang('Save') . "'>\n";
|
||||
if (!isset($_GET["select"])) {
|
||||
echo "<input type='submit' name='insert' value='" . ($update
|
||||
? lang('Save and continue edit')
|
||||
: lang('Save and insert next')
|
||||
) . "' title='Ctrl+Shift+Enter'>\n";
|
||||
echo ($update ? script("qsl('input').onclick = function () { return !ajaxForm(this.form, '" . lang('Saving') . "…', this); };") : "");
|
||||
}
|
||||
}
|
||||
echo ($update ? "<input type='submit' name='delete' value='" . lang('Delete') . "'>" . confirm() . "\n"
|
||||
: ($_POST || !$fields ? "" : script("focus(qsa('td', qs('#form'))[2*$first+1].firstChild);"))
|
||||
);
|
||||
if (isset($_GET["select"])) {
|
||||
hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"]));
|
||||
}
|
||||
?>
|
||||
<input type="hidden" name="referer" value="<?php echo h(isset($_POST["referer"]) ? $_POST["referer"] : $_SERVER["HTTP_REFERER"]); ?>">
|
||||
<input type="hidden" name="save" value="1">
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
520
adminer/include/html.inc.php
Normal file
520
adminer/include/html.inc.php
Normal file
@@ -0,0 +1,520 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
/** Return <script> element
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function script($source, $trailing = "\n") {
|
||||
return "<script" . nonce() . ">$source</script>$trailing";
|
||||
}
|
||||
|
||||
/** Return <script src> element
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function script_src($url) {
|
||||
return "<script src='" . h($url) . "'" . nonce() . "></script>\n";
|
||||
}
|
||||
|
||||
/** Get a nonce="" attribute with CSP nonce
|
||||
* @return string
|
||||
*/
|
||||
function nonce() {
|
||||
return ' nonce="' . get_nonce() . '"';
|
||||
}
|
||||
|
||||
/** Get a target="_blank" attribute
|
||||
* @return string
|
||||
*/
|
||||
function target_blank() {
|
||||
return ' target="_blank" rel="noreferrer noopener"';
|
||||
}
|
||||
|
||||
/** Escape for HTML
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function h($string) {
|
||||
return str_replace("\0", "�", htmlspecialchars($string, ENT_QUOTES, 'utf-8'));
|
||||
}
|
||||
|
||||
/** Convert \n to <br>
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function nl_br($string) {
|
||||
return str_replace("\n", "<br>", $string); // nl2br() uses XHTML before PHP 5.3
|
||||
}
|
||||
|
||||
/** Generate HTML checkbox
|
||||
* @param string
|
||||
* @param string
|
||||
* @param bool
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function checkbox($name, $value, $checked, $label = "", $onclick = "", $class = "", $labelled_by = "") {
|
||||
$return = "<input type='checkbox' name='$name' value='" . h($value) . "'"
|
||||
. ($checked ? " checked" : "")
|
||||
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
|
||||
. ">"
|
||||
. ($onclick ? script("qsl('input').onclick = function () { $onclick };", "") : "")
|
||||
;
|
||||
return ($label != "" || $class ? "<label" . ($class ? " class='$class'" : "") . ">$return" . h($label) . "</label>" : $return);
|
||||
}
|
||||
|
||||
/** Generate list of HTML options
|
||||
* @param array array of strings or arrays (creates optgroup)
|
||||
* @param mixed
|
||||
* @param bool always use array keys for value="", otherwise only string keys are used
|
||||
* @return string
|
||||
*/
|
||||
function optionlist($options, $selected = null, $use_keys = false) {
|
||||
$return = "";
|
||||
foreach ($options as $k => $v) {
|
||||
$opts = array($k => $v);
|
||||
if (is_array($v)) {
|
||||
$return .= '<optgroup label="' . h($k) . '">';
|
||||
$opts = $v;
|
||||
}
|
||||
foreach ($opts as $key => $val) {
|
||||
$return .= '<option'
|
||||
. ($use_keys || is_string($key) ? ' value="' . h($key) . '"' : '')
|
||||
. ($selected !== null && ($use_keys || is_string($key) ? (string) $key : $val) === $selected ? ' selected' : '')
|
||||
. '>' . h($val)
|
||||
;
|
||||
}
|
||||
if (is_array($v)) {
|
||||
$return .= '</optgroup>';
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Generate HTML <select>
|
||||
* @param string
|
||||
* @param array
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function html_select($name, $options, $value = "", $onchange = "", $labelled_by = "") {
|
||||
return "<select name='" . h($name) . "'"
|
||||
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
|
||||
. ">" . optionlist($options, $value) . "</select>"
|
||||
. ($onchange ? script("qsl('select').onchange = function () { $onchange };", "") : "")
|
||||
;
|
||||
}
|
||||
|
||||
/** Generate HTML radio list
|
||||
* @param string
|
||||
* @param array
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function html_radios($name, $options, $value = "") {
|
||||
$return = "";
|
||||
foreach ($options as $key => $val) {
|
||||
$return .= "<label><input type='radio' name='" . h($name) . "' value='" . h($key) . "'" . ($key == $value ? " checked" : "") . ">" . h($val) . "</label>";
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Get onclick confirmation
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function confirm($message = "", $selector = "qsl('input')") {
|
||||
return script("$selector.onclick = function () { return confirm('" . ($message ? js_escape($message) : lang('Are you sure?')) . "'); };", "");
|
||||
}
|
||||
|
||||
/** Print header for hidden fieldset (close by </div></fieldset>)
|
||||
* @param string
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return null
|
||||
*/
|
||||
function print_fieldset($id, $legend, $visible = false) {
|
||||
echo "<fieldset><legend>";
|
||||
echo "<a href='#fieldset-$id'>$legend</a>";
|
||||
echo script("qsl('a').onclick = partial(toggle, 'fieldset-$id');", "");
|
||||
echo "</legend>";
|
||||
echo "<div id='fieldset-$id'" . ($visible ? "" : " class='hidden'") . ">\n";
|
||||
}
|
||||
|
||||
/** Return class='active' if $bold is true
|
||||
* @param bool
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function bold($bold, $class = "") {
|
||||
return ($bold ? " class='active $class'" : ($class ? " class='$class'" : ""));
|
||||
}
|
||||
|
||||
/** Escape string for JavaScript apostrophes
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function js_escape($string) {
|
||||
return addcslashes($string, "\r\n'\\/"); // slash for <script>
|
||||
}
|
||||
|
||||
/** Generate page number for pagination
|
||||
* @param int
|
||||
* @param int
|
||||
* @return string
|
||||
*/
|
||||
function pagination($page, $current) {
|
||||
return " " . ($page == $current
|
||||
? $page + 1
|
||||
: '<a href="' . h(remove_from_uri("page") . ($page ? "&page=$page" . ($_GET["next"] ? "&next=" . urlencode($_GET["next"]) : "") : "")) . '">' . ($page + 1) . "</a>"
|
||||
);
|
||||
}
|
||||
|
||||
/** Print hidden fields
|
||||
* @param array
|
||||
* @param array
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
function hidden_fields($process, $ignore = array(), $prefix = '') {
|
||||
$return = false;
|
||||
foreach ($process as $key => $val) {
|
||||
if (!in_array($key, $ignore)) {
|
||||
if (is_array($val)) {
|
||||
hidden_fields($val, array(), $key);
|
||||
} else {
|
||||
$return = true;
|
||||
echo '<input type="hidden" name="' . h($prefix ? $prefix . "[$key]" : $key) . '" value="' . h($val) . '">';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Print hidden fields for GET forms
|
||||
* @return null
|
||||
*/
|
||||
function hidden_fields_get() {
|
||||
echo (sid() ? '<input type="hidden" name="' . session_name() . '" value="' . h(session_id()) . '">' : '');
|
||||
echo (SERVER !== null ? '<input type="hidden" name="' . DRIVER . '" value="' . h(SERVER) . '">' : "");
|
||||
echo '<input type="hidden" name="username" value="' . h($_GET["username"]) . '">';
|
||||
}
|
||||
|
||||
/** Print enum input field
|
||||
* @param string "radio"|"checkbox"
|
||||
* @param string
|
||||
* @param array
|
||||
* @param mixed string|array
|
||||
* @param string
|
||||
* @return null
|
||||
*/
|
||||
function enum_input($type, $attrs, $field, $value, $empty = null) {
|
||||
global $adminer;
|
||||
preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
|
||||
$return = ($empty !== null ? "<label><input type='$type'$attrs value='$empty'" . ((is_array($value) ? in_array($empty, $value) : $value === $empty) ? " checked" : "") . "><i>" . lang('empty') . "</i></label>" : "");
|
||||
foreach ($matches[1] as $i => $val) {
|
||||
$val = stripcslashes(str_replace("''", "'", $val));
|
||||
$checked = (is_array($value) ? in_array($val, $value) : $value === $val);
|
||||
$return .= " <label><input type='$type'$attrs value='" . h($val) . "'" . ($checked ? ' checked' : '') . '>' . h($adminer->editVal($val, $field)) . '</label>';
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Print edit input field
|
||||
* @param array one field from fields()
|
||||
* @param mixed
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return null
|
||||
*/
|
||||
function input($field, $value, $function, $autofocus = false) {
|
||||
global $driver, $adminer;
|
||||
$name = h(bracket_escape($field["field"]));
|
||||
echo "<td class='function'>";
|
||||
if (is_array($value) && !$function) {
|
||||
$value = json_encode($value, 128); // 128 - JSON_PRETTY_PRINT available since PHP 5.4
|
||||
$function = "json";
|
||||
}
|
||||
$reset = (JUSH == "mssql" && $field["auto_increment"]);
|
||||
if ($reset && !$_POST["save"]) {
|
||||
$function = null;
|
||||
}
|
||||
$functions = (isset($_GET["select"]) || $reset ? array("orig" => lang('original')) : array()) + $adminer->editFunctions($field);
|
||||
$disabled = stripos($field["default"], "GENERATED ALWAYS AS ") === 0 ? " disabled=''" : "";
|
||||
$attrs = " name='fields[$name]'$disabled" . ($autofocus ? " autofocus" : "");
|
||||
$enums = $driver->enumLength($field);
|
||||
if ($enums) {
|
||||
$field["type"] = "enum";
|
||||
$field["length"] = $enums;
|
||||
}
|
||||
echo $driver->unconvertFunction($field) . " ";
|
||||
if ($field["type"] == "enum") {
|
||||
echo h($functions[""]) . "<td>" . $adminer->editInput($_GET["edit"], $field, $attrs, $value);
|
||||
} else {
|
||||
$has_function = (in_array($function, $functions) || isset($functions[$function]));
|
||||
echo (count($functions) > 1
|
||||
? "<select name='function[$name]'$disabled>" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>"
|
||||
. on_help("getTarget(event).value.replace(/^SQL\$/, '')", 1)
|
||||
. script("qsl('select').onchange = functionChange;", "")
|
||||
: h(reset($functions))
|
||||
) . '<td>';
|
||||
$input = $adminer->editInput($_GET["edit"], $field, $attrs, $value); // usage in call is without a table
|
||||
if ($input != "") {
|
||||
echo $input;
|
||||
} elseif (preg_match('~bool~', $field["type"])) {
|
||||
echo "<input type='hidden'$attrs value='0'>"
|
||||
. "<input type='checkbox'" . (preg_match('~^(1|t|true|y|yes|on)$~i', $value) ? " checked='checked'" : "") . "$attrs value='1'>";
|
||||
} elseif ($field["type"] == "set") {
|
||||
preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
|
||||
foreach ($matches[1] as $i => $val) {
|
||||
$val = stripcslashes(str_replace("''", "'", $val));
|
||||
$checked = in_array($val, explode(",", $value), true);
|
||||
echo " <label><input type='checkbox' name='fields[$name][$i]' value='" . h($val) . "'" . ($checked ? ' checked' : '') . ">" . h($adminer->editVal($val, $field)) . '</label>';
|
||||
}
|
||||
} elseif (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
|
||||
echo "<input type='file' name='fields-$name'>";
|
||||
} elseif (($text = preg_match('~text|lob|memo~i', $field["type"])) || preg_match("~\n~", $value)) {
|
||||
if ($text && JUSH != "sqlite") {
|
||||
$attrs .= " cols='50' rows='12'";
|
||||
} else {
|
||||
$rows = min(12, substr_count($value, "\n") + 1);
|
||||
$attrs .= " cols='30' rows='$rows'" . ($rows == 1 ? " style='height: 1.2em;'" : ""); // 1.2em - line-height
|
||||
}
|
||||
echo "<textarea$attrs>" . h($value) . '</textarea>';
|
||||
} elseif ($function == "json" || preg_match('~^jsonb?$~', $field["type"])) {
|
||||
echo "<textarea$attrs cols='50' rows='12' class='jush-js'>" . h($value) . '</textarea>';
|
||||
} else {
|
||||
// int(3) is only a display hint
|
||||
$types = $driver->types();
|
||||
$maxlength = (!preg_match('~int~', $field["type"]) && preg_match('~^(\d+)(,(\d+))?$~', $field["length"], $match)
|
||||
? ((preg_match("~binary~", $field["type"]) ? 2 : 1) * $match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0))
|
||||
: ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0)
|
||||
);
|
||||
if (JUSH == 'sql' && min_version(5.6) && preg_match('~time~', $field["type"])) {
|
||||
$maxlength += 7; // microtime
|
||||
}
|
||||
// type='date' and type='time' display localized value which may be confusing, type='datetime' uses 'T' as date and time separator
|
||||
echo "<input"
|
||||
. ((!$has_function || $function === "") && preg_match('~(?<!o)int(?!er)~', $field["type"]) && !preg_match('~\[\]~', $field["full_type"]) ? " type='number'" : "")
|
||||
. " value='" . h($value) . "'" . ($maxlength ? " data-maxlength='$maxlength'" : "")
|
||||
. (preg_match('~char|binary~', $field["type"]) && $maxlength > 20 ? " size='40'" : "")
|
||||
. "$attrs>"
|
||||
;
|
||||
}
|
||||
echo $adminer->editHint($_GET["edit"], $field, $value);
|
||||
// skip 'original'
|
||||
$first = 0;
|
||||
foreach ($functions as $key => $val) {
|
||||
if ($key === "" || !$val) {
|
||||
break;
|
||||
}
|
||||
$first++;
|
||||
}
|
||||
if ($first) {
|
||||
echo script("mixin(qsl('td'), {onchange: partial(skipOriginal, $first), oninput: function () { this.onchange(); }});");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Process edit input field
|
||||
* @param one field from fields()
|
||||
* @return string or false to leave the original value
|
||||
*/
|
||||
function process_input($field) {
|
||||
global $adminer, $driver;
|
||||
if (stripos($field["default"], "GENERATED ALWAYS AS ") === 0) {
|
||||
return null;
|
||||
}
|
||||
$idf = bracket_escape($field["field"]);
|
||||
$function = $_POST["function"][$idf];
|
||||
$value = $_POST["fields"][$idf];
|
||||
if ($field["type"] == "enum" || $driver->enumLength($field)) {
|
||||
if ($value == -1) {
|
||||
return false;
|
||||
}
|
||||
if ($value == "") {
|
||||
return "NULL";
|
||||
}
|
||||
}
|
||||
if ($field["auto_increment"] && $value == "") {
|
||||
return null;
|
||||
}
|
||||
if ($function == "orig") {
|
||||
return (preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"]) ? idf_escape($field["field"]) : false);
|
||||
}
|
||||
if ($function == "NULL") {
|
||||
return "NULL";
|
||||
}
|
||||
if ($field["type"] == "set") {
|
||||
$value = implode(",", (array) $value);
|
||||
}
|
||||
if ($function == "json") {
|
||||
$function = "";
|
||||
$value = json_decode($value, true);
|
||||
if (!is_array($value)) {
|
||||
return false; //! report errors
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
if (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
|
||||
$file = get_file("fields-$idf");
|
||||
if (!is_string($file)) {
|
||||
return false; //! report errors
|
||||
}
|
||||
return $driver->quoteBinary($file);
|
||||
}
|
||||
return $adminer->processInput($field, $value, $function);
|
||||
}
|
||||
|
||||
/** Print results of search in all tables
|
||||
* @uses $_GET["where"][0]
|
||||
* @uses $_POST["tables"]
|
||||
* @return null
|
||||
*/
|
||||
function search_tables() {
|
||||
global $adminer, $connection;
|
||||
$_GET["where"][0]["val"] = $_POST["query"];
|
||||
$sep = "<ul>\n";
|
||||
foreach (table_status('', true) as $table => $table_status) {
|
||||
$name = $adminer->tableName($table_status);
|
||||
if (isset($table_status["Engine"]) && $name != "" && (!$_POST["tables"] || in_array($table, $_POST["tables"]))) {
|
||||
$result = $connection->query("SELECT" . limit("1 FROM " . table($table), " WHERE " . implode(" AND ", $adminer->selectSearchProcess(fields($table), array())), 1));
|
||||
if (!$result || $result->fetch_row()) {
|
||||
$print = "<a href='" . h(ME . "select=" . urlencode($table) . "&where[0][op]=" . urlencode($_GET["where"][0]["op"]) . "&where[0][val]=" . urlencode($_GET["where"][0]["val"])) . "'>$name</a>";
|
||||
echo "$sep<li>" . ($result ? $print : "<p class='error'>$print: " . error()) . "\n";
|
||||
$sep = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
echo ($sep ? "<p class='message'>" . lang('No tables.') : "</ul>") . "\n";
|
||||
}
|
||||
|
||||
/** Return events to display help on mouse over
|
||||
* @param string JS expression
|
||||
* @param bool JS expression
|
||||
* @return string
|
||||
*/
|
||||
function on_help($command, $side = 0) {
|
||||
return script("mixin(qsl('select, input'), {onmouseover: function (event) { helpMouseover.call(this, event, $command, $side) }, onmouseout: helpMouseout});", "");
|
||||
}
|
||||
|
||||
/** Print edit data form
|
||||
* @param string
|
||||
* @param array
|
||||
* @param mixed
|
||||
* @param bool
|
||||
* @return null
|
||||
*/
|
||||
function edit_form($table, $fields, $row, $update) {
|
||||
global $adminer, $token, $error;
|
||||
$table_name = $adminer->tableName(table_status1($table, true));
|
||||
page_header(
|
||||
($update ? lang('Edit') : lang('Insert')),
|
||||
$error,
|
||||
array("select" => array($table, $table_name)),
|
||||
$table_name
|
||||
);
|
||||
$adminer->editRowPrint($table, $fields, $row, $update);
|
||||
if ($row === false) {
|
||||
echo "<p class='error'>" . lang('No rows.') . "\n";
|
||||
return;
|
||||
}
|
||||
echo "<form action='' method='post' enctype='multipart/form-data' id='form'>\n";
|
||||
if (!$fields) {
|
||||
echo "<p class='error'>" . lang('You have no privileges to update this table.') . "\n";
|
||||
} else {
|
||||
echo "<table class='layout'>" . script("qsl('table').onkeydown = editingKeydown;");
|
||||
$autofocus = !$_POST;
|
||||
foreach ($fields as $name => $field) {
|
||||
echo "<tr><th>" . $adminer->fieldName($field);
|
||||
$default = $_GET["set"][bracket_escape($name)];
|
||||
if ($default === null) {
|
||||
$default = $field["default"];
|
||||
if ($field["type"] == "bit" && preg_match("~^b'([01]*)'\$~", $default, $regs)) {
|
||||
$default = $regs[1];
|
||||
}
|
||||
if (JUSH == "sql" && preg_match('~binary~', $field["type"])) {
|
||||
$default = bin2hex($default); // same as UNHEX
|
||||
}
|
||||
}
|
||||
$value = ($row !== null
|
||||
? ($row[$name] != "" && JUSH == "sql" && preg_match("~enum|set~", $field["type"]) && is_array($row[$name])
|
||||
? implode(",", $row[$name])
|
||||
: (is_bool($row[$name]) ? +$row[$name] : $row[$name])
|
||||
)
|
||||
: (!$update && $field["auto_increment"]
|
||||
? ""
|
||||
: (isset($_GET["select"]) ? false : $default)
|
||||
)
|
||||
);
|
||||
if (!$_POST["save"] && is_string($value)) {
|
||||
$value = $adminer->editVal($value, $field);
|
||||
}
|
||||
$function = ($_POST["save"]
|
||||
? (string) $_POST["function"][$name]
|
||||
: ($update && preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"])
|
||||
? "now"
|
||||
: ($value === false ? null : ($value !== null ? '' : 'NULL'))
|
||||
)
|
||||
);
|
||||
if (!$_POST && !$update && $value == $field["default"] && preg_match('~^[\w.]+\(~', $value)) {
|
||||
$function = "SQL";
|
||||
}
|
||||
if (preg_match("~time~", $field["type"]) && preg_match('~^CURRENT_TIMESTAMP~i', $value)) {
|
||||
$value = "";
|
||||
$function = "now";
|
||||
}
|
||||
if ($field["type"] == "uuid" && $value == "uuid()") {
|
||||
$value = "";
|
||||
$function = "uuid";
|
||||
}
|
||||
if ($autofocus !== false) {
|
||||
$autofocus = ($field["auto_increment"] || $function == "now" || $function == "uuid" ? null : true); // null - don't autofocus this input but check the next one
|
||||
}
|
||||
input($field, $value, $function, $autofocus);
|
||||
if ($autofocus) {
|
||||
$autofocus = false;
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
if (!support("table")) {
|
||||
echo "<tr>"
|
||||
. "<th><input name='field_keys[]'>"
|
||||
. script("qsl('input').oninput = fieldChange;")
|
||||
. "<td class='function'>" . html_select("field_funs[]", $adminer->editFunctions(array("null" => isset($_GET["select"]))))
|
||||
. "<td><input name='field_vals[]'>"
|
||||
. "\n"
|
||||
;
|
||||
}
|
||||
echo "</table>\n";
|
||||
}
|
||||
echo "<p>\n";
|
||||
if ($fields) {
|
||||
echo "<input type='submit' value='" . lang('Save') . "'>\n";
|
||||
if (!isset($_GET["select"])) {
|
||||
echo "<input type='submit' name='insert' value='" . ($update
|
||||
? lang('Save and continue edit')
|
||||
: lang('Save and insert next')
|
||||
) . "' title='Ctrl+Shift+Enter'>\n";
|
||||
echo ($update ? script("qsl('input').onclick = function () { return !ajaxForm(this.form, '" . lang('Saving') . "…', this); };") : "");
|
||||
}
|
||||
}
|
||||
echo ($update ? "<input type='submit' name='delete' value='" . lang('Delete') . "'>" . confirm() . "\n" : "");
|
||||
if (isset($_GET["select"])) {
|
||||
hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"]));
|
||||
}
|
||||
?>
|
||||
<input type="hidden" name="referer" value="<?php echo h(isset($_POST["referer"]) ? $_POST["referer"] : $_SERVER["HTTP_REFERER"]); ?>">
|
||||
<input type="hidden" name="save" value="1">
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
@@ -63,10 +63,12 @@ function get_lang() {
|
||||
* @param int
|
||||
* @return string
|
||||
*/
|
||||
// this is matched by compile.php
|
||||
function lang($idf, $number = null) {
|
||||
global $LANG, $translations;
|
||||
$translation = ($translations[$idf] ?: $idf);
|
||||
if (is_array($translation)) {
|
||||
// this is matched by compile.php
|
||||
$pos = ($number == 1 ? 0
|
||||
: ($LANG == 'cs' || $LANG == 'sk' ? ($number && $number < 5 ? 1 : 2) // different forms for 1, 2-4, other
|
||||
: ($LANG == 'fr' ? (!$number ? 0 : 1) // different forms for 0-1, other
|
||||
@@ -75,8 +77,8 @@ function lang($idf, $number = null) {
|
||||
: ($LANG == 'lt' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1, 12-19, other
|
||||
: ($LANG == 'lv' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number ? 1 : 2)) // different forms for 1 except 11, other, 0
|
||||
: (in_array($LANG, array('bs', 'ru', 'sr', 'uk')) ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1 except 11, 2-4 except 12-14, other
|
||||
: 1 // different forms for 1, other
|
||||
)))))))); // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
|
||||
: 1)))))))) // different forms for 1, other
|
||||
; // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
|
||||
$translation = $translation[$pos];
|
||||
}
|
||||
$args = func_get_args();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
$VERSION = "5.0.5";
|
||||
$VERSION = "5.0.6";
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
|
||||
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||
*/
|
||||
// this is matched by compile.php
|
||||
|
||||
namespace Adminer;
|
||||
|
||||
@@ -15,6 +16,7 @@ include "./include/tmpfile.inc.php";
|
||||
if (isset($_GET["select"]) && ($_POST["edit"] || $_POST["clone"]) && !$_POST["save"]) {
|
||||
$_GET["edit"] = $_GET["select"];
|
||||
}
|
||||
// this is matched by compile.php
|
||||
if (isset($_GET["callf"])) {
|
||||
$_GET["call"] = $_GET["callf"];
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ if (JUSH == "mongo") { // doesn't support primary key
|
||||
}
|
||||
$row = $_POST;
|
||||
if ($row) {
|
||||
set_adminer_settings(array("index_options" => $row["options"]));
|
||||
save_settings(array("index_options" => $row["options"]));
|
||||
}
|
||||
if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) {
|
||||
$alter = array();
|
||||
@@ -97,7 +97,7 @@ if (!$row) {
|
||||
$row["indexes"] = $indexes;
|
||||
}
|
||||
$lengths = (JUSH == "sql" || JUSH == "mssql");
|
||||
$show_options = ($_POST ? $_POST["options"] : adminer_setting("index_options"));
|
||||
$show_options = ($_POST ? $_POST["options"] : get_setting("index_options"));
|
||||
?>
|
||||
|
||||
<form action="" method="post">
|
||||
|
||||
@@ -7,7 +7,7 @@ $indexes = indexes($TABLE);
|
||||
$fields = fields($TABLE);
|
||||
$foreign_keys = column_foreign_keys($TABLE);
|
||||
$oid = $table_status["Oid"];
|
||||
parse_str($_COOKIE["adminer_import"], $adminer_import);
|
||||
$adminer_import = get_settings("adminer_import");
|
||||
|
||||
$rights = array(); // privilege => 0
|
||||
$columns = array(); // selectable columns
|
||||
@@ -83,7 +83,7 @@ if ($_POST && !$error) {
|
||||
}
|
||||
$where_check = ($where_check ? "\nWHERE " . implode(" AND ", $where_check) : "");
|
||||
if ($_POST["export"]) {
|
||||
cookie("adminer_import", "output=" . urlencode($_POST["output"]) . "&format=" . urlencode($_POST["format"]));
|
||||
save_settings(array("output" => $_POST["output"], "format" => $_POST["format"]), "adminer_import");
|
||||
dump_headers($TABLE);
|
||||
$adminer->dumpTable($TABLE, "");
|
||||
$from = ($select ? implode(", ", $select) : "*")
|
||||
@@ -195,7 +195,7 @@ if ($_POST && !$error) {
|
||||
} elseif (!preg_match('~~u', $file)) {
|
||||
$error = lang('File must be in UTF-8 encoding.');
|
||||
} else {
|
||||
cookie("adminer_import", "output=" . urlencode($adminer_import["output"]) . "&format=" . urlencode($_POST["separator"]));
|
||||
save_settings(array("output" => $adminer_import["output"], "format" => $_POST["separator"]), "adminer_import");
|
||||
$result = true;
|
||||
$cols = array_keys($fields);
|
||||
preg_match_all('~(?>"[^"]*"|[^"\r\n]+)+~', $file, $matches);
|
||||
@@ -453,7 +453,7 @@ if (!$columns && support("table")) {
|
||||
$value = $_POST["val"][$unique_idf][bracket_escape($key)];
|
||||
$editable = !is_array($row[$key]) && is_utf8($val) && $rows[$n][$key] == $row[$key] && !$functions[$key] && !$field["generated"];
|
||||
$text = preg_match('~text|json|lob~', $field["type"]);
|
||||
echo "<td id='$id'";
|
||||
echo "<td id='$id'" . (preg_match(number_type(), $field["type"]) && is_numeric(strip_tags($val)) ? " class='number'" : "");
|
||||
if (($_GET["modify"] && $editable) || $value !== null) {
|
||||
$h_value = h($value !== null ? $value : $row[$key]);
|
||||
echo ">" . ($text ? "<textarea name='$id' cols='30' rows='" . (substr_count($row[$key], "\n") + 1) . "'>$h_value</textarea>" : "<input name='$id' value='$h_value' size='$lengths[$key]'>");
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
namespace Adminer;
|
||||
|
||||
if (!$error && $_POST["export"]) {
|
||||
save_settings(array("output" => $_POST["output"], "format" => $_POST["format"]), "adminer_import");
|
||||
dump_headers("sql");
|
||||
$adminer->dumpTable("", "");
|
||||
$adminer->dumpData("", "table", $_POST["query"]);
|
||||
@@ -64,7 +65,7 @@ if (!$error && $_POST) {
|
||||
$errors = array();
|
||||
$parse = '[\'"' . (JUSH == "sql" ? '`#' : (JUSH == "sqlite" ? '`[' : (JUSH == "mssql" ? '[' : ''))) . ']|/\*|-- |$' . (JUSH == "pgsql" ? '|\$[^$]*\$' : '');
|
||||
$total_start = microtime(true);
|
||||
parse_str($_COOKIE["adminer_export"], $adminer_export);
|
||||
$adminer_export = get_settings("adminer_import"); // this doesn't offer SQL export so we match the import/export style at select
|
||||
$dump_format = $adminer->dumpFormat();
|
||||
unset($dump_format["sql"]);
|
||||
|
||||
@@ -89,8 +90,8 @@ if (!$error && $_POST) {
|
||||
$pattern = ($found == '/*' ? '\*/'
|
||||
: ($found == '[' ? ']'
|
||||
: (preg_match('~^-- |^#~', $found) ? "\n"
|
||||
: preg_quote($found) . ($c_style_escapes ? "|\\\\." : "")
|
||||
)));
|
||||
: preg_quote($found) . ($c_style_escapes ? "|\\\\." : "")))
|
||||
);
|
||||
|
||||
while (preg_match("($pattern|\$)s", $query, $match, PREG_OFFSET_CAPTURE, $offset)) {
|
||||
$s = $match[0][0];
|
||||
|
||||
@@ -12,9 +12,8 @@ thead td, thead th { color: #a8b05f; background: #011d35; }
|
||||
thead th a { color: #a8b05f; }
|
||||
fieldset { border-color: #16548a; }
|
||||
code { background: #11385a; }
|
||||
code[class^="jush-"] { color: #002240; background: #81a0bc; padding: .2em .5em; }
|
||||
tbody tr:hover td, tbody tr:hover th { background: #133553; }
|
||||
pre.jush { background: #a7c3dc; }
|
||||
pre.jush { background: #11385a; }
|
||||
input.default { box-shadow: 1px 1px 1px #888; }
|
||||
input.required, input.maxlength { box-shadow: 1px 1px 1px red; }
|
||||
.version { color: #888; }
|
||||
|
||||
@@ -665,7 +665,7 @@ function indexesAddColumn(prefix) {
|
||||
* @param string
|
||||
*/
|
||||
function sqlSubmit(form, root) {
|
||||
if (encodeURIComponent(form['query'].value).length < 2e3) {
|
||||
if (encodeURIComponent(form['query'].value).length < 500) {
|
||||
form.action = root
|
||||
+ '&sql=' + encodeURIComponent(form['query'].value)
|
||||
+ (form['limit'].value ? '&limit=' + +form['limit'].value : '')
|
||||
|
||||
@@ -880,16 +880,6 @@ function addEvent(el, action, handler) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Defer focusing element
|
||||
* @param HTMLElement
|
||||
*/
|
||||
function focus(el) {
|
||||
setTimeout(function () {
|
||||
// this has to be an anonymous function because Firefox passes some arguments to setTimeout callback
|
||||
el.focus();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
/** Clone node and setup submit highlighting
|
||||
* @param HTMLElement
|
||||
* @return HTMLElement
|
||||
|
||||
281
changes.txt
281
changes.txt
@@ -1,9 +1,22 @@
|
||||
Adminer 5.0.6 (released 2025-03-17):
|
||||
Align numbers right (bug #912)
|
||||
Display comment in title of field
|
||||
Remember export setting at SQL command
|
||||
Shorten queries saved from SQL command to URL (bug #917)
|
||||
SQL textarea: Open help on Ctrl+click
|
||||
Security: Disallow writing temporary files to symlinks (bug SF-855)
|
||||
MariaDB: Display MariaDB instead of MySQL
|
||||
CSS: Dark mode syntax highlighting
|
||||
CSS: Dark input fields in dark mode
|
||||
Designs named adminer-dark.css use dark basic style
|
||||
Plugins: Add method syntaxHighlighting()
|
||||
|
||||
Adminer 5.0.5 (released 2025-03-13):
|
||||
MySQL: Display converting function for binary, bit or geometry fields
|
||||
MySQL: Display default values of binary columns
|
||||
MySQL: Allow setting default values of json column
|
||||
MariaDB: Don't display NULL as default value (regression from 5.0.0)
|
||||
PostgreSQL PDO: Escape bytea values (bug #218)
|
||||
PostgreSQL PDO: Escape bytea values (bug SF-218)
|
||||
CockroachDB: Display version
|
||||
CockroachDB: Recognize unique_rowid() as auto_increment
|
||||
MS SQL: Fix editing rows with datetime column in primary key
|
||||
@@ -18,7 +31,7 @@ Fix gzip export (bug #896, regression from 5.0.0)
|
||||
Fix importing multiple SQL files not terminated by semicolon
|
||||
Use <datalist> for altering collations
|
||||
MySQL: Allow setting default values of text column
|
||||
MySQL: Stop treating enum and set as numbers (bug #475)
|
||||
MySQL: Stop treating enum and set as numbers (bug SF-475)
|
||||
MySQL, MariaDB: Fix default values with ' (bug #895)
|
||||
MariaDB: Fix creating and altering generated columns (bug #897)
|
||||
PostgreSQL: Fix "where" and "order" privileges (bug #902, regression from 5.0.2)
|
||||
@@ -28,30 +41,30 @@ Elastic: Fix displaying sparse rows (PR #893)
|
||||
Plugins: Add method dumpFooter()
|
||||
|
||||
Adminer 5.0.2 (released 2025-03-10):
|
||||
PostgreSQL: Fix setting NULL and original value on enum (bug #884)
|
||||
PostgreSQL: Fix setting NULL and original value on enum (bug SF-884)
|
||||
CockroachDB: Add support via PostgreSQL driver
|
||||
Elasticsearch: Add support for "where" and "order" field privilege
|
||||
|
||||
Adminer 5.0.1 (released 2025-03-07):
|
||||
Fix bulk operations with tables (regression from 5.0.0)
|
||||
Remove duplicate columns from select (bug #670)
|
||||
MariaDB: Fix link to status variable doc (bug #658)
|
||||
Remove duplicate columns from select (bug SF-670)
|
||||
MariaDB: Fix link to status variable doc (bug SF-658)
|
||||
PostgreSQL: Support indexes on materialized views (PR #467)
|
||||
Elasticsearch: Drop support for version < 7
|
||||
|
||||
Adminer 5.0.0 (released 2025-03-07):
|
||||
Speed up with disabled output buffering
|
||||
Allow creating generated columns (bug #857)
|
||||
Allow creating generated columns (bug SF-857)
|
||||
Don't autofocus computed fields in insert form
|
||||
Skip generated columns in multi-edit (bug #882)
|
||||
Skip generated columns in multi-edit (bug SF-882)
|
||||
MySQL: Display generated value in table structure
|
||||
MySQL: Drop support for MySQL 4
|
||||
PostgreSQL: Compute size of all databases (bug #881)
|
||||
PostgreSQL: Compute size of all databases (bug SF-881)
|
||||
PostgreSQL: Do not alter indexes with expressions
|
||||
PostgreSQL: Fix export of indexes with expressions (bug #768)
|
||||
PostgreSQL: Fix export of indexes with expressions (bug SF-768)
|
||||
PostgreSQL: Display ENUM types
|
||||
PostgreSQL: Export ENUM types (bug #587)
|
||||
PostgreSQL: Display ? instead of -1 rows in table overview (bug #883)
|
||||
PostgreSQL: Export ENUM types (bug SF-587)
|
||||
PostgreSQL: Display ? instead of -1 rows in table overview (bug SF-883)
|
||||
PostgreSQL: Show accessible databases to non-owners (regression from 4.9.1)
|
||||
PostgreSQL: Skip editing generated columns
|
||||
PostgreSQL, MS SQL, Oracle: Hide table actions for information_schema
|
||||
@@ -60,10 +73,10 @@ SQLite: Support generated columns
|
||||
SQLite: Add command Check tables
|
||||
SQLite: Display all rows of variable values
|
||||
SQLite: Remove support for SQLite version 2
|
||||
MS SQL: Support export (bug #480)
|
||||
MS SQL: Support export (bug SF-480)
|
||||
MS SQL: Display foreign keys ON UPDATE and ON DELETE
|
||||
MS SQL: Support computed columns
|
||||
MS SQL: Fix CSV import (bug #859)
|
||||
MS SQL: Fix CSV import (bug SF-859)
|
||||
MS SQL: Fix altering foreign key
|
||||
MS SQL PDO: Support offset
|
||||
MS SQL: Remove support for MSSQL extension
|
||||
@@ -82,28 +95,28 @@ Hide index column options by default
|
||||
Offer original values in multi-row editing (regression from 4.16.0)
|
||||
Print SQL errors as comments in export (regression from 3.2.0)
|
||||
MySQL, PostgreSQL, MS SQL: Support CHECK constraint
|
||||
MySQL: Show comments at routine call (bug #874)
|
||||
MySQL: Show comments at routine call (bug SF-874)
|
||||
MySQL: Don't offer empty enum value in edit
|
||||
MySQL 9+: Support vector type
|
||||
PostgreSQL: Link user defined types
|
||||
PostgreSQL: Constraint enum values in editing (bug #270)
|
||||
PostgreSQL: Constraint enum values in editing (bug SF-270)
|
||||
PostgreSQL: Export functions
|
||||
PostgreSQL 8+: Fix exporting table constraints
|
||||
SQLite: Show all supported pragmas in Variables
|
||||
MS SQL: Allow altering table in non-default schema (bug #405)
|
||||
MS SQL: Fix default values (bug #732, bug #733)
|
||||
MS SQL: Allow altering table in non-default schema (bug SF-405)
|
||||
MS SQL: Fix default values (bug SF-732, bug SF-733)
|
||||
MS SQL: Fix length of nvarchar columns
|
||||
Editor PDO: Select value of foreign key in edit (bug #847)
|
||||
Editor PDO: Select value of foreign key in edit (bug SF-847)
|
||||
Mobile devices: Use device width
|
||||
|
||||
Adminer 4.16.0 (released 2025-02-20):
|
||||
MySQL: Fix saving bit(64) values (bug #839)
|
||||
PostgreSQL: Preserve whitespace in EXPLAIN (bug #827)
|
||||
MySQL: Fix saving bit(64) values (bug SF-839)
|
||||
PostgreSQL: Preserve whitespace in EXPLAIN (bug SF-827)
|
||||
PostgreSQL: Support SSL
|
||||
PostgreSQL: Support altering auto_increment (bug #761)
|
||||
SQLite: Fix altering forign keys (bug #841)
|
||||
SQLite: Fix expressions in default values (bug #860)
|
||||
MS SQL: Foreign keys in non-default schema (bug #833)
|
||||
PostgreSQL: Support altering auto_increment (bug SF-761)
|
||||
SQLite: Fix altering forign keys (bug SF-841)
|
||||
SQLite: Fix expressions in default values (bug SF-860)
|
||||
MS SQL: Foreign keys in non-default schema (bug SF-833)
|
||||
Oracle: Include tables granted by other user
|
||||
MongoDB: Execute commands against the selected DB
|
||||
|
||||
@@ -170,28 +183,28 @@ PostgreSQL: Don't reset table comments (regression from 4.2.0)
|
||||
PostgreSQL PDO: Allow editing rows identified by boolean column (PR #380)
|
||||
|
||||
Adminer 4.8.1 (released 2021-05-14):
|
||||
Internet Explorer or PDO in Adminer 4.7.8-4.8.0: Fix XSS in doc_link (bug #797)
|
||||
Fix more PHP 8 warnings (bug #781)
|
||||
Avoid PHP warnings with PDO drivers (bug #786, regression from 4.7.8)
|
||||
MySQL: Allow moving views to other DB and renaming DB with views (bug #783)
|
||||
Internet Explorer or PDO in Adminer 4.7.8-4.8.0: Fix XSS in doc_link (bug SF-797)
|
||||
Fix more PHP 8 warnings (bug SF-781)
|
||||
Avoid PHP warnings with PDO drivers (bug SF-786, regression from 4.7.8)
|
||||
MySQL: Allow moving views to other DB and renaming DB with views (bug SF-783)
|
||||
MariaDB: Do not treat sequences as views (PR #416)
|
||||
PostgreSQL: Support UPDATE OF triggers (bug #789)
|
||||
PostgreSQL: Support UPDATE OF triggers (bug SF-789)
|
||||
PostgreSQL: Support triggers with more events (OR)
|
||||
PostgreSQL: Fix parsing of foreign keys with non-ASCII column names
|
||||
PostgreSQL < 10 PDO: Avoid displaying GENERATED ALWAYS BY IDENTITY everywhere (bug #785, regression from 4.7.9)
|
||||
SQLite: Fix displayed types (bug #784, regression from 4.8.0)
|
||||
PostgreSQL < 10 PDO: Avoid displaying GENERATED ALWAYS BY IDENTITY everywhere (bug SF-785, regression from 4.7.9)
|
||||
SQLite: Fix displayed types (bug SF-784, regression from 4.8.0)
|
||||
|
||||
Adminer 4.8.0 (released 2021-02-10):
|
||||
Support function default values in insert (bug #713)
|
||||
Support function default values in insert (bug SF-713)
|
||||
Allow SQL pseudo-function in insert
|
||||
Skip date columns for non-date values in search anywhere
|
||||
Add DB version to comment in export
|
||||
Support PHP 8 in create table (regression from 4.7.9)
|
||||
MySQL 8: Fix EXPLAIN in SQL command
|
||||
PostgreSQL: Create PRIMARY KEY for auto increment columns
|
||||
PostgreSQL: Avoid exporting empty sequence last value (bug #768)
|
||||
PostgreSQL: Avoid exporting empty sequence last value (bug SF-768)
|
||||
PostgreSQL: Do not show triggers from other schemas (PR #412)
|
||||
PostgreSQL: Fix multi-parameter functions in default values (bug #736)
|
||||
PostgreSQL: Fix multi-parameter functions in default values (bug SF-736)
|
||||
PostgreSQL: Fix displaying NULL bytea fields
|
||||
PostgreSQL PDO: Do not select NULL function for false values in edit
|
||||
Oracle: Alter indexes
|
||||
@@ -202,21 +215,21 @@ MongoDB: Handle errors
|
||||
SimpleDB, Firebird, ClickHouse: Move to plugin
|
||||
|
||||
Adminer 4.7.9 (released 2021-02-07):
|
||||
Fix XSS in browsers which don't encode URL parameters (bug #775, regression from 4.7.0)
|
||||
Fix XSS in browsers which don't encode URL parameters (bug SF-775, regression from 4.7.0)
|
||||
Elasticsearch, ClickHouse: Do not print response if HTTP code is not 200
|
||||
Don't syntax highlight during IME composition (bug #747)
|
||||
Quote values with leading and trailing zeroes in CSV export (bug #777)
|
||||
Don't syntax highlight during IME composition (bug SF-747)
|
||||
Quote values with leading and trailing zeroes in CSV export (bug SF-777)
|
||||
Link URLs in SQL command (PR #411)
|
||||
Fix displayed foreign key columns from other DB (bug #766)
|
||||
Fix displayed foreign key columns from other DB (bug SF-766)
|
||||
Re-enable PHP warnings (regression from 4.7.8)
|
||||
MySQL: Do not export names in quotes with sql_mode='ANSI_QUOTES' (bug #749)
|
||||
MySQL: Do not export names in quotes with sql_mode='ANSI_QUOTES' (bug SF-749)
|
||||
MySQL: Avoid error in PHP 8 when connecting to socket (PR #409)
|
||||
MySQL: Don't quote default value of text fields (bug #779)
|
||||
MySQL: Don't quote default value of text fields (bug SF-779)
|
||||
PostgreSQL: Export all FKs after all CREATE TABLE (PR #351)
|
||||
PostgreSQL: Fix dollar-quoted syntax highlighting (bug #738)
|
||||
PostgreSQL: Fix dollar-quoted syntax highlighting (bug SF-738)
|
||||
PostgreSQL: Do not show view definition from other schema (PR #392)
|
||||
PostgreSQL: Use bigserial for bigint auto increment (bug #765, regression from 3.0.0)
|
||||
PostgreSQL PDO: Support PgBouncer, unsupport PostgreSQL < 9.1 (bug #771)
|
||||
PostgreSQL: Use bigserial for bigint auto increment (bug SF-765, regression from 3.0.0)
|
||||
PostgreSQL PDO: Support PgBouncer, unsupport PostgreSQL < 9.1 (bug SF-771)
|
||||
PostgreSQL 10: Support GENERATED ALWAYS BY IDENTITY (PR #386)
|
||||
PostgreSQL 10: Support partitioned tables (PR #396)
|
||||
PostgreSQL 11: Create PRIMARY KEY for auto increment columns
|
||||
@@ -224,12 +237,12 @@ SQLite: Set busy_timeout to 500
|
||||
MS SQL: Don't truncate comments to 30 chars (PR #376)
|
||||
Elasticsearch 6: Fix displaying type mapping (PR #402)
|
||||
MongoDB: Fix password-less check in the mongo extension (PR #405)
|
||||
Editor: Cast to string when searching (bug #325)
|
||||
Editor: Cast to string when searching (bug SF-325)
|
||||
Editor: Avoid trailing dot in export filename
|
||||
|
||||
Adminer 4.7.8 (released 2020-12-06):
|
||||
Support PHP 8
|
||||
Disallow connecting to privileged ports (bug #769)
|
||||
Disallow connecting to privileged ports (bug SF-769)
|
||||
|
||||
Adminer 4.7.7 (released 2020-05-11):
|
||||
Fix open redirect if Adminer is accessible at //adminer.php%2F@
|
||||
@@ -238,15 +251,15 @@ Adminer 4.7.6 (released 2020-01-31):
|
||||
Speed up alter table form (regression from 4.4.0)
|
||||
Fix clicking on non-input fields in alter table (regression from 4.6.2)
|
||||
Display time of procedure execution
|
||||
Disallow connecting to ports > 65535 (bug #730)
|
||||
Disallow connecting to ports > 65535 (bug SF-730)
|
||||
MySQL: Always set foreign_key_checks in export
|
||||
PostgreSQL: Support exporting views
|
||||
Editor: Fix focusing foreign key search in select
|
||||
|
||||
Adminer 4.7.5 (released 2019-11-13):
|
||||
Add id="" to cells with failed inline edit (bug #708)
|
||||
PostgreSQL: Fix getting default value in PostgreSQL 12 (bug #719)
|
||||
PostgreSQL, Oracle: Set schema for EXPLAIN queries in SQL command (bug #706)
|
||||
Add id="" to cells with failed inline edit (bug SF-708)
|
||||
PostgreSQL: Fix getting default value in PostgreSQL 12 (bug SF-719)
|
||||
PostgreSQL, Oracle: Set schema for EXPLAIN queries in SQL command (bug SF-706)
|
||||
ClickHouse: SQL command
|
||||
Swedish translation
|
||||
|
||||
@@ -254,40 +267,40 @@ Adminer 4.7.4 (released 2019-10-22):
|
||||
Fix XSS if Adminer is accessible at URL /data:
|
||||
|
||||
Adminer 4.7.3 (released 2019-08-27):
|
||||
Allow editing foreign keys pointing to tables in other database/schema (bug #694)
|
||||
Fix blocking of concurrent instances in PHP >7.2 (bug #703)
|
||||
MySQL: Speed up displaying tables in large databases (bug #700, regression from 4.7.2)
|
||||
MySQL: Allow editing rows identified by negative floats (bug #695)
|
||||
Allow editing foreign keys pointing to tables in other database/schema (bug SF-694)
|
||||
Fix blocking of concurrent instances in PHP >7.2 (bug SF-703)
|
||||
MySQL: Speed up displaying tables in large databases (bug SF-700, regression from 4.7.2)
|
||||
MySQL: Allow editing rows identified by negative floats (bug SF-695)
|
||||
MySQL: Skip editing generated columns
|
||||
SQLite: Quote strings stored in integer columns in export (bug #696)
|
||||
SQLite: Handle error in altering table (bug #697)
|
||||
SQLite: Quote strings stored in integer columns in export (bug SF-696)
|
||||
SQLite: Handle error in altering table (bug SF-697)
|
||||
SQLite: Allow setting auto increment for empty tables
|
||||
SQLite: Preserve auto increment when recreating table
|
||||
MS SQL: Support foreign keys to other DB
|
||||
MongoDB: Allow setting authSource from environment variable
|
||||
|
||||
Adminer 4.7.2 (released 2019-07-18):
|
||||
Do not attempt logging in without password (bug #676)
|
||||
Stretch footer over the whole table width (bug #624)
|
||||
Do not attempt logging in without password (bug SF-676)
|
||||
Stretch footer over the whole table width (bug SF-624)
|
||||
Allow overwriting tables when copying them
|
||||
Fix displaying SQL command after Save and continue edit
|
||||
Cache busting for adminer.css
|
||||
MySQL: Fix displaying multi-columns foreign keys (bug #675, regression from 4.7.0)
|
||||
MySQL: Fix creating users and changing password in MySQL 8 (bug #663)
|
||||
MySQL: Fix displaying multi-columns foreign keys (bug SF-675, regression from 4.7.0)
|
||||
MySQL: Fix creating users and changing password in MySQL 8 (bug SF-663)
|
||||
MySQL: Pass SRID to GeomFromText
|
||||
PostgreSQL: Fix setting column comments on new table
|
||||
PostgreSQL: Display definitions of materialized views (bug #682)
|
||||
PostgreSQL: Fix table status in PostgreSQL 12 (bug #683)
|
||||
PostgreSQL: Display definitions of materialized views (bug SF-682)
|
||||
PostgreSQL: Fix table status in PostgreSQL 12 (bug SF-683)
|
||||
MS SQL: Support comments
|
||||
Elasticsearch: Fix setting number of rows
|
||||
|
||||
Adminer 4.7.1 (released 2019-01-24):
|
||||
Display the tables scrollbar (bug #647)
|
||||
Remember visible columns in Create Table form (bug #493)
|
||||
Display the tables scrollbar (bug SF-647)
|
||||
Remember visible columns in Create Table form (bug SF-493)
|
||||
Add autocomplete attributes to login form
|
||||
PHP <5.4 compatibility even with ClickHouse enabled (regression from 4.7.0)
|
||||
SQLite: Hide server field in login form
|
||||
Editor: Allow disabling boolean fields in PostgreSQL (bug #640)
|
||||
Editor: Allow disabling boolean fields in PostgreSQL (bug SF-640)
|
||||
|
||||
Adminer 4.7.0 (released 2018-11-24):
|
||||
Simplify storing executed SQL queries to bookmarks
|
||||
@@ -295,16 +308,16 @@ Warn when using password with leading or trailing spaces
|
||||
Hide import from server if importServerPath() returns an empty string
|
||||
Fix inline editing of empty cells (regression from 4.6.3)
|
||||
Allow adding more than two indexes and forign key columns at a time (regression from 4.4.0)
|
||||
Avoid overwriting existing tables when copying tables (bug #642)
|
||||
Avoid overwriting existing tables when copying tables (bug SF-642)
|
||||
Fix function change with set data type
|
||||
Increase username maxlength to 80 (bug #623)
|
||||
Increase username maxlength to 80 (bug SF-623)
|
||||
Make maxlength in all fields a soft limit
|
||||
Make tables horizontally scrollable
|
||||
MySQL: Support foreign keys created with ANSI quotes (bug #620)
|
||||
MySQL: Recognize ON UPDATE current_timestamp() (bug #632, bug #638)
|
||||
MySQL: Descending indexes in MySQL 8 (bug #643)
|
||||
PostgreSQL: Quote array values in export (bug #621)
|
||||
PostgreSQL: Export DESC indexes (bug #639)
|
||||
MySQL: Support foreign keys created with ANSI quotes (bug SF-620)
|
||||
MySQL: Recognize ON UPDATE current_timestamp() (bug SF-632, bug SF-638)
|
||||
MySQL: Descending indexes in MySQL 8 (bug SF-643)
|
||||
PostgreSQL: Quote array values in export (bug SF-621)
|
||||
PostgreSQL: Export DESC indexes (bug SF-639)
|
||||
PostgreSQL: Support GENERATED BY DEFAULT AS IDENTITY in PostgreSQL 10
|
||||
MS SQL: Pass database when connecting
|
||||
ClickHouse: Connect, databases list, tables list, select, SQL command
|
||||
@@ -316,26 +329,26 @@ Copy triggers when copying table
|
||||
Stop session before connecting
|
||||
Simplify running slow queries
|
||||
Decrease timeout for running slow queries from 5 seconds to 2 seconds
|
||||
Fix displaying info about non-alphabetical objects (bug #599)
|
||||
Fix displaying info about non-alphabetical objects (bug SF-599)
|
||||
Use secure cookies on HTTP if session.cookie_secure is set
|
||||
PDO: Support binary fields download
|
||||
MySQL: Disallow LOAD DATA LOCAL INFILE
|
||||
MySQL: Use CONVERT() only when searching for non-ASCII (bug #603)
|
||||
MySQL: Order database names in MySQL 8 (bug #613)
|
||||
PostgreSQL: Fix editing data in views (bug #605, regression from 4.6.0)
|
||||
PostgreSQL: Do not cast date/time/number/uuid searches to text (bug #608)
|
||||
PostgreSQL: Export false as 0 in PDO (bug #619)
|
||||
MySQL: Use CONVERT() only when searching for non-ASCII (bug SF-603)
|
||||
MySQL: Order database names in MySQL 8 (bug SF-613)
|
||||
PostgreSQL: Fix editing data in views (bug SF-605, regression from 4.6.0)
|
||||
PostgreSQL: Do not cast date/time/number/uuid searches to text (bug SF-608)
|
||||
PostgreSQL: Export false as 0 in PDO (bug SF-619)
|
||||
MS SQL: Support port with sqlsrv
|
||||
Editor: Do not check boolean checkboxes with false in PostgreSQL (bug #607)
|
||||
Editor: Do not check boolean checkboxes with false in PostgreSQL (bug SF-607)
|
||||
|
||||
Adminer 4.6.2 (released 2018-02-20):
|
||||
Semi-transparent border on table actions
|
||||
Shorten JSON values in select (bug #594)
|
||||
Shorten JSON values in select (bug SF-594)
|
||||
Speed up alter table form (regression from 4.4.0)
|
||||
Store current version without authentication and in Editor
|
||||
PostgreSQL: Fix exporting string default values
|
||||
PostgreSQL: Fix exporting sequences in PostgreSQL 10
|
||||
PostgreSQL: Add IF EXISTS to DROP SEQUENCE in export (bug #595)
|
||||
PostgreSQL: Add IF EXISTS to DROP SEQUENCE in export (bug SF-595)
|
||||
Editor: Fix displaying of true boolean values (regression from 4.5.0)
|
||||
|
||||
Adminer 4.6.1 (released 2018-02-09):
|
||||
@@ -344,12 +357,12 @@ Speed up rendering of long tables (regression from 4.4.0)
|
||||
Display notification about performing action after relogin
|
||||
Add system tables help links
|
||||
MySQL: Support non-utf8 charset in search in column
|
||||
MySQL: Support geometry in MySQL 8 (bug #574)
|
||||
MySQL: Support geometry in MySQL 8 (bug SF-574)
|
||||
MariaDB: Links to documentation
|
||||
SQLite: Allow deleting PRIMARY KEY from tables with auto increment
|
||||
PostgreSQL: Support binary files in bytea fields
|
||||
PostgreSQL: Don't treat interval type as number (bug #474)
|
||||
PostgreSQL: Cast to string when searching using LIKE (bug #325)
|
||||
PostgreSQL: Don't treat interval type as number (bug SF-474)
|
||||
PostgreSQL: Cast to string when searching using LIKE (bug SF-325)
|
||||
PostgreSQL: Fix condition for selecting no rows
|
||||
PostgreSQL: Support TRUNCATE+INSERT export
|
||||
Customization: Support connecting to MySQL via SSL
|
||||
@@ -370,34 +383,34 @@ MySQL: Add FIND_IN_SET search operator
|
||||
MariaDB: Support JSON since MariaDB 10.2
|
||||
SQLite, PostgreSQL: Limit rows in data manipulation without unique key
|
||||
PostgreSQL: Support routines
|
||||
PostgreSQL: Allow editing views with uppercase letters (bug #467)
|
||||
PostgreSQL: Allow now() as default value (bug #525)
|
||||
PostgreSQL: Allow editing views with uppercase letters (bug SF-467)
|
||||
PostgreSQL: Allow now() as default value (bug SF-525)
|
||||
SimpleDB: Document that allow_url_fopen is required
|
||||
Malay translation
|
||||
|
||||
Adminer 4.5.0 (released 2018-01-24):
|
||||
Display name of the object in confirmation when dropping it
|
||||
Display newlines in column comments (bug #573)
|
||||
Support current_timestamp() as default of time fields (bug #572)
|
||||
Hide window.opener from pages opened in a new window (bug #561)
|
||||
Display newlines in column comments (bug SF-573)
|
||||
Support current_timestamp() as default of time fields (bug SF-572)
|
||||
Hide window.opener from pages opened in a new window (bug SF-561)
|
||||
Display error when getting row to edit
|
||||
Store current Adminer version server-side to avoid excessive requests
|
||||
Adminer: Fix Search data in tables (regression from 4.4.0)
|
||||
CSP: Allow any styles, images, media and fonts, disallow base-uri
|
||||
MySQL: Support geometry in MySQL 8 (bug #574)
|
||||
MySQL: Support routines with comments in parameters (bug #460)
|
||||
MariaDB: Support fulltext and spatial indexes in InnoDB (bug #583)
|
||||
MySQL: Support geometry in MySQL 8 (bug SF-574)
|
||||
MySQL: Support routines with comments in parameters (bug SF-460)
|
||||
MariaDB: Support fulltext and spatial indexes in InnoDB (bug SF-583)
|
||||
SQLite: Enable foreign key checks
|
||||
PostgreSQL: Respect NULL default value
|
||||
PostgreSQL: Display foreign tables (bug #576)
|
||||
PostgreSQL: Display foreign tables (bug SF-576)
|
||||
PostgreSQL: Do not export triggers if not requested
|
||||
PostgreSQL: Export DROP SEQUENCE if dropping table
|
||||
PostgreSQL: Display boolean values as code (bug #562)
|
||||
PostgreSQL: Display boolean values as code (bug SF-562)
|
||||
MS SQL: Support freetds
|
||||
non-MySQL: Avoid CONVERT() (bug #509)
|
||||
non-MySQL: Avoid CONVERT() (bug SF-509)
|
||||
Elasticsearch: Insert, update, delete
|
||||
MongoDB: Support mongodb PHP extension
|
||||
Editor: Fix displaying of false values in PostgreSQL (bug #568)
|
||||
Editor: Fix displaying of false values in PostgreSQL (bug SF-568)
|
||||
|
||||
Adminer 4.4.0 (released 2018-01-17):
|
||||
Add Content Security Policy
|
||||
@@ -417,7 +430,7 @@ Customization: Always send security headers
|
||||
Hebrew translation
|
||||
|
||||
Adminer 4.3.1 (released 2017-04-14):
|
||||
Fix permanent login after logout (bug #539)
|
||||
Fix permanent login after logout (bug SF-539)
|
||||
Fix SQL command autofocus (regression from 4.0.0)
|
||||
PostgreSQL: Support JSON and JSONB data types
|
||||
PostgreSQL: Fix index size computation in PostgreSQL < 9.0 (regression from 4.3.0)
|
||||
@@ -464,16 +477,16 @@ MySQL: Use utf8mb4 in export only if required
|
||||
SQLite: Use EXPLAIN QUERY PLAN in SQL query
|
||||
|
||||
Adminer 4.2.0 (released 2015-02-07):
|
||||
Fix XSS in login form (bug #436)
|
||||
Fix XSS in login form (bug SF-436)
|
||||
Allow limiting number of displayed rows in SQL command
|
||||
Fix reading routine column collations
|
||||
Unlock session in alter database
|
||||
Make master key unreadable to others (bug #410)
|
||||
Make master key unreadable to others (bug SF-410)
|
||||
Fix edit by long non-utf8 string
|
||||
Specify encoding for PHP 5.6 with invalid default_charset
|
||||
Fix saving NULL value, bug since Adminer 4.0.3
|
||||
Send 403 for auth error
|
||||
Report offline and other AJAX errors (bug #419)
|
||||
Report offline and other AJAX errors (bug SF-419)
|
||||
Don't alter table comment if not changed
|
||||
Add links to documentation on table status page
|
||||
Fix handling of 64 bit numbers in auto_increment
|
||||
@@ -481,7 +494,7 @@ Add referrer: never meta tag
|
||||
MySQL: Use utf8mb4 if available
|
||||
MySQL: Support foreign keys in NDB storage
|
||||
PostgreSQL: Materialized views
|
||||
SQLite: Support CURRENT_* default values (bug #417)
|
||||
SQLite: Support CURRENT_* default values (bug SF-417)
|
||||
Elasticsearch: Use where in select
|
||||
Firebird: Alpha version
|
||||
Danish translation
|
||||
@@ -494,9 +507,9 @@ Display edit form after error in clone or multi-edit
|
||||
Trim trailing non-breaking spaces in SQL textarea
|
||||
Display time of the select command
|
||||
Print elapsed time in HTML instead of SQL command comment
|
||||
Improve gzip export ratio (bug #387)
|
||||
Improve gzip export ratio (bug SF-387)
|
||||
Use rel="noreferrer" for external links, skip adminer.org redirect in WebKit
|
||||
MySQL: Fix enum types in routines (bug #391)
|
||||
MySQL: Fix enum types in routines (bug SF-391)
|
||||
MySQL: Fix editing rows by binary values, bug since Adminer 3.7.1
|
||||
MySQL: Respect daylight saving time in dump, bug since Adminer 3.6.4
|
||||
MySQL 5.6.5+: Support ON UPDATE on datatime column
|
||||
@@ -564,7 +577,7 @@ Adminer 3.7.1 (released 2013-06-29):
|
||||
Increase click target for checkboxes
|
||||
Use shadow for highlighting default button
|
||||
Don't use LIMIT 1 if inline updating unique row
|
||||
Don't check previous checkbox on added column in create table (bug #326)
|
||||
Don't check previous checkbox on added column in create table (bug SF-326)
|
||||
Order table list by name
|
||||
Verify UTF-8 encoding of CSV import
|
||||
Notify user about expired master password for permanent login
|
||||
@@ -575,7 +588,7 @@ Display error on invalid alter table and view pages
|
||||
MySQL: Speed up updating rows without numeric or UTF-8 primary key
|
||||
Non-MySQL: Descending indexes
|
||||
PostgreSQL: Fix detecting oid column in PDO
|
||||
PostgreSQL: Handle timestamp types (bug #324)
|
||||
PostgreSQL: Handle timestamp types (bug SF-324)
|
||||
Korean translation
|
||||
|
||||
Adminer 3.7.0 (released 2013-05-19):
|
||||
@@ -588,17 +601,17 @@ Disable SQL export when applying functions in select
|
||||
Allow using lang() in plugins (customization)
|
||||
Remove bzip2 compression support
|
||||
Constraint memory used in TAR export
|
||||
Allow exporting views dependent on each other (bug #214)
|
||||
Fix resetting search (bug #318)
|
||||
Don't use LIMIT 1 if updating unique row (bug #320)
|
||||
Allow exporting views dependent on each other (bug SF-214)
|
||||
Fix resetting search (bug SF-318)
|
||||
Don't use LIMIT 1 if updating unique row (bug SF-320)
|
||||
Restrict editing rows without unique identifier to search results
|
||||
Display navigation below main content on mobile browsers
|
||||
Get number of rows on export page asynchronously
|
||||
Respect 'whole result' even if some rows are checked (bug #339 since Adminer 3.7.0)
|
||||
Respect 'whole result' even if some rows are checked (bug SF-339 since Adminer 3.7.0)
|
||||
MySQL: Optimize create table page and Editor navigation
|
||||
MySQL: Display bit type as binary number
|
||||
MySQL: Improve export of binary data types
|
||||
MySQL: Fix handling of POINT data type (bug #282)
|
||||
MySQL: Fix handling of POINT data type (bug SF-282)
|
||||
MySQL: Don't export binary and geometry columns twice in select
|
||||
MySQL: Fix EXPLAIN in MySQL < 5.1, bug since Adminer 3.6.4
|
||||
SQLite: Export views
|
||||
@@ -613,11 +626,11 @@ Recover original view, trigger, routine if creating fails
|
||||
Do not store plain text password to history in creating user
|
||||
Selectable ON UPDATE CURRENT_TIMESTAMP field in create table
|
||||
Open database to a new window after selecting it with Ctrl
|
||||
Clear column name after resetting search (bug #296)
|
||||
Explain partitions in SQL query (bug #294)
|
||||
Allow loading more data with inline edit (bug #299)
|
||||
Stay on the same page after deleting rows (bug #301)
|
||||
Respect checked tables in export filename (bug #133)
|
||||
Clear column name after resetting search (bug SF-296)
|
||||
Explain partitions in SQL query (bug SF-294)
|
||||
Allow loading more data with inline edit (bug SF-299)
|
||||
Stay on the same page after deleting rows (bug SF-301)
|
||||
Respect checked tables in export filename (bug SF-133)
|
||||
Respect PHP configuration max_input_vars
|
||||
Fix unsetting permanent login after logout
|
||||
Disable autocapitalize in identifiers on mobile browsers
|
||||
@@ -702,11 +715,11 @@ Ukrainian translation
|
||||
Bengali translation
|
||||
|
||||
Adminer 3.3.4 (released 2012-03-07):
|
||||
Foreign keys default actions (bug #188)
|
||||
Foreign keys default actions (bug SF-188)
|
||||
SET DEFAULT foreign key action
|
||||
Fix minor parser bug in SQL command with webserver file
|
||||
Ctrl+click on button opens form to a blank window
|
||||
Trim table and column names (bug #195)
|
||||
Trim table and column names (bug SF-195)
|
||||
Error message with no response from server in AJAX
|
||||
Esc to cancel AJAX request
|
||||
Move AJAX loading indicator to the right
|
||||
@@ -718,9 +731,9 @@ Ability to disable export (customization)
|
||||
Extensible list of databases (customization)
|
||||
MySQL: set autocommit after connect
|
||||
SQLite, PostgreSQL: vacuum
|
||||
SQLite, PostgreSQL: don't use LIKE for numbers (bug #202)
|
||||
SQLite, PostgreSQL: don't use LIKE for numbers (bug SF-202)
|
||||
PostgreSQL: fix alter foreign key
|
||||
PostgreSQL over PDO: connect if the eponymous database does not exist (bug #185)
|
||||
PostgreSQL over PDO: connect if the eponymous database does not exist (bug SF-185)
|
||||
Boolean search (Editor)
|
||||
Persian translation
|
||||
|
||||
@@ -748,8 +761,8 @@ Adminer 3.3.0 (released 2011-07-19):
|
||||
Use Esc to disable in-place edit
|
||||
Shortcut for database privileges
|
||||
Editable index names
|
||||
Append new index with auto index selection (bug #138)
|
||||
Preserve original timestamp value in multiple update (bug #158)
|
||||
Append new index with auto index selection (bug SF-138)
|
||||
Preserve original timestamp value in multiple update (bug SF-158)
|
||||
Bit type default value
|
||||
Display foreign key name in tooltip
|
||||
Display default column value in table overview
|
||||
@@ -763,7 +776,7 @@ Display foreign keys from other schemas (PostgreSQL)
|
||||
Pagination support (Oracle)
|
||||
Autocomplete for big foreign keys (Editor)
|
||||
Display name of the referenced record in PostgreSQL (Editor)
|
||||
Prefer NULL to empty string (Editor, bug #162)
|
||||
Prefer NULL to empty string (Editor, bug SF-162)
|
||||
Display searched columns (Editor)
|
||||
Customizable favicon (customization)
|
||||
Method name can return a link (customization)
|
||||
@@ -775,8 +788,8 @@ Fix AJAX history after reload
|
||||
|
||||
Adminer 3.2.1 (released 2011-03-23):
|
||||
Ability to save expression in edit
|
||||
Respect default database collation (bug #119)
|
||||
Don't export triggers without table (bug #123)
|
||||
Respect default database collation (bug SF-119)
|
||||
Don't export triggers without table (bug SF-123)
|
||||
Esc to focus next field in Tab textarea
|
||||
Send forms by Ctrl+Enter on <select>
|
||||
Enum editor and textarea Ctrl+Enter working in IE
|
||||
@@ -799,8 +812,8 @@ Get long texts and slow information by AJAX
|
||||
Most links and forms by AJAX in browsers with support for history.pushState
|
||||
Copy tables
|
||||
Ability to search by expression in select
|
||||
Export SQL command result (bug #99)
|
||||
Focus first field with insert (bug #106)
|
||||
Export SQL command result (bug SF-99)
|
||||
Focus first field with insert (bug SF-106)
|
||||
Permanent link in schema
|
||||
Display total time in show only errors mode in SQL command
|
||||
History: edit all
|
||||
@@ -813,7 +826,7 @@ Utilize oids in PostgreSQL
|
||||
Homepage customization
|
||||
Use IN for search in numeric fields (Editor)
|
||||
Use password input for _md5 and _sha1 fields (Editor)
|
||||
Work without session.use_cookies (bug #107)
|
||||
Work without session.use_cookies (bug SF-107)
|
||||
Fix saving schema to cookie in Opera
|
||||
Portuguese, Slovenian and Turkish translation
|
||||
|
||||
@@ -826,10 +839,10 @@ Recognize $$ strings in SQL command (PostgreSQL)
|
||||
Highlight and edit SQL command in processlist
|
||||
Always display all drivers
|
||||
Timestamp at the end of export
|
||||
Link to refresh database cache (bug #96)
|
||||
Link to refresh database cache (bug SF-96)
|
||||
Support for virtual foreign keys
|
||||
Disable XSS "protection" of IE8
|
||||
Immunity against zend.ze1_compatibility_mode (bug #86)
|
||||
Immunity against zend.ze1_compatibility_mode (bug SF-86)
|
||||
Fix last page with empty result set
|
||||
Arabic translation and RTL support
|
||||
Dual licensing: Apache or GPL
|
||||
@@ -877,7 +890,7 @@ Add Drop button to Alter pages (regression from 2.0.0)
|
||||
Link COUNT(*) result to listing
|
||||
Newlines in select query edit
|
||||
Return to referrer after edit
|
||||
Respect session.auto_start (bug #42)
|
||||
Respect session.auto_start (bug SF-42)
|
||||
|
||||
Adminer 2.3.0 (released 2010-02-26):
|
||||
Support for permanent login (customization required)
|
||||
@@ -906,7 +919,7 @@ Link URLs in select
|
||||
Display number of manipulated rows in JS confirm
|
||||
Set required memory in SQL command
|
||||
Fix removed default in ALTER
|
||||
Display whitespace in texts (bug #11)
|
||||
Display whitespace in texts (bug SF-11)
|
||||
ClickJacking protection in modern browsers
|
||||
E-mail attachments (Editor)
|
||||
Optional year in date (Editor)
|
||||
@@ -925,7 +938,7 @@ Use ON DUPLICATE KEY UPDATE for CSV import
|
||||
Print ALTER export instead of executing it
|
||||
Click on row selects it
|
||||
Fix Editor date format
|
||||
Fix long SQL query crash (bug #3)
|
||||
Fix long SQL query crash (bug SF-3)
|
||||
Speed up simple alter table
|
||||
Traditional Chinese translation
|
||||
|
||||
@@ -981,7 +994,7 @@ Use \n in SQL commands
|
||||
|
||||
phpMinAdmin 1.10.1 (released 2009-05-07):
|
||||
Highlight odd and hover rows
|
||||
Partition editing comfort (bug #12)
|
||||
Partition editing comfort (bug SF-12)
|
||||
Allow full length in limited int
|
||||
|
||||
phpMinAdmin 1.10.0 (released 2009-04-28):
|
||||
@@ -989,7 +1002,7 @@ Partitioning (MySQL 5.1)
|
||||
CSV import
|
||||
Plus and minus functions
|
||||
Option to stop on error in SQL command
|
||||
Cross links to select and table (bug #5), link new item
|
||||
Cross links to select and table (bug SF-5), link new item
|
||||
Suhosin compatibility
|
||||
Remove max_allowed_packet from export
|
||||
Read style from phpMinAdmin.css if exists
|
||||
@@ -1068,7 +1081,7 @@ phpMinAdmin 1.4.0 (released 2007-08-15):
|
||||
Privileges
|
||||
New design
|
||||
Dutch translation
|
||||
Use NULL for auto_increment (bug #1)
|
||||
Use NULL for auto_increment (bug SF-1)
|
||||
Fix dropping procedure parameters
|
||||
|
||||
phpMinAdmin 1.3.2 (released 2007-08-06):
|
||||
|
||||
77
compile.php
77
compile.php
@@ -2,8 +2,12 @@
|
||||
<?php
|
||||
include __DIR__ . "/adminer/include/version.inc.php";
|
||||
include __DIR__ . "/adminer/include/errors.inc.php";
|
||||
include __DIR__ . "/php_shrink.inc.php";
|
||||
include __DIR__ . "/externals/JsShrink/jsShrink.php";
|
||||
include __DIR__ . "/externals/PhpShrink/phpShrink.php";
|
||||
|
||||
function add_apo_slashes($s) {
|
||||
return addcslashes($s, "\\'");
|
||||
}
|
||||
|
||||
function add_quo_slashes($s) {
|
||||
$return = $s;
|
||||
@@ -33,31 +37,16 @@ function lang_ids($match) {
|
||||
}
|
||||
|
||||
function put_file($match) {
|
||||
global $project, $VERSION, $driver;
|
||||
global $project, $vendor;
|
||||
if (basename($match[2]) == '$LANG.inc.php') {
|
||||
return $match[0]; // processed later
|
||||
}
|
||||
$return = file_get_contents(__DIR__ . "/$project/$match[2]");
|
||||
$return = preg_replace('~namespace Adminer;\s*~', '', $return);
|
||||
if (basename($match[2]) == "file.inc.php") {
|
||||
$return = str_replace("\n// caching headers added in compile.php", (preg_match('~-dev$~', $VERSION) ? '' : '
|
||||
if ($_SERVER["HTTP_IF_MODIFIED_SINCE"]) {
|
||||
header("HTTP/1.1 304 Not Modified");
|
||||
exit;
|
||||
}
|
||||
|
||||
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 365*24*60*60) . " GMT");
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
||||
header("Cache-Control: immutable");
|
||||
'), $return, $count);
|
||||
if (!$count) {
|
||||
echo "adminer/file.inc.php: Caching headers placeholder not found\n";
|
||||
}
|
||||
}
|
||||
if ($driver && preg_match('~/drivers/~', $match[2])) {
|
||||
$return = preg_replace('~^if \(isset\(\$_GET\["' . $driver . '"]\)\) \{(.*)^}~ms', '\1', $return);
|
||||
if ($vendor && preg_match('~/drivers/~', $match[2])) {
|
||||
$return = preg_replace('~^if \(isset\(\$_GET\["' . $vendor . '"]\)\) \{(.*)^}~ms', '\1', $return);
|
||||
// check function definition in drivers
|
||||
if ($driver != "mysql") {
|
||||
if ($vendor != "mysql") {
|
||||
preg_match_all(
|
||||
'~\bfunction ([^(]+)~',
|
||||
preg_replace('~class Driver.*\n\t}~sU', '', file_get_contents(__DIR__ . "/adminer/drivers/mysql.inc.php")),
|
||||
@@ -85,10 +74,10 @@ header("Cache-Control: immutable");
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($functions["__construct"], $functions["__destruct"], $functions["set_charset"]);
|
||||
unset($functions["__construct"], $functions["__destruct"], $functions["set_charset"], $functions["fetch_column"]);
|
||||
foreach ($functions as $val) {
|
||||
if (!strpos($return, "$val(")) {
|
||||
fprintf(STDERR, "Missing $val in $driver\n");
|
||||
fprintf(STDERR, "Missing $val in $vendor\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,7 +106,7 @@ header("Cache-Control: immutable");
|
||||
|
||||
function lang(\$translation, \$number = null) {
|
||||
if (is_array(\$translation)) {
|
||||
\$pos = $match2[2]\t\t\t: " . (preg_match("~\\\$LANG == '$_SESSION[lang]'.* \\? (.+)\n~U", $match2[1], $match3) ? $match3[1] : "1") . '
|
||||
\$pos = $match2[2]\t\t\t: " . (preg_match("~'$_SESSION[lang]'.* \\? (.+)\n~U", $match2[1], $match3) ? $match3[1] : "1") . '
|
||||
);
|
||||
$translation = $translation[$pos];
|
||||
}
|
||||
@@ -253,13 +242,13 @@ if ($_SERVER["argv"][1] == "editor") {
|
||||
array_shift($_SERVER["argv"]);
|
||||
}
|
||||
|
||||
$driver = "";
|
||||
$vendor = "";
|
||||
$driver_path = "/adminer/drivers/" . $_SERVER["argv"][1] . ".inc.php";
|
||||
if (!file_exists(__DIR__ . $driver_path)) {
|
||||
$driver_path = "/plugins/drivers/" . $_SERVER["argv"][1] . ".php";
|
||||
}
|
||||
if (file_exists(__DIR__ . $driver_path)) {
|
||||
$driver = $_SERVER["argv"][1];
|
||||
$vendor = $_SERVER["argv"][1];
|
||||
array_shift($_SERVER["argv"]);
|
||||
}
|
||||
|
||||
@@ -279,12 +268,13 @@ if ($_SERVER["argv"][1]) {
|
||||
|
||||
include __DIR__ . "/adminer/include/pdo.inc.php";
|
||||
include __DIR__ . "/adminer/include/driver.inc.php";
|
||||
$connection = new stdClass; // used in support()
|
||||
$features = array("check", "call" => "routine", "dump", "event", "privileges", "procedure" => "routine", "processlist", "routine", "scheme", "sequence", "status", "trigger", "type", "user" => "privileges", "variables", "view");
|
||||
$lang_ids = array(); // global variable simplifies usage in a callback function
|
||||
$file = file_get_contents(__DIR__ . "/$project/index.php");
|
||||
$file = preg_replace('~\*/~', "* @version $VERSION\n*/", $file, 1);
|
||||
if ($driver) {
|
||||
$_GET[$driver] = true; // to load the driver
|
||||
if ($vendor) {
|
||||
$_GET[$vendor] = true; // to load the driver
|
||||
include_once __DIR__ . $driver_path;
|
||||
foreach ($features as $key => $feature) {
|
||||
if (!Adminer\support($feature)) {
|
||||
@@ -300,36 +290,39 @@ if ($driver) {
|
||||
}
|
||||
$file = preg_replace_callback('~\b(include|require) "([^"]*)";~', 'put_file', $file);
|
||||
$file = str_replace('include "../adminer/include/coverage.inc.php";', '', $file);
|
||||
if ($driver) {
|
||||
if ($vendor) {
|
||||
if (preg_match('~^/plugins/~', $driver_path)) {
|
||||
$file = preg_replace('((include "..)/adminer/drivers/mysql.inc.php)', "\\1$driver_path", $file);
|
||||
}
|
||||
$file = preg_replace('(include "../adminer/drivers/(?!' . preg_quote($driver) . '\.).*\s*)', '', $file);
|
||||
$file = preg_replace('(include "../adminer/drivers/(?!' . preg_quote($vendor) . '\.).*\s*)', '', $file);
|
||||
}
|
||||
$file = preg_replace_callback('~\b(include|require) "([^"]*)";~', 'put_file', $file); // bootstrap.inc.php
|
||||
if ($driver) {
|
||||
if ($vendor) {
|
||||
foreach ($features as $feature) {
|
||||
if (!Adminer\support($feature)) {
|
||||
$file = preg_replace("((\t*)" . preg_quote('if (support("' . $feature . '")') . ".*?\n\\1\\}( else)?)s", '', $file);
|
||||
}
|
||||
}
|
||||
if (count($drivers) == 1) {
|
||||
$file = str_replace('html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);")', "\"<input type='hidden' name='auth[driver]' value='" . ($driver == "mysql" ? "server" : $driver) . "'>" . reset($drivers) . "\"", $file, $count);
|
||||
if (!$count && $project != "editor") {
|
||||
if ($project != "editor" && count($drivers) == 1) {
|
||||
$file = str_replace('html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);")', "\"<input type='hidden' name='auth[driver]' value='" . ($vendor == "mysql" ? "server" : $vendor) . "'>" . reset($drivers) . "\"", $file, $count);
|
||||
if (!$count) {
|
||||
echo "auth[driver] form field not found\n";
|
||||
}
|
||||
$file = str_replace(" . script(\"qs('#username').form['auth[driver]'].onchange();\")", "", $file);
|
||||
if ($vendor == "sqlite") {
|
||||
$file = str_replace(");\n\t\techo \$this->loginFormField('server', '<tr><th>' . lang('Server') . '<td>', '<input name=\"auth[server]", ' . \'<input type="hidden" name="auth[server]"', $file);
|
||||
}
|
||||
}
|
||||
$file = preg_replace('(;\s*../externals/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('(;\s*../externals/jush/modules/jush-(?!textarea\.|txt\.|js\.|' . preg_quote($vendor == "mysql" ? "sql" : $vendor) . '\.)[^.]+.js)', '', $file);
|
||||
$file = preg_replace_callback('~doc_link\(array\((.*)\)\)~sU', function ($match) use ($vendor) {
|
||||
list(, $links) = $match;
|
||||
$links = preg_replace("~'(?!(" . ($driver == "mysql" ? "sql|mariadb" : $driver) . ")')[^']*' => [^,]*,?~", '', $links);
|
||||
$links = preg_replace("~'(?!(" . ($vendor == "mysql" ? "sql|mariadb" : $vendor) . ")')[^']*' => [^,]*,?~", '', $links);
|
||||
return (trim($links) ? "doc_link(array($links))" : "''");
|
||||
}, $file);
|
||||
//! strip doc_link() definition
|
||||
}
|
||||
if ($project == "editor") {
|
||||
$file = preg_replace('~;.\.\/externals/jush/jush\.css~', '', $file);
|
||||
$file = preg_replace('~;.\.\/externals/jush/jush(-dark)?\.css~', '', $file);
|
||||
$file = preg_replace('~compile_file\(\'\.\./(externals/jush/modules/jush\.js|adminer/static/[^.]+\.gif)[^)]+\)~', "''", $file);
|
||||
}
|
||||
$file = preg_replace_callback("~lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])~s", 'lang_ids', $file);
|
||||
@@ -343,15 +336,17 @@ if ($_SESSION["lang"]) {
|
||||
}
|
||||
$file = str_replace('echo script_src("static/editing.js");' . "\n", "", $file); // merged into functions.js
|
||||
$file = preg_replace('~\s+echo script_src\("\.\./externals/jush/modules/jush-(textarea|txt|js|" \. JUSH \. ")\.js"\);~', '', $file); // merged into jush.js
|
||||
$file = str_replace('<link rel="stylesheet" href="../externals/jush/jush.css">' . "\n", "", $file); // merged into default.css
|
||||
$file = preg_replace('~echo .*/jush(-dark)?.css\'>.*~', '', $file); // merged into default.css or dark.css
|
||||
$file = preg_replace_callback("~compile_file\\('([^']+)'(?:, '([^']*)')?\\)~", 'compile_file', $file); // integrate static files
|
||||
$replace = 'preg_replace("~\\\\\\\\?.*~", "", ME) . "?file=\1&version=' . $VERSION . '"';
|
||||
$file = preg_replace('~\.\./adminer/static/(default\.css|favicon\.ico)~', '<?php echo h(' . $replace . '); ?>', $file);
|
||||
$file = preg_replace('~\.\./adminer/static/(default\.css)~', '<?php echo h(' . $replace . '); ?>', $file);
|
||||
$file = preg_replace('~"\.\./adminer/static/(functions\.js)"~', $replace, $file);
|
||||
$file = preg_replace('~\.\./adminer/static/([^\'"]*)~', '" . h(' . $replace . ') . "', $file);
|
||||
$file = preg_replace('~"\.\./externals/jush/modules/(jush\.js)"~', $replace, $file);
|
||||
$file = php_shrink($file);
|
||||
if (function_exists('phpShrink')) {
|
||||
$file = phpShrink($file);
|
||||
}
|
||||
|
||||
$filename = $project . (preg_match('~-dev$~', $VERSION) ? "" : "-$VERSION") . ($driver ? "-$driver" : "") . ($_SESSION["lang"] ? "-$_SESSION[lang]" : "") . ".php";
|
||||
$filename = $project . (preg_match('~-dev$~', $VERSION) ? "" : "-$VERSION") . ($vendor ? "-$vendor" : "") . ($_SESSION["lang"] ? "-$_SESSION[lang]" : "") . ".php";
|
||||
file_put_contents($filename, $file);
|
||||
echo "$filename created (" . strlen($file) . " B).\n";
|
||||
|
||||
@@ -23,7 +23,7 @@ function xhtml_open_tags($s) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
$coverage_filename = sys_get_temp_dir() . "/adminer_coverage.ser";
|
||||
$coverage_filename = sys_get_temp_dir() . "/adminer.coverage";
|
||||
if (!extension_loaded("xdebug")) {
|
||||
echo "<p class='error'>Xdebug has to be enabled.\n";
|
||||
} elseif ($_GET["coverage"] === "0") {
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
/*
|
||||
* Dark Theme for Adminer by 'Muhammad Bilal Yameen' [github.com/bilal-yameen/dark-theme-for-adminer]
|
||||
*/
|
||||
html,body,header,footer,aside,menu,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;outline:0;border:none;background:transparent;font-size:10pt;font-weight:normal}
|
||||
ol,ul{list-style:none}
|
||||
blockquote,q{quotes:none}
|
||||
blockquote:before,blockquote:after,q:before,q:after{content:none}
|
||||
:focus{outline:0}
|
||||
ins{text-decoration:none}
|
||||
del{text-decoration:line-through}
|
||||
table{border-collapse:collapse;border-spacing:0}
|
||||
aside,menu{display:block}
|
||||
input[type='submit'],input[type='checkbox'],input[type='radio'],input[type='file'],select,label{cursor:pointer}
|
||||
input[disabled=""]{opacity:.5;cursor:not-allowed;color:#666 !important;border-color:#aaa !important}
|
||||
input[type='text']{-webkit-user-modify:read-write-plaintext-only}
|
||||
@font-face{font-family:'entypo';src:url('../fonts/entypo.eot');src:url('../fonts/entypo.eot?#iefix') format('embedded-opentype'),url('../fonts/entypo.woff') format('woff'),url('../fonts/entypo.ttf') format('truetype'),url('../fonts/entypo.svg#entypo') format('svg');font-weight:normal;font-style:normal}
|
||||
html{overflow-y:scroll;-webkit-text-size-adjust:none}
|
||||
body{font-family:"Helvetica Neue",Helvetica,Verdana,Arial,sans-serif;background:#22252a;color:#a5a8ad;width:100%}
|
||||
a,a:visited{padding:4px 0;color:#0c83d9;transition:color .1s ease 0s,background-color .1s ease 0s}
|
||||
a:link:hover,a:visited:hover{color:#0063a9;text-decoration:none}
|
||||
a sup{padding:0 5px}
|
||||
#logins a,#tables a,#tables span{background:none}
|
||||
.active:before{font-weight:normal}
|
||||
label{padding:3px 10px}
|
||||
input::-webkit-input-placeholder{color:#999}
|
||||
input::-moz-placeholder{color:#999}
|
||||
input:-ms-input-placeholder{color:#999}
|
||||
input:not([type]),input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],textarea,pre[contenteditable="true"],select{padding:4px 5px !important;border:1px solid #ccc !important;border-radius:2px;font-size:10pt;background:#202225;color:#a5a8ad;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
|
||||
input:not([type]),input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],textarea{-webkit-appearance:none}
|
||||
input:not([type]),input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],select{height:28px}
|
||||
input[type="submit"]{display:inline-block;padding:7px 15px;border:1px solid #0c83d9;border-radius:2px;background:#0c83d9;color:#fff;text-align:center;text-decoration:none;font-size:10pt;transition:background-color .1s ease 0s;-webkit-appearance:none}
|
||||
input[type="submit"]:hover{background:#0063a9;border-color:#0063a9}
|
||||
input[type="submit"][disabled=""]:hover{background:#22252a}
|
||||
input[type="submit"].default{box-shadow:none}
|
||||
input[type="image"]{border:4px solid #22252a;outline:1px solid #0a83d9;-moz-outline-radius:2px;margin-right:5px}
|
||||
input[type="image"]:last-child{margin-right:0}
|
||||
input[type="image"]:hover{border-color:#282b2f}
|
||||
input[type="checkbox"],input[type="radio"]{margin:7px 5px 7px 0}
|
||||
fieldset{margin:5px 5px 10px 0;padding:5px 10px;border:1px solid rgba(255,255,255,0.1);border-radius:2px;background:#282b2f;min-height:55px}
|
||||
fieldset input[type="submit"]{padding:3px 10px;border-color:#0c83d9;background:#22252a;color:#0c83d9}
|
||||
fieldset input[type="submit"]:hover{background:#0c82d4;color:#fff}
|
||||
fieldset input[type="submit"].default{border-color:#0c83d9;background:#0c83d9;color:#22252a}
|
||||
fieldset input[type="submit"].default:hover{background:#0063a9;border-color:#0063a9}
|
||||
fieldset a{padding:6px 8px}
|
||||
fieldset+table,table+fieldset{margin-top:10px}
|
||||
fieldset legend a{position:relative;padding:4px 0 50px}
|
||||
fieldset>div>div,fieldset>div>p,fieldset>div>a,fieldset>div>code,fieldset>div>input,fieldset>div>select,fieldset>a{position:relative}
|
||||
legend{margin-bottom:3px}
|
||||
legend:before,legend:after{content:" "}
|
||||
p input,p select,p label,fieldset input,fieldset select{margin:0 5px 5px 0}
|
||||
.js fieldset>.hidden{display:block;margin-top:5px;text-align:center}
|
||||
.js fieldset>.hidden *{display:none !important}
|
||||
.js fieldset>.hidden:before{content:"⏶";font-family:"entypo",sans-serif;font-size:40pt;line-height:0;vertical-align:middle;color:#e2e2e2}
|
||||
#fieldset-select.hidden:before{content:"⚏"}
|
||||
#fieldset-search.hidden:before{content:"🔍"}
|
||||
#fieldset-sort.hidden:before{content:"⏷"}
|
||||
#fieldset-export.hidden:before{content:"📤"}
|
||||
#fieldset-import.hidden:before{content:"📥"}
|
||||
#fieldset-history.hidden:before{content:""}
|
||||
#fieldset-history br{display:block;margin-bottom:20px}
|
||||
#fieldset-history.hidden br{display:none}
|
||||
#fieldset-partition.hidden:before{content:""}
|
||||
.size{width:8ex}
|
||||
.sqlarea{width:100% !important;height:350px}
|
||||
@media only screen and (max-width:768px){
|
||||
input:not([type]),input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],textarea,pre[contenteditable="true"],select{font-size:12pt;vertical-align:-1px}
|
||||
input:not([type]),input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],select{height:32px}
|
||||
fieldset input[type="submit"]{padding:6px 15px}
|
||||
.sqlarea{height:250px}
|
||||
}
|
||||
@media only screen and (max-width:360px){
|
||||
input:not([type]),input[type="text"],input[type="email"],input[type="password"],input[type="search"],input[type="number"],textarea,pre[contenteditable="true"],select{width:100%}
|
||||
input[type="submit"],fieldset input[type="submit"]{padding-left:10px;padding-right:10px}
|
||||
}
|
||||
#lang{position:fixed;right:0;top:0;left:auto;border:none;padding:0 0 0 10px;width:190px;height:40px;line-height:30px;font-size:0;z-index:101;background:#282b2f}
|
||||
#lang select{padding:2px 3px;margin:6px 0;width:100px}
|
||||
.logout{position:fixed;right:10px;margin:0;z-index:101;overflow:hidden}
|
||||
.logout input[type="submit"]{border:none;margin:0;padding:0 10px;height:40px;background:transparent;color:#0c83d9}
|
||||
.logout input[type="submit"]:hover{background:transparent;color:#0063a9}
|
||||
@media only screen and (max-width:768px){
|
||||
#lang{position:static;left:0;top:0;width:auto;border-top:1px solid rgba(255,255,255,0.1);background:#282b2f}
|
||||
#lang select{margin:4px 10px 0 10px}
|
||||
.logout{position:relative;float:right;margin-top:-40px}
|
||||
}
|
||||
@media only screen and (max-width:360px){
|
||||
#lang select{margin-left:0}
|
||||
}
|
||||
#content{position:relative;margin:0 0 0 261px;padding:41px 20px 80px 20px}
|
||||
#content:before{position:fixed;left:0;top:0;content:"";display:block;width:100%;height:40px;background:#282b2f;border-bottom:1px solid rgba(255,255,255,0.1)}
|
||||
#content .links+p{color:#999}
|
||||
#breadcrumb{position:fixed;left:261px;top:0;right:0;margin:0;padding:0 0 0 20px;border-right:205px solid #282b2f;background:#282b2f;height:40px;line-height:40px;z-index:100;overflow:hidden;text-overflow:ellipsis}
|
||||
#breadcrumb a{display:inline-block;padding:0;height:40px;line-height:40px}
|
||||
h2{margin:20px 0;font-size:20pt;color:#a5a8ad}
|
||||
h3{margin:30px 0 10px 0;font-size:16pt}
|
||||
p{margin:10px 0}
|
||||
code{display:block;padding:10px;margin:5px 0;border-left:7px solid #58595a;border-radius:2px;background:#2d3135;overflow:auto}
|
||||
td code,th code,fieldset code:first-child{display:inline;margin:0;padding:0;background:none;border:none}
|
||||
pre code{margin:0}
|
||||
fieldset code+i{display:none}
|
||||
.time{margin-left:10px;float:right;font-size:8pt;color:#bbb}
|
||||
.error,.message{margin:20px 0;padding:10px;border-left:7px solid #cec}
|
||||
.error{color:#900;border-color:#ecc}
|
||||
.message pre{margin:15px 0 5px 0}
|
||||
.message p{margin:0 0 5px 0}
|
||||
pre+.message,pre+.error{margin-top:0}
|
||||
#help{z-index:200;border:1px solid rgba(255,255,255,0.1);border-radius:2px;background:#282b2f;padding:5px 7px}
|
||||
.icon{background-color:#0c83d9}
|
||||
.icon:hover{background-color:#0063a9}
|
||||
@media only screen and (max-width:768px){
|
||||
#content{margin-left:0}
|
||||
#breadcrumb{left:0;padding-left:50px;border-right-width:0}
|
||||
}
|
||||
@media only screen and (max-width:360px){
|
||||
#content{padding:41px 10px 20px}
|
||||
h2{margin:15px 0;font-size:16pt}
|
||||
}
|
||||
h1{height:40px;white-space:nowrap;overflow:hidden}
|
||||
h1 #h1{display:inline-block;padding:0;background:url("../images/logo.png?3") 10px center no-repeat;background-size:120px;text-indent:-100px;width:135px;height:40px}
|
||||
.version,#version{position:relative;top:-7px;vertical-align:bottom;font-size:8pt;font-style:italic;color:#bbb}
|
||||
#version{padding:5px;color:#0c83d9}
|
||||
#version:hover{color:#0063a9}
|
||||
#menu{position:fixed;left:0;top:0;bottom:0;width:260px;margin:0;padding:0;border-right:1px solid rgba(255,255,255,0.1);overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;background:#22252a;z-index:100}
|
||||
#menu p{padding:10px;border-bottom:none}
|
||||
#menu .links{background:#282b2f;border-bottom:1px solid rgba(255,255,255,0.1);padding:0 10px 7px 10px}
|
||||
#menu .message{background:transparent;border:none;border-bottom:1px solid rgba(255,255,255,0.1);color:#bbb}
|
||||
#filter-field{margin:0;width:100%}
|
||||
.menu-list{border-bottom:1px solid rgba(255,255,255,0.1) !important;padding:0 !important;margin-bottom:25px !important }
|
||||
.menu-link{display:block;padding:2px 10px;width:auto;height:20px;line-height:20px;color:#a5a8ad;overflow:hidden;text-overflow:ellipsis}
|
||||
.menu-link.active{background:#282b2f;color:#0c83d9}
|
||||
.menu-link.active:hover{background:#1b1f25}
|
||||
p#dbs{border-top:1px solid rgba(255,255,255,0.1);background:#282b2f;color:#282b2f;font-size:0}
|
||||
p#dbs span{font-size:0}
|
||||
p#dbs select{margin:0;width:100%}
|
||||
#tables{border-bottom:1px solid rgba(255,255,255,0.1) !important;padding:0 !important;margin-bottom:25px !important }
|
||||
#tables li{position:relative}
|
||||
#tables li:hover{background:#282b2f}
|
||||
#tables a strong{font-weight:bold}
|
||||
#tables a.structure{display:block;padding:2px 10px;width:auto;height:20px;line-height:20px;color:#a5a8ad;overflow:hidden;text-overflow:ellipsis;padding-right:0}
|
||||
#tables a.structure.active{background:#282b2f;color:#0c83d9}
|
||||
#tables a.structure.active:hover{background:#1b1f25}
|
||||
#tables a.select{position:absolute;right:0;top:0;display:block;padding:2px 7px;height:20px;line-height:20px;color:#999;overflow:hidden;width:16px}
|
||||
#tables a.select:before{content:"📄 ";font-family:entypo,sans-serif;font-size:24pt;line-height:0;vertical-align:-3px}
|
||||
#tables li:first-of-type a{padding-top:7px}
|
||||
#tables li:last-child a{padding-bottom:7px}
|
||||
#tables a.active+a{background:#282b2f;color:#0c83d9;font-weight:bold}
|
||||
#tables a.active+a:hover{background:#1b1f25}
|
||||
#tables a.active:hover+a{background:#1b1f25}
|
||||
#tables a:hover+a.active{background:#1b1f25}
|
||||
#tables br{display:none}
|
||||
#tables.simple a{display:block;padding:2px 10px;width:auto;height:20px;line-height:20px;color:#a5a8ad;overflow:hidden;text-overflow:ellipsis}
|
||||
#tables.simple a.active{background:#282b2f;color:#0c83d9}
|
||||
#tables.simple a.active:hover{background:#1b1f25}
|
||||
#logins{border-bottom:1px solid rgba(255,255,255,0.1) !important;padding:0 !important;margin-bottom:25px !important ;border-top:1px solid rgba(255,255,255,0.1)}
|
||||
#logins a{display:block;padding:2px 10px;width:auto;height:20px;line-height:20px;color:#a5a8ad;overflow:hidden;text-overflow:ellipsis}
|
||||
#logins a.active{background:#282b2f;color:#0c83d9}
|
||||
#logins a.active:hover{background:#1b1f25}
|
||||
#logins a:hover{background:#282b2f}
|
||||
#logins a:first-of-type{padding-top:7px}
|
||||
#logins a:last-of-type{padding-bottom:7px}
|
||||
#logins br{display:none}
|
||||
@media only screen and (max-width:768px){
|
||||
h1:before{float:left;position:relative;left:4px;top:4px;width:30px;height:30px;content:"☰";font-family:"entypo",sans-serif;font-size:32pt;line-height:30px;border:1px solid #0c83d9;border-radius:2px;text-align:center;vertical-align:middle;background:#22252a;cursor:pointer}
|
||||
h1 #h1{margin-left:10px}
|
||||
#menu{width:40px;height:40px;bottom:auto;border:none;overflow:hidden;background:transparent}
|
||||
#menu form,#menu p{display:none}
|
||||
#menu.open{width:260px;height:auto;max-width:100%;max-height:100%;border-right:1px solid rgba(255,255,255,0.1);border-bottom:5px solid rgba(255,255,255,0.1);background:#22252a;box-shadow:2px 2px 10px rgba(0,0,0,0.03);z-index:200;overflow-y:auto}
|
||||
#menu.open form,#menu.open p{display:block}
|
||||
}
|
||||
@media only screen and (max-width:270px){
|
||||
#menu.open{border-right:none}
|
||||
}
|
||||
@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (-o-min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5){
|
||||
h1 #h1{background-image:url("../images/logo-hres.png?3");background-size:120px}
|
||||
}
|
||||
a[href*="&sql="]:before{content:"✎";padding:0 5px;font-family:entypo,sans-serif;font-size:24pt;line-height:10pt;vertical-align:-3px}
|
||||
.links{line-height:22px}
|
||||
.links a:before{content:"⏴ ";font-family:entypo,sans-serif;font-size:24pt;line-height:10pt;vertical-align:-3px}
|
||||
.links a[href*="&sql="]:before{content:"";margin-left:-4px;margin-right:3px}
|
||||
.links a[href*="&import="]:before{content:"📥 "}
|
||||
.links a[href*="&dump="]:before{content:"📤 "}
|
||||
.links a[href*="&create="]:before,.links a[href*="&db="][href*="&database="]:before,.links a[href*="&indexes="]:before{content:"✎ "}
|
||||
.links a[href$="&create="]:before,.links a[href$="&database="]:before,.links a[href$="&indexes="]:before{content:"➕ "}
|
||||
.links a[href*="&schema="]:before{content:"🕪 "}
|
||||
.links a[href*="&privileges="]:before{content:"👥 "}
|
||||
.links a[href*="&view="]:before{content:" "}
|
||||
.links a[href*="&procedure="]:before,.links a[href*="&function="]:before{content:" "}
|
||||
.links a[href*="&event="]:before{content:"🔁 "}
|
||||
.links a[href*="&edit="]:before{content:"⊕ "}
|
||||
.links a[href*="&table="]:before{content:"⚙ "}
|
||||
.links a[href*="&select="]:before{content:"📄 "}
|
||||
.links a[href*="&processlist="]:before{content:" "}
|
||||
.links a[href*="&status="]:before{content:"📿 "}
|
||||
.links a[href*="&variables="]:before{content:" "}
|
||||
.links a[href*="&user="]:before{content:" "}
|
||||
.links a[href*="&foreign="]:before,.links a[href*="&trigger="]:before{content:"➕ "}
|
||||
table{border:1px solid rgba(255,255,255,0.1);margin:20px 0 10px 0}
|
||||
table label.block{padding:0}
|
||||
tr{border-bottom:1px dotted rgba(255,255,255,0.1)}
|
||||
th,td{padding:4px 10px}
|
||||
th[style="text-align: right;"] input[type="checkbox"],td[align="right"] input[type="checkbox"],th[style="text-align: right;"] input[type="radio"],td[align="right"] input[type="radio"]{margin-right:0;margin-left:5px}
|
||||
thead td,thead th,.odds tbody tr:nth-child(2n),tbody tr:hover td,tbody tr:hover th,.js .checkable .checked td,.js .checkable .checked th{background:transparent}
|
||||
thead tr{background:#282b2f;border-bottom:1px solid rgba(255,255,255,0.1)}
|
||||
thead td,thead th{padding:7px 10px;background:transparent;text-align:left}
|
||||
tbody th,tbody td{vertical-align:top}
|
||||
tbody td[align="right"]{text-align:right}
|
||||
tbody td[align="right"] label.block{text-align:right}
|
||||
tbody th span{padding-top:4px}
|
||||
table.checkable .checked{background:#282b2f}
|
||||
table.checkable input[type="checkbox"],table.checkable input[type="radio"]{margin:2px 5px 2px 0}
|
||||
table.checkable>thead a{padding:7px 0}
|
||||
table.checkable>thead input[type="checkbox"],table.checkable>thead input[type="radio"]{margin:2px 5px 2px 0}
|
||||
table.checkable>tbody>tr:hover{background:#282b2f}
|
||||
table.checkable>tbody>tr.checked:hover{background:#1b1f25}
|
||||
.scrollable{display:table-cell;padding-right:20px}
|
||||
.loadmore{margin:0;padding:10px 0}
|
||||
.footer{position:relative;padding:0}
|
||||
.footer>div{padding:0}
|
||||
.footer>p{position:fixed;left:261px;right:0;bottom:0;margin:0;padding:0 10px;border:none;border-top:1px solid rgba(255,255,255,0.1);background:#282b2f;z-index:102;font-weight:bold}
|
||||
.footer>p a,.footer>p label{display:inline-block;margin:0;padding:0 10px;height:40px;line-height:40px}
|
||||
.footer+div{line-height:36px}
|
||||
.footer+div a{padding:10px 0}
|
||||
.js .column{background:#22252a;padding:0;margin:-36px 0 0 -62px;border:1px solid #3e4144;border-radius:2px;z-index:10}
|
||||
.js .column a{display:inline-block;padding:0;width:30px;height:30px;overflow:hidden;vertical-align:middle}
|
||||
.js .column a:before{display:inline-block;width:30px;height:30px;line-height:30px;font-family:entypo,sans-serif;font-size:24pt;text-align:center;vertical-align:-3px}
|
||||
.js .column a:hover:before{background:#282b2f}
|
||||
.js .column a[href*='&select=']:before{content:"⬇"}
|
||||
.js .column a[href='#fieldset-search']:before{content:"🔍"}
|
||||
@media only screen and (max-width:768px){
|
||||
.footer>p{position:static;margin:-10px 0 10px 0;border-top:none;border-left:1px solid rgba(255,255,255,0.1);border-right:1px solid rgba(255,255,255,0.1);border-bottom:1px solid rgba(255,255,255,0.1)}
|
||||
.scrollable{display:block;margin:0 -20px;padding:0 20px;overflow-x:scroll}
|
||||
}
|
||||
a.jush-custom:hover,a.jush-help:hover{color:inherit;text-decoration:underline}
|
||||
.json{border-color:#58595a;border-left:7px solid #58595a;background:#282b2f;margin:5px 0 3px 0}
|
||||
.json tr{border-bottom:1px solid #58595a}
|
||||
.json tr:last-child{border-bottom:none}
|
||||
.json th{border-right:1px solid #58595a;vertical-align:top}
|
||||
.json code{padding:4px 10px}
|
||||
.json+textarea{margin-top:6px}
|
||||
a.json-icon{background:transparent;text-indent:0}
|
||||
a.json-icon:hover{background:transparent}
|
||||
a.json-icon:before{display:inline-block;width:20px;height:18px;line-height:18px;font-family:entypo,sans-serif;font-size:24pt;vertical-align:-3px;content:"▸"}
|
||||
a.json-icon.json-up{background:transparent;text-indent:0}
|
||||
a.json-icon.json-up:before{content:"▾"}
|
||||
a.json-link{padding-left:0}
|
||||
a.json-link:before{width:10px}
|
||||
a.json-link span{color:inherit}
|
||||
.footer{border-image: linear-gradient(rgb(34 37 42 / 22%),#22252a) 100% 0;}
|
||||
.footer > div{background: #22252a;}
|
||||
.jush a {color: #1383d9;}
|
||||
a.jush-custom:hover, a.jush-help:hover{color:#fff;}
|
||||
.jush {color: #a5a8ad;}
|
||||
.error {background: #ff00001a;color: #d8bfbf;}
|
||||
.message {color: #cceecc;background: #0075001c;}
|
||||
::-webkit-scrollbar {width: 10px;height: 10px;}
|
||||
::-webkit-scrollbar-track {background: #3e3e3e;}
|
||||
::-webkit-scrollbar-thumb {background: #888;}
|
||||
::-webkit-scrollbar-thumb:hover {background: #555;}
|
||||
input[type=checkbox] {display:inline-block;padding-left:25px;height:20px;outline:0;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgd2lkdGg9IjIwcHQiCiAgIGhlaWdodD0iNDBwdCIKICAgdmlld0JveD0iMCAwIDIwIDQwIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmcyIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjQ4LjUgcjEwMDQwIgogICBzb2RpcG9kaTpkb2NuYW1lPSJjaGVjay5zdmciPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTE5Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZGVmcwogICAgIGlkPSJkZWZzMTciIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxIgogICAgIG9iamVjdHRvbGVyYW5jZT0iMTAiCiAgICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgICAgZ3VpZGV0b2xlcmFuY2U9IjEwIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxOTIwIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwMTciCiAgICAgaWQ9Im5hbWVkdmlldzE1IgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpbmtzY2FwZTp6b29tPSIxNiIKICAgICBpbmtzY2FwZTpjeD0iNDMuNzAyNjQ2IgogICAgIGlua3NjYXBlOmN5PSIzMS45NTE3ODMiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjE5MTIiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9Ii04IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnMiIgLz4KICA8ZwogICAgIHN0eWxlPSJmaWxsOiMwMDAwMDAiCiAgICAgaWQ9ImczMDY4IgogICAgIHRyYW5zZm9ybT0ic2NhbGUoMC44LDAuOCkiPgogICAgPHBhdGgKICAgICAgIGlkPSJwYXRoMzA1OCIKICAgICAgIGQ9Ik0gMTksNSBWIDE5IEggNSBWIDUgSCAxOSBNIDE5LDMgSCA1IEMgMy45LDMgMywzLjkgMyw1IHYgMTQgYyAwLDEuMSAwLjksMiAyLDIgaCAxNCBjIDEuMSwwIDIsLTAuOSAyLC0yIFYgNSBDIDIxLDMuOSAyMC4xLDMgMTksMyB6IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBpZD0icGF0aDMwNjAiCiAgICAgICBkPSJNIDAsMCBIIDI0IFYgMjQgSCAwIHoiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgc3R5bGU9ImZpbGw6bm9uZSIgLz4KICA8L2c+CiAgPGcKICAgICBzdHlsZT0iZmlsbDojMDAwMDAwIgogICAgIGlkPSJnMzA4NCIKICAgICB0cmFuc2Zvcm09Im1hdHJpeCgwLjgsMCwwLDAuOCwwLDIwKSI+CiAgICA8cGF0aAogICAgICAgaWQ9InBhdGgzMDc0IgogICAgICAgZD0iTSAwLDAgSCAyNCBWIDI0IEggMCB6IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgIHN0eWxlPSJmaWxsOm5vbmUiIC8+CiAgICA8cGF0aAogICAgICAgaWQ9InBhdGgzMDc2IgogICAgICAgZD0iTSAxOSwzIEggNSBDIDMuODksMyAzLDMuOSAzLDUgdiAxNCBjIDAsMS4xIDAuODksMiAyLDIgaCAxNCBjIDEuMTEsMCAyLC0wLjkgMiwtMiBWIDUgQyAyMSwzLjkgMjAuMTEsMyAxOSwzIHogTSAxMCwxNyA1LDEyIDYuNDEsMTAuNTkgMTAsMTQuMTcgMTcuNTksNi41OCAxOSw4IDEwLDE3IHoiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogIDwvZz4KPC9zdmc+Cg==);background-position:00;background-size:20px;background-repeat:no-repeat;vertical-align:middle;font-size:20px;line-height:20px;cursor:pointer;-webkit-appearance:none;-webkit-user-select:none;user-select:none;filter:invert();}
|
||||
input[type=checkbox]:checked {background-position:0-20px;}
|
||||
@@ -1 +1,3 @@
|
||||
Copy adminer.css alongside Adminer PHP script to use an alternative design.
|
||||
|
||||
If the design supports dark mode then it should be named adminer-dark.css.
|
||||
|
||||
@@ -59,15 +59,17 @@ class Adminer {
|
||||
return csp();
|
||||
}
|
||||
|
||||
function head() {
|
||||
function head($dark = null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function css() {
|
||||
$return = array();
|
||||
$filename = "adminer.css";
|
||||
if (file_exists($filename)) {
|
||||
$return[] = $filename;
|
||||
foreach (array("", "-dark") as $mode) {
|
||||
$filename = "adminer$mode.css";
|
||||
if (file_exists($filename)) {
|
||||
$return[] = "$filename?v=" . crc32(file_get_contents($filename));
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
@@ -211,9 +213,8 @@ ORDER BY ORDINAL_POSITION", null, "") as $row //! requires MySQL 5
|
||||
if ($link) {
|
||||
$return = "<a href='$link'" . (is_url($link) ? target_blank() : "") . ">$return</a>";
|
||||
}
|
||||
if (!$link && !like_bool($field) && preg_match(number_type(), $field["type"])) {
|
||||
$return = "<div class='number'>$return</div>"; // Firefox doesn't support <colgroup>
|
||||
} elseif (preg_match('~date~', $field["type"])) {
|
||||
// Firefox doesn't support <colgroup>
|
||||
if (preg_match('~date~', $field["type"])) {
|
||||
$return = "<div class='datetime'>$return</div>";
|
||||
}
|
||||
return $return;
|
||||
@@ -626,6 +627,9 @@ qsl('div').onclick = whisperClick;", "")
|
||||
}
|
||||
}
|
||||
|
||||
function syntaxHighlighting($tables) {
|
||||
}
|
||||
|
||||
function databasesPrint($missing) {
|
||||
}
|
||||
|
||||
|
||||
2
externals/JsShrink
vendored
2
externals/JsShrink
vendored
Submodule externals/JsShrink updated: 17cbfacae6...18dcc3849a
1
externals/PhpShrink
vendored
Submodule
1
externals/PhpShrink
vendored
Submodule
Submodule externals/PhpShrink added at b6fc11da47
2
externals/jush
vendored
2
externals/jush
vendored
Submodule externals/jush updated: e095c0d590...a80237e93e
@@ -1,144 +0,0 @@
|
||||
<?php
|
||||
|
||||
/** Minify PHP code with these operations:
|
||||
* remove extra {}
|
||||
* minify variables
|
||||
* strip comments, preserve only the first doc-comment
|
||||
* join consecutive echo
|
||||
* change ?>HTML<?php to echo 'HTML' if it saves space
|
||||
* strip public visibility or change it to var
|
||||
*
|
||||
* @param string PHP code including <?php
|
||||
* @return string
|
||||
*/
|
||||
function php_shrink($input) {
|
||||
// based on http://latrine.dgx.cz/jak-zredukovat-php-skripty
|
||||
$input = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $input);
|
||||
$special_variables = array_flip(array('$this', '$GLOBALS', '$_GET', '$_POST', '$_FILES', '$_COOKIE', '$_SESSION', '$_SERVER', '$http_response_header', '$php_errormsg'));
|
||||
$short_variables = array();
|
||||
$shortening = true;
|
||||
$tokens = token_get_all($input);
|
||||
|
||||
// remove unnecessary { }
|
||||
//! change also `while () { if () {;} }` to `while () if () ;` but be careful about `if () { if () { } } else { }
|
||||
$shorten = 0;
|
||||
$opening = -1;
|
||||
foreach ($tokens as $i => $token) {
|
||||
if (in_array($token[0], array(T_IF, T_ELSE, T_ELSEIF, T_WHILE, T_DO, T_FOR, T_FOREACH), true)) {
|
||||
$shorten = ($token[0] == T_FOR ? 4 : 2);
|
||||
$opening = -1;
|
||||
} elseif (in_array($token[0], array(T_SWITCH, T_FUNCTION, T_CLASS, T_CLOSE_TAG), true)) {
|
||||
$shorten = 0;
|
||||
} elseif ($token === ';') {
|
||||
$shorten--;
|
||||
} elseif ($token === '{') {
|
||||
if ($opening < 0) {
|
||||
$opening = $i;
|
||||
} elseif ($shorten > 1) {
|
||||
$shorten = 0;
|
||||
}
|
||||
} elseif ($token === '}' && $opening >= 0 && $shorten == 1) {
|
||||
unset($tokens[$opening]);
|
||||
unset($tokens[$i]);
|
||||
$shorten = 0;
|
||||
$opening = -1;
|
||||
}
|
||||
}
|
||||
$tokens = array_values($tokens);
|
||||
|
||||
foreach ($tokens as $i => $token) {
|
||||
if ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
|
||||
$short_variables[$token[1]]++;
|
||||
}
|
||||
}
|
||||
|
||||
arsort($short_variables);
|
||||
$chars = implode(range('a', 'z')) . '_' . implode(range('A', 'Z'));
|
||||
//! preserve variable names between versions if possible
|
||||
$short_variables2 = array_splice($short_variables, strlen($chars));
|
||||
ksort($short_variables);
|
||||
ksort($short_variables2);
|
||||
$short_variables += $short_variables2;
|
||||
foreach (array_keys($short_variables) as $number => $key) {
|
||||
$short_variables[$key] = short_identifier($number, $chars); // could use also numbers and \x7f-\xff
|
||||
}
|
||||
|
||||
$set = array_flip(preg_split('//', '!"#$%&\'()*+,-./:;<=>?@[]^`{|}'));
|
||||
$space = '';
|
||||
$output = '';
|
||||
$in_echo = false;
|
||||
$doc_comment = false; // include only first /**
|
||||
for (reset($tokens); list($i, $token) = each($tokens);) {
|
||||
if (!is_array($token)) {
|
||||
$token = array(0, $token);
|
||||
}
|
||||
if (
|
||||
$tokens[$i+2][0] === T_CLOSE_TAG && $tokens[$i+3][0] === T_INLINE_HTML && $tokens[$i+4][0] === T_OPEN_TAG
|
||||
&& strlen(add_apo_slashes($tokens[$i+3][1])) < strlen($tokens[$i+3][1]) + 3
|
||||
) {
|
||||
$tokens[$i+2] = array(T_ECHO, 'echo');
|
||||
$tokens[$i+3] = array(T_CONSTANT_ENCAPSED_STRING, "'" . add_apo_slashes($tokens[$i+3][1]) . "'");
|
||||
$tokens[$i+4] = array(0, ';');
|
||||
}
|
||||
if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE || ($token[0] == T_DOC_COMMENT && $doc_comment)) {
|
||||
$space = "\n";
|
||||
} else {
|
||||
if ($token[0] == T_DOC_COMMENT) {
|
||||
$doc_comment = true;
|
||||
}
|
||||
if ($token[0] == T_VAR || $token[0] == T_PUBLIC || $token[0] == T_PROTECTED || $token[0] == T_PRIVATE) {
|
||||
if ($token[0] == T_PUBLIC) {
|
||||
$token[1] = ($tokens[$i+2][1][0] == '$' ? 'var' : '');
|
||||
}
|
||||
$shortening = false;
|
||||
} elseif (!$shortening) {
|
||||
if ($token[1] == ';' || $token[0] == T_FUNCTION) {
|
||||
$shortening = true;
|
||||
}
|
||||
} elseif ($token[0] == T_ECHO) {
|
||||
$in_echo = true;
|
||||
} elseif ($token[1] == ';' && $in_echo) {
|
||||
if ($tokens[$i+1][0] === T_WHITESPACE && $tokens[$i+2][0] === T_ECHO) {
|
||||
next($tokens);
|
||||
$i++;
|
||||
}
|
||||
if ($tokens[$i+1][0] === T_ECHO) {
|
||||
// join two consecutive echos
|
||||
next($tokens);
|
||||
$token[1] = ','; // '.' would conflict with "a".1+2 and would use more memory //! remove ',' and "," but not $var","
|
||||
} else {
|
||||
$in_echo = false;
|
||||
}
|
||||
} elseif ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
|
||||
$token[1] = '$' . $short_variables[$token[1]];
|
||||
}
|
||||
if (isset($set[substr($output, -1)]) || isset($set[$token[1][0]])) {
|
||||
$space = '';
|
||||
}
|
||||
$output .= $space . $token[1];
|
||||
$space = '';
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
function short_identifier($number, $chars) {
|
||||
$return = '';
|
||||
while ($number >= 0) {
|
||||
$return .= $chars[$number % strlen($chars)];
|
||||
$number = floor($number / strlen($chars)) - 1;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
function add_apo_slashes($s) {
|
||||
return addcslashes($s, "\\'");
|
||||
}
|
||||
|
||||
if (!function_exists("each")) {
|
||||
function each(&$arr) {
|
||||
$key = key($arr);
|
||||
next($arr);
|
||||
return $key === null ? false : array($key, $arr[$key]);
|
||||
}
|
||||
}
|
||||
10
phpcs.xml
10
phpcs.xml
@@ -32,11 +32,19 @@
|
||||
<exclude name="PSR12.Classes.ClassInstantiation.MissingParentheses"/>
|
||||
<exclude name="Squiz.Scope.MethodScope.Missing"/>
|
||||
|
||||
<!-- TODO: Ignore only in <?php if () { ?><?php } ?> -->
|
||||
<!-- False positives. -->
|
||||
<exclude name="Generic.WhiteSpace.ScopeIndent.Incorrect"/>
|
||||
<exclude name="Generic.WhiteSpace.ScopeIndent.IncorrectExact"/>
|
||||
</rule>
|
||||
|
||||
<rule ref="Generic.WhiteSpace.ScopeIndent">
|
||||
<properties>
|
||||
<property name="ignoreIndentationTokens" type="array">
|
||||
<element value="T_OPEN_TAG"/>
|
||||
</property>
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<rule ref="PSR1.Methods.CamelCapsMethodName.NotCamelCaps">
|
||||
<exclude-pattern>adminer/drivers/</exclude-pattern>
|
||||
<exclude-pattern>adminer/include/pdo.inc.php</exclude-pattern>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
class AdminerDotJs {
|
||||
const FILENAME = "adminer.js";
|
||||
|
||||
function head() {
|
||||
function head($dark = null) {
|
||||
if (file_exists(self::FILENAME)) {
|
||||
echo Adminer\script_src(self::FILENAME . "?v=" . crc32(file_get_contents(self::FILENAME))), "\n";
|
||||
}
|
||||
|
||||
92
plugins/codemirror.php
Normal file
92
plugins/codemirror.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/** Use Codemirror 5 for syntax highlighting and SQL <textarea> including type-ahead of keywords and tables
|
||||
* @link https://codemirror.net/5/
|
||||
* @link https://www.adminer.org/plugins/#use
|
||||
* @author Jakub Vrana, https://www.vrana.cz/
|
||||
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
|
||||
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||
*/
|
||||
class AdminerCodemirror {
|
||||
private $root;
|
||||
|
||||
function __construct($root = "codemirror5") {
|
||||
$this->root = $root;
|
||||
}
|
||||
|
||||
function syntaxHighlighting($tableStatuses) {
|
||||
$connection = Adminer\connection();
|
||||
?>
|
||||
<style>
|
||||
@import url(<?php echo $this->root; ?>/lib/codemirror.css);
|
||||
@import url(<?php echo $this->root; ?>/addon/hint/show-hint.css);
|
||||
.CodeMirror { border: 1px inset #ccc; resize: both; }
|
||||
</style>
|
||||
<?php
|
||||
echo Adminer\script_src("$this->root/lib/codemirror.js");
|
||||
echo Adminer\script_src("$this->root/addon/runmode/runmode.js");
|
||||
echo Adminer\script_src("$this->root/addon/hint/show-hint.js");
|
||||
echo Adminer\script_src("$this->root/mode/javascript/javascript.js");
|
||||
if (Adminer\support("sql")) {
|
||||
echo Adminer\script_src("$this->root/mode/sql/sql.js");
|
||||
echo Adminer\script_src("$this->root/addon/hint/sql-hint.js");
|
||||
}
|
||||
$tables = array();
|
||||
foreach ($tableStatuses as $status) {
|
||||
foreach (Adminer\fields($status["Name"]) as $name => $field) {
|
||||
$tables[$status["Name"]][] = $name;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<script <?php echo Adminer\nonce(); ?>>
|
||||
function getCmMode(el) {
|
||||
const match = el.className.match(/(^|\s)jush-([^ ]+)/);
|
||||
if (match) {
|
||||
const modes = {
|
||||
js: 'application/json',
|
||||
sql: 'text/x-<?php echo ($connection->maria ? "mariadb" : "mysql"); ?>',
|
||||
oracle: 'text/x-sql',
|
||||
clickhouse: 'text/x-sql',
|
||||
firebird: 'text/x-sql'
|
||||
};
|
||||
return modes[match[2]] || 'text/x-' + match[2];
|
||||
}
|
||||
}
|
||||
|
||||
for (const el of qsa('code')) {
|
||||
const mode = getCmMode(el);
|
||||
if (mode) {
|
||||
el.className += ' cm-s-default';
|
||||
CodeMirror.runMode(el.textContent, mode, el);
|
||||
}
|
||||
}
|
||||
|
||||
for (const el of qsa('textarea')) {
|
||||
const mode = getCmMode(el);
|
||||
if (mode) {
|
||||
const width = el.clientWidth;
|
||||
const height = el.clientHeight;
|
||||
const cm = CodeMirror.fromTextArea(el, {
|
||||
mode: mode,
|
||||
extraKeys: { 'Ctrl-Space': 'autocomplete' },
|
||||
hintOptions: {
|
||||
completeSingle: false,
|
||||
tables: <?php echo json_encode($tables); ?>,
|
||||
defaultTable: <?php echo json_encode($_GET["trigger"] ? $_GET["trigger"] : ($_GET["check"] ? $_GET["check"] : null)); ?>
|
||||
}
|
||||
});
|
||||
cm.setSize(width, height);
|
||||
cm.on('inputRead', function () {
|
||||
const token = cm.getTokenAt(cm.getCursor());
|
||||
if (/^[.`"\w]\w*$/.test(token.string)) {
|
||||
CodeMirror.commands.autocomplete(cm);
|
||||
}
|
||||
});
|
||||
setupSubmitHighlightInput(cm.getWrapperElement());
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<?php
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ if (isset($_GET["elastic"])) {
|
||||
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)) {
|
||||
$driver = get_driver();
|
||||
$driver = driver();
|
||||
|
||||
$where = explode(" AND ", $matches[2]);
|
||||
|
||||
|
||||
@@ -73,8 +73,8 @@ if (isset($_GET["mongo"])) {
|
||||
(is_a($val, 'MongoDB\BSON\Binary') ? $val->getData() : //! allow downloading
|
||||
(is_a($val, 'MongoDB\BSON\Regex') ? "$val" :
|
||||
(is_object($val) || is_array($val) ? json_encode($val, 256) : // 256 = JSON_UNESCAPED_UNICODE
|
||||
$val // MongoMinKey, MongoMaxKey
|
||||
)))));
|
||||
$val))))) // MongoMinKey, MongoMaxKey
|
||||
;
|
||||
}
|
||||
$this->rows[] = $row;
|
||||
foreach ($row as $key => $val) {
|
||||
@@ -166,7 +166,7 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
function fields($table) {
|
||||
$driver = get_driver();
|
||||
$driver = driver();
|
||||
$fields = fields_from_edit();
|
||||
if (!$fields) {
|
||||
$result = $driver->select($table, array("*"), null, null, array(), 10);
|
||||
|
||||
@@ -27,7 +27,7 @@ class AdminerEditCalendar {
|
||||
$this->langPath = $langPath;
|
||||
}
|
||||
|
||||
function head() {
|
||||
function head($dark = null) {
|
||||
echo $this->prepend;
|
||||
if ($this->langPath) {
|
||||
$lang = Adminer\get_lang();
|
||||
|
||||
@@ -10,19 +10,10 @@ class AdminerPlugin extends Adminer\Adminer {
|
||||
protected $plugins;
|
||||
|
||||
/** Register plugins
|
||||
* @param array object instances or null to register all classes starting by 'Adminer'
|
||||
* @param array object instances
|
||||
*/
|
||||
function __construct($plugins) {
|
||||
if ($plugins === null) {
|
||||
$plugins = array();
|
||||
foreach (get_declared_classes() as $class) {
|
||||
if (preg_match('~^Adminer\w~i', $class) && !is_subclass_of($class, 'Adminer\Adminer')) {
|
||||
$plugins[$class] = new $class;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->plugins = $plugins;
|
||||
//! it is possible to use ReflectionObject to find out which plugins defines which methods at once
|
||||
}
|
||||
|
||||
private function callParent($function, $args) {
|
||||
@@ -162,7 +153,7 @@ class AdminerPlugin extends Adminer\Adminer {
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function head() {
|
||||
function head($dark = null) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
@@ -407,6 +398,11 @@ class AdminerPlugin extends Adminer\Adminer {
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function syntaxHighlighting($tables) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function databasesPrint($missing) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
|
||||
@@ -18,7 +18,7 @@ class AdminerPrettyJsonColumn {
|
||||
$json = $this->testJson($value);
|
||||
if ($json !== $value) {
|
||||
$jsonText = json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
return "<textarea$attrs cols='50' rows='20'>" . h($jsonText) . "</textarea>";
|
||||
return "<textarea$attrs cols='50' rows='20'>" . Adminer\h($jsonText) . "</textarea>";
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<?php
|
||||
|
||||
/** Show comments of sql structure in more places (mainly where you edit things)
|
||||
* @link https://www.adminer.org/plugins/#use
|
||||
* @author Adam Kuśmierz, http://kusmierz.be/
|
||||
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
|
||||
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||
*/
|
||||
class AdminerStructComments {
|
||||
|
||||
function fieldName(&$field, $order = 0) {
|
||||
return '<span title="' . Adminer\h($field["full_type"]) . (!empty($field["comment"]) ? ': ' . $field["comment"] : '') . '">' . Adminer\h($field["field"]) . '</span>';
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ class AdminerTinymce {
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
function head() {
|
||||
function head($dark = null) {
|
||||
$lang = Adminer\get_lang();
|
||||
$lang = ($lang == "zh" ? "zh-cn" : ($lang == "zh-tw" ? "zh" : $lang));
|
||||
if (!file_exists(dirname($this->path) . "/langs/$lang.js")) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
class AdminerVersionNoverify {
|
||||
|
||||
function head() {
|
||||
function head($dark = null) {
|
||||
echo Adminer\script("verifyVersion = function () {};");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class AdminerWymeditor {
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
function head() {
|
||||
function head($dark = null) {
|
||||
foreach ($this->scripts as $script) {
|
||||
echo Adminer\script_src($script);
|
||||
}
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
<title>Katalon CockroachDB</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Login</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Login</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=lang</td><td>label=English</td></tr>
|
||||
@@ -18,13 +17,12 @@
|
||||
<tr><td>type</td><td>name=auth[server]</td><td>localhost:26257</td></tr>
|
||||
<tr><td>type</td><td>id=username</td><td>ODBC</td></tr>
|
||||
<tr><td>type</td><td>name=auth[password]</td><td>ODBC</td></tr>
|
||||
<tr><td>clickAndWait</td><td>xpath=//input[@value='Login']</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Login']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>CockroachDB</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create table</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create table</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create table</td><td></td></tr>
|
||||
@@ -42,10 +40,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create index</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create index</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter indexes</td><td></td></tr>
|
||||
@@ -58,10 +55,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Indexes have been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create table 2</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create table 2</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create table</td><td></td></tr>
|
||||
@@ -79,10 +75,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Foreign key</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Foreign key</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&table=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Add foreign key</td><td></td></tr>
|
||||
@@ -91,10 +86,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Foreign key has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Alter table</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Alter table</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter table</td><td></td></tr>
|
||||
@@ -108,27 +102,29 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Check constraints</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Check constraints</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&table=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Create check</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>albums_interpret_check</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="clause"]').value = 'interpret > 0'</td><td></td></tr>
|
||||
<tr><td>click</td><td>xpath=//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been created.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[interpret]</td><td>0</td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>failed to satisfy CHECK constraint</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&check=albums&name=albums_interpret_check</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent<td>((interpret > 0:::INT8))</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop albums_interpret_check?</td><td></td></tr>
|
||||
<tr><td>click</td><td>name=drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create view</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create view</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&view=</td><td></td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="select"]').value = 'SELECT albums.id, albums.title, interprets.name FROM albums LEFT JOIN interprets ON albums.interpret = interprets.id'</td><td></td></tr>
|
||||
@@ -136,10 +132,20 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>View has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Insert</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Materialized view</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&view=</td><td></td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="select"]').value = 'SELECT albums.id, albums.title, interprets.name FROM albums LEFT JOIN interprets ON albums.interpret = interprets.id'</td><td></td></tr>
|
||||
<tr><td>type</td><td>name</td><td>materialized_view</td></tr>
|
||||
<tr><td>click</td><td>materialized</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Materialized view</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Insert</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&edit=interprets</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[id]</td><td>1</td></tr>
|
||||
@@ -152,10 +158,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item has been inserted.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Clone</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Clone</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>check[]</td><td></td></tr>
|
||||
@@ -165,10 +170,35 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>1 item has been affected.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Explain</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3" data-tags="">Enum</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>http://localhost:8080/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Create type</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>alive</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="as"]').value = "AS ENUM('alive', 'deceased')"</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=interprets</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Alter table</td><td></td></tr>
|
||||
<tr><td>click</td><td>name=add[3]</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[4][field]</td><td>alive</td></tr>
|
||||
<tr><td>select</td><td>name=fields[4][type]</td><td>label=alive</td></tr>
|
||||
<tr><td>click</td><td>name=fields[4][null]</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=alive</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>'alive', 'deceased'</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop alive?</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Drop']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>cannot drop type</td><td></td></tr>
|
||||
<tr><td>open</td><td>http://localhost:8080/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&edit=interprets&where%5Bid%5D=1</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@value='deceased']</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>deceased</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Explain</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&select=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Edit</td><td></td></tr>
|
||||
@@ -176,29 +206,26 @@
|
||||
<tr><td>click</td><td>link=Explain</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>LIMITED SCAN</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Reference</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Reference</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&select=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=1</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Michael Jackson</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Update</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Update</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&edit=albums&where%5Bid%5D=2</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[title]</td><td>Black or White</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item has been updated.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Delete</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Delete</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@name='check[]' and @value='where%5Bid%5D=2']</td><td></td></tr>
|
||||
@@ -207,10 +234,9 @@
|
||||
<tr><td>click</td><td>delete</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>1 item has been affected.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Truncate</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Truncate</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>all</td><td></td></tr>
|
||||
@@ -219,10 +245,9 @@
|
||||
<tr><td>click</td><td>delete</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>No rows.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Export</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Export</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&dump=</td><td></td></tr>
|
||||
<tr><td>click</td><td>output</td><td></td></tr>
|
||||
@@ -234,10 +259,9 @@
|
||||
<tr><td>verifyTextPresent</td><td>INSERT INTO "interprets"</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>VIEW "albums_interprets"</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Procedures</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Procedures</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&procedure=</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>add[0]</td><td></td></tr>
|
||||
@@ -257,18 +281,41 @@
|
||||
<tr><td>type</td><td>fields[album_title]</td><td>Dangerous</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Call']</td><td></td></tr>
|
||||
<tr><td>assertTextPresent</td><td>Routine has been called,</td><td></td></tr>
|
||||
<!-- https://github.com/cockroachdb/cockroach/issues/142886
|
||||
<tr><td>clickAndWait</td><td>link=public</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop insert_album?</td><td></td></tr>
|
||||
<tr><td>click</td><td>drop</td><td></td></tr>
|
||||
<!-- This looks like a bug in CockroachDB, not Adminer. <tr><td>verifyTextPresent</td><td>Routine has been dropped.</td><td></td></tr> -->
|
||||
<tr><td>verifyTextPresent</td><td>Routine has been dropped.</td><td></td></tr>
|
||||
-->
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost%3A26257&username=ODBC&db=adminer_test&ns=public&sql=DROP+PROCEDURE+%22insert_album%22</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Execute']</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Drop</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3" data-tags="">Generated columns</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&create=</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>generated</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1][field]</td><td>normal</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][field]</td><td>stored</td></tr>
|
||||
<tr><td>select</td><td>name=fields[1.1][generated]</td><td>label=STORED</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][default]</td><td>normal + 200</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>normal + 200</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Alter indexes</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=indexes[2][columns][1]</td><td>label=stored</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Indexes have been altered.</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>verifyTextNotPresent</td><td>stored</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[normal]</td><td>20</td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>220</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Drop</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public</td><td></td></tr>
|
||||
<tr><td>click</td><td>id=check-all</td><td></td></tr>
|
||||
@@ -276,32 +323,30 @@
|
||||
<tr><td>click</td><td>name=drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>No tables.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Variables</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Variables</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&variables=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>crdb_version</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">SQL command</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">SQL command</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&sql=SELECT+122%2B1</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Execute']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>123</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Logout</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Logout</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>logout</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Logout successful.</td><td></td></tr>
|
||||
<tr><td>open</td><td>/coverage.php</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
<title>Katalon MariaDB</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Login</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Login</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=lang</td><td>label=English</td></tr>
|
||||
@@ -17,17 +16,16 @@
|
||||
<tr><td>type</td><td>id=username</td><td>ODBC</td></tr>
|
||||
<tr><td>type</td><td>name=auth[server]</td><td>localhost:3307</td></tr>
|
||||
<tr><td>type</td><td>name=auth[password]</td><td>ODBC</td></tr>
|
||||
<tr><td>clickAndWait</td><td>xpath=//input[@value='Login']</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Login']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>MariaDB</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=SQL command</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&sql=DROP+DATABASE+IF+EXISTS+adminer_test</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Execute']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Query executed OK</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create database</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create database</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create database</td><td></td></tr>
|
||||
@@ -36,10 +34,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Database has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create table</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create table</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create table</td><td></td></tr>
|
||||
@@ -58,10 +55,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create index</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create index</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter indexes</td><td></td></tr>
|
||||
@@ -74,10 +70,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Indexes have been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Partitioning</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Partitioning</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter table</td><td></td></tr>
|
||||
@@ -97,10 +92,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create table 2</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create table 2</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create table</td><td></td></tr>
|
||||
@@ -120,10 +114,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Foreign key</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Foreign key</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&table=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Add foreign key</td><td></td></tr>
|
||||
@@ -132,10 +125,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Foreign key has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Alter table</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Alter table</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter table</td><td></td></tr>
|
||||
@@ -149,10 +141,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create trigger</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create trigger</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&trigger=albums</td><td></td></tr>
|
||||
<tr><td>select</td><td>Timing</td><td>label=AFTER</td></tr>
|
||||
@@ -160,27 +151,29 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Trigger has been created.</td><td></td></tr></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Check constraints</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Check constraints</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&table=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Create check</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>albums_interpret_check</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="clause"]').value = 'interpret > 0'</td><td></td></tr>
|
||||
<tr><td>click</td><td>xpath=//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been created.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[interpret]</td><td>0</td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>CONSTRAINT `albums_interpret_check` failed for `adminer_test`.`albums`</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&check=albums&name=albums_interpret_check</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent<td>`interpret` > 0</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop albums_interpret_check?</td><td></td></tr>
|
||||
<tr><td>click</td><td>name=drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create view</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create view</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&view=</td><td></td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="select"]').value = 'SELECT albums.id, albums.title, interprets.name FROM albums LEFT JOIN interprets ON albums.interpret = interprets.id'</td><td></td></tr>
|
||||
@@ -188,10 +181,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>View has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Insert</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Insert</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&edit=interprets</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[name]</td><td>Michael Jackson</td></tr>
|
||||
@@ -203,10 +195,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item 1 has been inserted.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Clone</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Clone</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>check[]</td><td></td></tr>
|
||||
@@ -215,10 +206,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item 2 has been inserted.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Explain</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Explain</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&select=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Edit</td><td></td></tr>
|
||||
@@ -226,29 +216,26 @@
|
||||
<tr><td>click</td><td>link=Explain</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>possible_keys</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Reference</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Reference</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&select=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=1</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Michael Jackson</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Update</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Update</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&edit=albums&where%5Bid%5D=2</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[title]</td><td>Black or White</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item has been updated.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Delete</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Delete</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@name='check[]' and @value='where%5Bid%5D=2']</td><td></td></tr>
|
||||
@@ -257,10 +244,9 @@
|
||||
<tr><td>click</td><td>delete</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>1 item has been affected.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Truncate</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Truncate</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>all</td><td></td></tr>
|
||||
@@ -269,10 +255,9 @@
|
||||
<tr><td>click</td><td>delete</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>No rows.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Privileges</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Privileges</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&user=</td><td></td></tr>
|
||||
<tr><td>type</td><td>user</td><td>adminer_test</td></tr>
|
||||
@@ -298,18 +283,16 @@
|
||||
<tr><td>click</td><td>drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>User has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Process list</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Process list</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&processlist=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>SHOW FULL PROCESSLIST</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Export</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Export</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&dump=</td><td></td></tr>
|
||||
<tr><td>click</td><td>output</td><td></td></tr>
|
||||
@@ -322,10 +305,9 @@
|
||||
<tr><td>verifyTextPresent</td><td>INSERT INTO `interprets`</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>VIEW `albums_interprets`</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Events</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Events</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&event=</td><td></td></tr>
|
||||
<tr><td>type</td><td>EVENT_NAME</td><td>no_albums</td></tr>
|
||||
@@ -340,10 +322,9 @@
|
||||
<tr><td>click</td><td>drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Event has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Procedures</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Procedures</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&procedure=</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>add[0]</td><td></td></tr>
|
||||
@@ -368,31 +349,60 @@
|
||||
<tr><td>click</td><td>drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Routine has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Variables</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3" data-tags="">Generated columns</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&create=</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>generated</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1][field]</td><td>normal</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][field]</td><td>virtual</td></tr>
|
||||
<tr><td>select</td><td>name=fields[1.1][generated]</td><td>label=VIRTUAL</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][default]</td><td>normal + 100</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.11][field]</td><td>stored</td></tr>
|
||||
<tr><td>select</td><td>name=fields[1.11][generated]</td><td>label=STORED</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.11][default]</td><td>normal + 200</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>`normal` + 100</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>`normal` + 200</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Alter indexes</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=indexes[1][columns][1]</td><td>label=virtual</td></tr>
|
||||
<tr><td>select</td><td>name=indexes[1][columns][11]</td><td>label=stored</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Indexes have been altered.</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>verifyTextNotPresent</td><td>virtual</td><td></td></tr>
|
||||
<tr><td>verifyTextNotPresent</td><td>stored</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[normal]</td><td>20</td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>120</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>220</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Variables</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&variables=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>basedir</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&status=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Uptime</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">History</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">History</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC&sql=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>DROP DATABASE IF EXISTS adminer_test</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Logout</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Logout</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?server=localhost:3307&username=ODBC</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>logout</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Logout successful.</td><td></td></tr>
|
||||
<tr><td>open</td><td>/coverage.php</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
133
tests/mssql.html
133
tests/mssql.html
@@ -6,10 +6,9 @@
|
||||
<title>Katalon MS SQL</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Login</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Login</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=lang</td><td>label=English</td></tr>
|
||||
@@ -18,12 +17,11 @@
|
||||
<tr><td>type</td><td>name=auth[server]</td><td>(local)</td></tr>
|
||||
<tr><td>type</td><td>id=username</td><td>ODBC</td></tr>
|
||||
<tr><td>type</td><td>name=auth[password]</td><td>ODBC</td></tr>
|
||||
<tr><td>clickAndWait</td><td>xpath=//input[@value='Login']</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Login']</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create table</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create table</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create table</td><td></td></tr>
|
||||
@@ -41,10 +39,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create index</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create index</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter indexes</td><td></td></tr>
|
||||
@@ -57,10 +54,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Indexes have been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create table 2</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create table 2</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create table</td><td></td></tr>
|
||||
@@ -78,10 +74,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Foreign key</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Foreign key</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&table=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Add foreign key</td><td></td></tr>
|
||||
@@ -90,10 +85,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Foreign key has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Alter table</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Alter table</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter table</td><td></td></tr>
|
||||
@@ -107,27 +101,29 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Check constraints</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Check constraints</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&table=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Create check</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>albums_interpret_check</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="clause"]').value = 'interpret > 0'</td><td></td></tr>
|
||||
<tr><td>click</td><td>xpath=//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been created.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[interpret]</td><td>0</td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>statement conflicted with the CHECK constraint</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&check=albums&name=albums_interpret_check</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent<td>([interpret]>(0))</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop albums_interpret_check?</td><td></td></tr>
|
||||
<tr><td>click</td><td>name=drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create view</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create view</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&view=</td><td></td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="select"]').value = 'SELECT albums.id, albums.title, interprets.name FROM albums LEFT JOIN interprets ON albums.interpret = interprets.id'</td><td></td></tr>
|
||||
@@ -135,10 +131,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>View has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Insert</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Insert</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&edit=interprets</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[name]</td><td>Michael Jackson</td></tr>
|
||||
@@ -150,10 +145,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item 1 has been inserted.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Clone</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Clone</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>check[]</td><td></td></tr>
|
||||
@@ -162,10 +156,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item 2 has been inserted.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Explain</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Explain</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&select=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Edit</td><td></td></tr>
|
||||
@@ -173,29 +166,26 @@
|
||||
<tr><td>click</td><td>link=Explain</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Clustered Index Scan</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Reference</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Reference</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&select=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=1</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Michael Jackson</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Update</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Update</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&edit=albums&where%5Bid%5D=2</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[title]</td><td>Black or White</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item has been updated.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Delete</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Delete</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@name='check[]' and @value='where%5Bid%5D=2']</td><td></td></tr>
|
||||
@@ -204,10 +194,9 @@
|
||||
<tr><td>click</td><td>delete</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>1 item has been affected.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Truncate</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Truncate</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>all</td><td></td></tr>
|
||||
@@ -216,10 +205,9 @@
|
||||
<tr><td>click</td><td>delete</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>No rows.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Export</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Export</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&dump=</td><td></td></tr>
|
||||
<tr><td>click</td><td>output</td><td></td></tr>
|
||||
@@ -231,10 +219,38 @@
|
||||
<tr><td>verifyTextPresent</td><td>INSERT INTO [dbo].[interprets]</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>VIEW [dbo].[albums_interprets]</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Drop</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3" data-tags="">Generated columns</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&create=</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>generated</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1][field]</td><td>normal</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][field]</td><td>virtual</td></tr>
|
||||
<tr><td>select</td><td>name=fields[1.1][generated]</td><td>label=VIRTUAL</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][default]</td><td>normal + 100</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.11][field]</td><td>stored</td></tr>
|
||||
<tr><td>select</td><td>name=fields[1.11][generated]</td><td>label=PERSISTED</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.11][default]</td><td>normal + 200</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>[normal]+(100)</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>[normal]+(200)</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Alter indexes</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=indexes[1][columns][1]</td><td>label=virtual</td></tr>
|
||||
<tr><td>select</td><td>name=indexes[1][columns][11]</td><td>label=stored</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Indexes have been altered.</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>verifyTextNotPresent</td><td>virtual</td><td></td></tr>
|
||||
<tr><td>verifyTextNotPresent</td><td>stored</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[normal]</td><td>20</td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>120</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>220</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Drop</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo</td><td></td></tr>
|
||||
<tr><td>click</td><td>id=check-all</td><td></td></tr>
|
||||
@@ -242,24 +258,23 @@
|
||||
<tr><td>click</td><td>name=drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>No tables.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">SQL command</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">SQL command</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&sql=SELECT+122%2B1</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Execute']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>123</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Logout</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Logout</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?mssql=%28local%29&username=ODBC</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>logout</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Logout successful.</td><td></td></tr>
|
||||
<tr><td>open</td><td>/coverage.php</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
184
tests/mysql.html
184
tests/mysql.html
@@ -6,10 +6,9 @@
|
||||
<title>Katalon MySQL</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Login</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Login</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/coverage.php?coverage=0</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/</td><td></td></tr>
|
||||
@@ -17,17 +16,16 @@
|
||||
<tr><td>clickAndWait</td><td>css=#lang > input[type="submit"]</td><td></td></tr>
|
||||
<tr><td>type</td><td>id=username</td><td>ODBC</td></tr>
|
||||
<tr><td>type</td><td>name=auth[password]</td><td>ODBC</td></tr>
|
||||
<tr><td>clickAndWait</td><td>xpath=//input[@value='Login']</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Login']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Logged as</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=SQL command</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&sql=DROP+DATABASE+IF+EXISTS+adminer_test</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Execute']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Query executed OK</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create database</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create database</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create database</td><td></td></tr>
|
||||
@@ -36,10 +34,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Database has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create table</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create table</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create table</td><td></td></tr>
|
||||
@@ -58,10 +55,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create index</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create index</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter indexes</td><td></td></tr>
|
||||
@@ -74,10 +70,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Indexes have been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Partitioning</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Partitioning</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter table</td><td></td></tr>
|
||||
@@ -97,10 +92,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create table 2</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create table 2</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create table</td><td></td></tr>
|
||||
@@ -120,10 +114,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Foreign key</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Foreign key</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&table=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Add foreign key</td><td></td></tr>
|
||||
@@ -132,10 +125,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Foreign key has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Alter table</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Alter table</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter table</td><td></td></tr>
|
||||
@@ -149,10 +141,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create trigger</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create trigger</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&trigger=albums</td><td></td></tr>
|
||||
<tr><td>select</td><td>Timing</td><td>label=AFTER</td></tr>
|
||||
@@ -160,27 +151,29 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Trigger has been created.</td><td></td></tr></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Check constraints</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Check constraints</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&table=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Create check</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>albums_interpret_check</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="clause"]').value = 'interpret > 0'</td><td></td></tr>
|
||||
<tr><td>click</td><td>xpath=//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been created.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[interpret]</td><td>0</td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check constraint 'albums_interpret_check' is violated.</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&check=albums&name=albums_interpret_check</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent<td>(`interpret` > 0)</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop albums_interpret_check?</td><td></td></tr>
|
||||
<tr><td>click</td><td>name=drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create view</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create view</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&view=</td><td></td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="select"]').value = 'SELECT albums.id, albums.title, interprets.name FROM albums LEFT JOIN interprets ON albums.interpret = interprets.id'</td><td></td></tr>
|
||||
@@ -188,10 +181,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>View has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Insert</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Insert</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&edit=interprets</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[name]</td><td>Michael Jackson</td></tr>
|
||||
@@ -203,10 +195,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item 1 has been inserted.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Clone</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Clone</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>check[]</td><td></td></tr>
|
||||
@@ -215,10 +206,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item 2 has been inserted.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Explain</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Explain</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&select=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Edit</td><td></td></tr>
|
||||
@@ -226,29 +216,26 @@
|
||||
<tr><td>click</td><td>link=Explain</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>possible_keys</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Reference</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Reference</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&select=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=1</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Michael Jackson</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Update</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Update</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&edit=albums&where%5Bid%5D=2</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[title]</td><td>Black or White</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item has been updated.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Delete</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Delete</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@name='check[]' and @value='where%5Bid%5D=2']</td><td></td></tr>
|
||||
@@ -257,10 +244,9 @@
|
||||
<tr><td>click</td><td>delete</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>1 item has been affected.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Truncate</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Truncate</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>all</td><td></td></tr>
|
||||
@@ -269,10 +255,9 @@
|
||||
<tr><td>click</td><td>delete</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>No rows.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Privileges</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Privileges</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&user=</td><td></td></tr>
|
||||
<tr><td>type</td><td>user</td><td>adminer_test</td></tr>
|
||||
@@ -298,18 +283,16 @@
|
||||
<tr><td>click</td><td>drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>User has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Process list</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Process list</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&processlist=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>SHOW FULL PROCESSLIST</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Export</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Export</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&dump=</td><td></td></tr>
|
||||
<tr><td>click</td><td>output</td><td></td></tr>
|
||||
@@ -322,10 +305,9 @@
|
||||
<tr><td>verifyTextPresent</td><td>INSERT INTO `interprets`</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>VIEW `albums_interprets`</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Events</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Events</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&event=</td><td></td></tr>
|
||||
<tr><td>type</td><td>EVENT_NAME</td><td>no_albums</td></tr>
|
||||
@@ -340,10 +322,9 @@
|
||||
<tr><td>click</td><td>drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Event has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Procedures</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Procedures</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&procedure=</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>add[0]</td><td></td></tr>
|
||||
@@ -368,44 +349,71 @@
|
||||
<tr><td>click</td><td>drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Routine has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Variables</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3" data-tags="">Generated columns</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&create=</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>generated</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1][field]</td><td>normal</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][field]</td><td>virtual</td></tr>
|
||||
<tr><td>select</td><td>name=fields[1.1][generated]</td><td>label=VIRTUAL</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][default]</td><td>normal + 100</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.11][field]</td><td>stored</td></tr>
|
||||
<tr><td>select</td><td>name=fields[1.11][generated]</td><td>label=STORED</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.11][default]</td><td>normal + 200</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>`normal` + 100</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>`normal` + 200</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Alter indexes</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=indexes[1][columns][1]</td><td>label=virtual</td></tr>
|
||||
<tr><td>select</td><td>name=indexes[1][columns][11]</td><td>label=stored</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Indexes have been altered.</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>verifyTextNotPresent</td><td>virtual</td><td></td></tr>
|
||||
<tr><td>verifyTextNotPresent</td><td>stored</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[normal]</td><td>20</td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>120</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>220</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Variables</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&variables=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>basedir</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&status=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Uptime</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">History</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">History</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&sql=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>DROP DATABASE IF EXISTS adminer_test</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Warnings</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Warnings</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>xpath=(//a[contains(text(),'=')])[1]</td><td></td></tr>
|
||||
<tr><td>click</td><td>//th[@id='th[interpret]']/span/a[2]</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=where[0][val]</td><td>1.2.3</td></tr>
|
||||
<tr><td>submit</td><td>id=form</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Warnings</td><td></td></tr>
|
||||
<tr><td>verifyText</td><td>//div[@id='warnings']/div/table/tbody/tr/td[3]</td><td>Truncated incorrect DOUBLE value: '1.2.3'</td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Editor</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Editor</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/editor/example.php</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=lang</td><td>label=English</td></tr>
|
||||
<tr><td>clickAndWait</td><td>css=#lang > input[type="submit"]</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=auth[username]</td><td>admin</td></tr>
|
||||
<tr><td>click</td><td>xpath=//input[@value='Login']</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Login']</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[name]</td><td>Michael Jackson</td></tr>
|
||||
@@ -417,10 +425,9 @@
|
||||
<tr><td>verifyTextPresent</td><td>Item 4 has been inserted.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>logout</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Logout</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Logout</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>logout</td><td></td></tr>
|
||||
@@ -429,5 +436,6 @@
|
||||
<tr><td>verifyTextPresent</td><td>Přihlásit se</td><td></td></tr>
|
||||
<tr><td>open</td><td>/coverage.php</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
180
tests/pgsql.html
180
tests/pgsql.html
@@ -6,10 +6,9 @@
|
||||
<title>Katalon PostgreSQL</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Login</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Login</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=lang</td><td>label=English</td></tr>
|
||||
@@ -18,12 +17,11 @@
|
||||
<tr><td>type</td><td>id=username</td><td>ODBC</td></tr>
|
||||
<tr><td>type</td><td>name=auth[password]</td><td>ODBC</td></tr>
|
||||
<tr><td>type</td><td>name=auth[db]</td><td>adminer_test</td></tr>
|
||||
<tr><td>clickAndWait</td><td>xpath=//input[@value='Login']</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Login']</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create table</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create table</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create table</td><td></td></tr>
|
||||
@@ -41,10 +39,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create index</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create index</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter indexes</td><td></td></tr>
|
||||
@@ -57,10 +54,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Indexes have been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create table 2</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create table 2</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create table</td><td></td></tr>
|
||||
@@ -78,10 +74,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Foreign key</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Foreign key</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&table=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Add foreign key</td><td></td></tr>
|
||||
@@ -90,10 +85,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Foreign key has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Alter table</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Alter table</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter table</td><td></td></tr>
|
||||
@@ -107,27 +101,29 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Check constraints</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Check constraints</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&table=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Create check</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>albums_interpret_check</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="clause"]').value = 'interpret > 0'</td><td></td></tr>
|
||||
<tr><td>click</td><td>xpath=//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been created.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[interpret]</td><td>0</td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>violates check constraint</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&check=albums&name=albums_interpret_check</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent<td>(interpret > 0)</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop albums_interpret_check?</td><td></td></tr>
|
||||
<tr><td>click</td><td>name=drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Create view</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Create view</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&view=</td><td></td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="select"]').value = 'SELECT albums.id, albums.title, interprets.name FROM albums LEFT JOIN interprets ON albums.interpret = interprets.id'</td><td></td></tr>
|
||||
@@ -135,10 +131,20 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>View has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Insert</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Materialized view</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&view=</td><td></td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="select"]').value = 'SELECT albums.id, albums.title, interprets.name FROM albums LEFT JOIN interprets ON albums.interpret = interprets.id'</td><td></td></tr>
|
||||
<tr><td>type</td><td>name</td><td>materialized_view</td></tr>
|
||||
<tr><td>click</td><td>materialized</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Materialized view</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Insert</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&edit=interprets</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[name]</td><td>Michael Jackson</td></tr>
|
||||
@@ -150,10 +156,9 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item has been inserted.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Clone</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Clone</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>check[]</td><td></td></tr>
|
||||
@@ -162,10 +167,35 @@
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>1 item has been affected.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Explain</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3" data-tags="">Enum</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>http://localhost:8080/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Create type</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>alive</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="as"]').value = "AS ENUM('alive', 'deceased')"</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=interprets</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Alter table</td><td></td></tr>
|
||||
<tr><td>click</td><td>name=add[3]</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[4][field]</td><td>alive</td></tr>
|
||||
<tr><td>select</td><td>name=fields[4][type]</td><td>label=alive</td></tr>
|
||||
<tr><td>click</td><td>name=fields[4][null]</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=alive</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>'alive', 'deceased'</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop alive?</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Drop']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>cannot drop type</td><td></td></tr>
|
||||
<tr><td>open</td><td>http://localhost:8080/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&edit=interprets&where%5Bid%5D=1</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@value='deceased']</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>deceased</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Explain</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&select=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Edit</td><td></td></tr>
|
||||
@@ -173,29 +203,26 @@
|
||||
<tr><td>click</td><td>link=Explain</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Seq Scan</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Reference</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Reference</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&select=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=1</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Michael Jackson</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Update</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Update</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&edit=albums&where%5Bid%5D=2</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[title]</td><td>Black or White</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item has been updated.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Delete</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Delete</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@name='check[]' and @value='where%5Bid%5D=2']</td><td></td></tr>
|
||||
@@ -204,10 +231,9 @@
|
||||
<tr><td>click</td><td>delete</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>1 item has been affected.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Truncate</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Truncate</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>all</td><td></td></tr>
|
||||
@@ -216,18 +242,16 @@
|
||||
<tr><td>click</td><td>delete</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>No rows.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Process list</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Process list</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&processlist=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>pg_stat_activity</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Export</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Export</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&dump=</td><td></td></tr>
|
||||
<tr><td>click</td><td>output</td><td></td></tr>
|
||||
@@ -239,10 +263,9 @@
|
||||
<tr><td>verifyTextPresent</td><td>INSERT INTO "interprets"</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>VIEW "albums_interprets"</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Procedures</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Procedures</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&procedure=</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>add[0]</td><td></td></tr>
|
||||
@@ -268,10 +291,31 @@
|
||||
<tr><td>click</td><td>drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Routine has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Drop</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3" data-tags="">Generated columns</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&create=</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>generated</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1][field]</td><td>normal</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][field]</td><td>stored</td></tr>
|
||||
<tr><td>select</td><td>name=fields[1.1][generated]</td><td>label=STORED</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][default]</td><td>normal + 200</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>normal + 200</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Alter indexes</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=indexes[1][columns][1]</td><td>label=stored</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Indexes have been altered.</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>verifyTextNotPresent</td><td>stored</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[normal]</td><td>20</td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>220</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Drop</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public</td><td></td></tr>
|
||||
<tr><td>click</td><td>id=check-all</td><td></td></tr>
|
||||
@@ -279,32 +323,30 @@
|
||||
<tr><td>click</td><td>name=drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>No tables.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Variables</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Variables</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&variables=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>autovacuum</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">SQL command</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">SQL command</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&sql=SELECT+122%2B1</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&sql=SELECT+122%2B1</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Execute']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>123</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">Logout</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Logout</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>logout</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Logout successful.</td><td></td></tr>
|
||||
<tr><td>open</td><td>/coverage.php</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
include __DIR__ . "/../adminer/include/errors.inc.php";
|
||||
include __DIR__ . "/../php_shrink.inc.php";
|
||||
|
||||
function check($code, $expected) {
|
||||
$shrinked = str_replace("\n", " ", php_shrink("<?php\n$code"));
|
||||
if ("<?php $expected" != $shrinked) {
|
||||
$backtrace = reset(debug_backtrace());
|
||||
echo "$backtrace[file]:$backtrace[line]:" . substr($shrinked, 6) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
check('$ab = 1; echo $ab;', '$a=1;echo$a;');
|
||||
check('$ab = 1; $cd = 2;', '$a=1;$b=2;');
|
||||
check('define("AB", 1);', 'define("AB",1);');
|
||||
check('function f($ab, $cd = 1) { return $ab; }', 'function f($a,$b=1){return$a;}');
|
||||
check('class C { var $ab = 1; }', 'class C{var$ab=1;}');
|
||||
check('class C { public $ab = 1; }', 'class C{var$ab=1;}');
|
||||
check('class C { protected $ab = 1; }', 'class C{protected$ab=1;}');
|
||||
check('class C { private $ab = 1; }', 'class C{private$ab=1;}');
|
||||
check('class C { private $ab = 1; }', 'class C{private$ab=1;}');
|
||||
check('class C { private function f($ab) { return $ab; }}', 'class C{private function f($a){return$a;}}');
|
||||
check('class C { public function f($ab) { return $ab; }}', 'class C{function f($a){return$a;}}');
|
||||
check('class C { private static $ab; }', 'class C{private static$ab;}');
|
||||
check('class C { const AB = 1; }', 'class C{const AB=1;}');
|
||||
check('class C { private const AB = 1; }', 'class C{private const AB=1;}');
|
||||
check('class C { public $ab; function f($cd) { return $cd . $this->ab; }}', 'class C{var$ab;function f($b){return$b.$this->ab;}}');
|
||||
check('namespace NS { class C { public $ab = 1; } } new NS\C; $ab = 2;', 'namespace NS{class C{var$ab=1;}}new NS\C;$a=2;');
|
||||
check('new \stdClass;', 'new \stdClass;');
|
||||
check('if (true) { echo "a"; } else { echo "b"; }', 'if(true)echo"a";else echo"b";');
|
||||
check('echo $_GET["a"];', 'echo$_GET["a"];');
|
||||
check('$ab = 1; echo "$ab";', '$a=1;echo"$a";');
|
||||
check('echo 1; echo 3;', 'echo 1,3;');
|
||||
check('echo 1; ?>2<?php echo 3;', "echo 1,'2',3;");
|
||||
check('/** preserve */ $a; /** ignore */ /* also ignore */ // ignore too', '/** preserve */$a;');
|
||||
check('$a = 1; ?><?php ?><?php $a = 2;', '$a=1;$a=2;');
|
||||
@@ -6,16 +6,15 @@
|
||||
<title>Katalon SQLite</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead>
|
||||
<tr><td rowspan="1" colspan="3">SQLite</td></tr>
|
||||
</thead>
|
||||
<thead><tr><td rowspan="1" colspan="3">Login</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=lang</td><td>label=English</td></tr>
|
||||
<tr><td>clickAndWait</td><td>css=#lang > input[type="submit"]</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=auth[driver]</td><td>label=SQLite</td></tr>
|
||||
<tr><td>type</td><td>id=username</td><td>admin</td></tr>
|
||||
<tr><td>type</td><td>id=username</td><td>ODBC</td></tr>
|
||||
<tr><td>type</td><td>name=auth[password]</td><td>YOUR_PASSWORD_HERE</td></tr>
|
||||
<tr><td>click</td><td>css=input[type="submit"]</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Create database</td><td></td></tr>
|
||||
@@ -25,39 +24,253 @@
|
||||
<tr><td>type</td><td>name=name</td><td>adminer_test.sqlite</td></tr>
|
||||
<tr><td>click</td><td>css=input[type="submit"]</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Database has been created.</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Create table</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>interprets</td></tr>
|
||||
<tr><td>click</td><td>css=label.block > input[name="auto_increment_col"]</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][field]</td><td>name</td></tr>
|
||||
<tr><td>select</td><td>name=fields[1.1][type]</td><td>label=text</td></tr>
|
||||
<tr><td>click</td><td>xpath=(//input[@value='Save'])[2]</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Create table</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create table</td><td></td></tr>
|
||||
<tr><td>type</td><td>name</td><td>interprets</td></tr>
|
||||
<tr><td>type</td><td>fields[1][field]</td><td>id</td></tr>
|
||||
<tr><td>select</td><td>fields[1][type]</td><td>label=integer</td></tr>
|
||||
<tr><td>click</td><td>//input[@name='auto_increment_col' and @value='1']</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][field]</td><td>name</td></tr>
|
||||
<tr><td>select</td><td>fields[1.1][type]</td><td>label=text</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][length]</td><td>50</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been created.</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[name]</td><td>Michael Jackson</td></tr>
|
||||
<tr><td>click</td><td>css=input[type="submit"]</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Create index</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter indexes</td><td></td></tr>
|
||||
<tr><td>select</td><td>indexes[2][type]</td><td>label=PRIMARY</td></tr>
|
||||
<tr><td>select</td><td>indexes[2][columns][1]</td><td>label=name</td></tr>
|
||||
<tr><td>verifyValue</td><td>name=indexes[2][name]</td><td>interprets_name</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>has more than one primary key</td><td></td></tr>
|
||||
<tr><td>select</td><td>indexes[2][type]</td><td>label=INDEX</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Indexes have been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Create table 2</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Create table</td><td></td></tr>
|
||||
<tr><td>type</td><td>name</td><td>albums</td></tr>
|
||||
<tr><td>type</td><td>fields[1][field]</td><td>id</td></tr>
|
||||
<tr><td>select</td><td>fields[1][type]</td><td>label=integer</td></tr>
|
||||
<tr><td>click</td><td>//input[@name='auto_increment_col' and @value='1']</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][field]</td><td>interpret</td></tr>
|
||||
<tr><td>select</td><td>fields[1.1][type]</td><td>label=integer</td></tr>
|
||||
<tr><td>type</td><td>fields[1.11][field]</td><td>title</td></tr>
|
||||
<tr><td>select</td><td>fields[1.11][type]</td><td>label=text</td></tr>
|
||||
<tr><td>type</td><td>fields[1.11][length]</td><td>50</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Foreign key</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&table=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Add foreign key</td><td></td></tr>
|
||||
<tr><td>selectAndWait</td><td>table</td><td>label=interprets</td></tr>
|
||||
<tr><td>select</td><td>source[0]</td><td>label=interpret</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Foreign key has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Alter table</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&table=interprets</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter table</td><td></td></tr>
|
||||
<tr><td>click</td><td>add[2]</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[2.1][field]</td><td>albums</td></tr>
|
||||
<tr><td>select</td><td>fields[2.1][type]</td><td>label=integer</td></tr>
|
||||
<tr><td>type</td><td>fields[2.1][length]</td><td></td></tr>
|
||||
<tr><td>uncheck</td><td>name=defaults</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>name=defaults</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[2.1][default]</td><td>0</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Table has been altered.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Create trigger</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&trigger=albums</td><td></td></tr>
|
||||
<tr><td>select</td><td>Timing</td><td>label=AFTER</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="Statement"]').value = 'BEGIN\nUPDATE interprets SET albums = albums + 1 WHERE id = NEW.interpret;\nEND'</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Trigger has been created.</td><td></td></tr></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Check constraints</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&table=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Create check</td><td></td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="clause"]').value = 'interpret > 0'</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been created.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[interpret]</td><td>0</td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>CHECK constraint failed</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&check=albums&name=interpret+%3E+0</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent<td>interpret > 0</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop interpret > 0?</td><td></td></tr>
|
||||
<tr><td>click</td><td>name=drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been dropped.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Create view</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&view=</td><td></td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="select"]').value = 'SELECT albums.id, albums.title, interprets.name FROM albums LEFT JOIN interprets ON albums.interpret = interprets.id'</td><td></td></tr>
|
||||
<tr><td>type</td><td>name</td><td>albums_interprets</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>View has been created.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Insert</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&edit=interprets</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[name]</td><td>Michael Jackson</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item 1 has been inserted.</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Create table</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>albums</td></tr>
|
||||
<tr><td>click</td><td>css=label.block > input[name="auto_increment_col"]</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][field]</td><td>interpret</td></tr>
|
||||
<tr><td>select</td><td>name=fields[1.1][on_delete]</td><td>label=CASCADE</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.11][field]</td><td>title</td></tr>
|
||||
<tr><td>select</td><td>name=fields[1.11][type]</td><td>label=text</td></tr>
|
||||
<tr><td>click</td><td>xpath=(//input[@value='Save'])[2]</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>interprets(id)</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&edit=albums</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[interpret]</td><td>1</td></tr>
|
||||
<tr><td>type</td><td>fields[title]</td><td>Dangerous</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item 1 has been inserted.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Clone</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>check[]</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>clone</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[title]</td><td>Black and White</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item 2 has been inserted.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Explain</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&select=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Edit</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Execute']</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Explain</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>SCAN albums</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Reference</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&select=albums</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=1</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Michael Jackson</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Update</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&edit=albums&where%5Bid%5D=2</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[title]</td><td>Black or White</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Item has been updated.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Delete</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@name='check[]' and @value='where%5Bid%5D=2']</td><td></td></tr>
|
||||
<tr><td>waitForChecked</td><td>//input[@name='check[]' and @value='where%5Bid%5D=2']</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Are you sure?</td><td></td></tr>
|
||||
<tr><td>click</td><td>delete</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>1 item has been affected.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Truncate</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&select=albums</td><td></td></tr>
|
||||
<tr><td>click</td><td>all</td><td></td></tr>
|
||||
<tr><td>waitForChecked</td><td>all</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Are you sure?</td><td></td></tr>
|
||||
<tr><td>click</td><td>delete</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>No rows.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Export</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&dump=</td><td></td></tr>
|
||||
<tr><td>click</td><td>output</td><td></td></tr>
|
||||
<tr><td>click</td><td>format</td><td></td></tr>
|
||||
<tr><td>select</td><td>table_style</td><td>label=DROP+CREATE</td></tr>
|
||||
<tr><td>select</td><td>data_style</td><td>label=INSERT</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Export']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>CREATE TABLE "interprets"</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>CREATE TRIGGER "albums_ai"</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>INSERT INTO "interprets"</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>VIEW "albums_interprets"</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3" data-tags="">Generated columns</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&create=</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=name</td><td>generated</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1][field]</td><td>normal</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][field]</td><td>stored</td></tr>
|
||||
<tr><td>select</td><td>name=fields[1.1][generated]</td><td>label=STORED</td></tr>
|
||||
<tr><td>type</td><td>name=fields[1.1][default]</td><td>normal + 200</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>normal + 200</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Alter indexes</td><td></td></tr>
|
||||
<tr><td>select</td><td>name=indexes[1][columns][1]</td><td>label=stored</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Indexes have been altered.</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=New item</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[interpret]</td><td>1</td></tr>
|
||||
<tr><td>type</td><td>name=fields[title]</td><td>Dangerous</td></tr>
|
||||
<tr><td>click</td><td>css=input[type="submit"]</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=1</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Select: interprets</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=adminer_test.sqlite</td><td></td></tr>
|
||||
<tr><td>click</td><td>link=Alter database</td><td></td></tr>
|
||||
<tr><td>verifyTextNotPresent</td><td>stored</td><td></td></tr>
|
||||
<tr><td>type</td><td>name=fields[normal]</td><td>20</td></tr>
|
||||
<tr><td>click</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>220</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3">Variables</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&variables=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>integrity_check</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&status=</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>MAX_COLUMN</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<thead><tr><td rowspan="1" colspan="3" data-tags="">Drop</td></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php?sqlite=&username=ODBC&db=adminer_test.sqlite&database=</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop adminer_test.sqlite?</td><td></td></tr>
|
||||
<tr><td>click</td><td>name=drop</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Database has been dropped.</td><td></td></tr>
|
||||
<tr><td>click</td><td>id=logout</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Thanks for using Adminer, consider donating.</td><td></td></tr>
|
||||
</tbody></table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user