mirror of
https://github.com/vrana/adminer.git
synced 2025-09-05 04:01:48 +02:00
Compare commits
132 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 | ||
|
967647759e | ||
|
e4323ced55 | ||
|
85c6af6f87 | ||
|
9226804aa2 | ||
|
041e7064ca | ||
|
4c2a8b0050 | ||
|
9afbf1a465 | ||
|
352ef9c778 | ||
|
45107dc46e | ||
|
21f3426adb | ||
|
95dccfe9fb | ||
|
fe88f83c95 | ||
|
078957fe32 | ||
|
61f07867f9 | ||
|
0135dd5b81 | ||
|
773a2253d3 | ||
|
272042a30e | ||
|
48308f3357 | ||
|
c90033a962 | ||
|
8bd022f974 | ||
|
b1550b052d | ||
|
9862846a7c | ||
|
f14e3e38f6 | ||
|
95262c4215 | ||
|
dacfdc4608 | ||
|
7636c253fb | ||
|
44d26a9dd3 | ||
|
b229e7b583 | ||
|
8e91417be1 | ||
|
db7202fcf0 | ||
|
260487fbc2 | ||
|
3ae964c915 | ||
|
d56c8cbaae | ||
|
d347f88c54 | ||
|
b9b4db0c8e | ||
|
818b9ad903 | ||
|
4a6436773f | ||
|
81594e4a2d | ||
|
f0bdb0e6ca | ||
|
b9e4806d3c | ||
|
7e708dae57 | ||
|
a0fe44ec18 | ||
|
eb0f280776 | ||
|
3b1189cd3c | ||
|
434a8f7705 | ||
|
f9478c67d2 | ||
|
f2ce6c0a71 | ||
|
a50b3d6385 | ||
|
e39deca4f1 | ||
|
ce69970f54 | ||
|
51ac1312a1 | ||
|
4505544953 | ||
|
fa75213ff6 | ||
|
63acb37ea6 | ||
|
3ad6c16f59 | ||
|
22d08b4a50 | ||
|
dd3cc4e683 | ||
|
5504a617d0 | ||
|
2fdebfda29 | ||
|
dc2e945aef | ||
|
43d86287c4 | ||
|
a94a727af7 | ||
|
c2d29a6937 | ||
|
c082136558 | ||
|
7b1ea5fa2c | ||
|
156839142e | ||
|
2ee4e3b2e1 | ||
|
8b4c8b0156 | ||
|
9702878297 | ||
|
4a54648995 | ||
|
2e5027a1aa |
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -8,7 +8,7 @@ assignees: ''
|
||||
---
|
||||
|
||||
**Adminer version:** please use latest published or Git
|
||||
**Driver:** e.g. MySQL
|
||||
**Database version:** e.g. 10.1.48-MariaDB
|
||||
**Driver:** e.g. MySQLi
|
||||
**Database version:** e.g. 10.2.12-MariaDB
|
||||
|
||||
Please provide reproducible steps including a SQL dump (with no personal information) if applicable.
|
||||
|
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) {
|
||||
@@ -83,17 +83,18 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
|
||||
$partitioning = "";
|
||||
if (support("partitioning")) {
|
||||
if (isset($partition_by[$row["partition_by"]])) {
|
||||
$params = array_filter($row, function ($key) {
|
||||
return preg_match('~^partition~', $key);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
|
||||
$params = array();
|
||||
foreach ($row as $key => $val) {
|
||||
if (preg_match('~^partition~', $key)) {
|
||||
$params[$key] = $val;
|
||||
}
|
||||
}
|
||||
foreach ($params["partition_names"] as $key => $name) {
|
||||
if ($name == "") {
|
||||
unset($params["partition_names"][$key]);
|
||||
unset($params["partition_values"][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($params != get_partitions_info($TABLE)) {
|
||||
$partitions = array();
|
||||
if ($params["partition_by"] == 'RANGE' || $params["partition_by"] == 'LIST') {
|
||||
@@ -102,7 +103,6 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
|
||||
$partitions[] = "\n PARTITION " . idf_escape($name) . " VALUES " . ($params["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection
|
||||
}
|
||||
}
|
||||
|
||||
// $params["partition"] can be expression, not only column
|
||||
$partitioning .= "\nPARTITION BY $params[partition_by]($params[partition])";
|
||||
if ($partitions) {
|
||||
@@ -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),
|
||||
|
@@ -509,7 +509,16 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
|
||||
foreach ($comments as $key => $val) {
|
||||
$comment = substr($val, 9); // 9 - strlen(" COMMENT ")
|
||||
queries("EXEC sp_dropextendedproperty @name = N'MS_Description', @level0type = N'Schema', @level0name = " . q(get_schema()) . ", @level1type = N'Table', @level1name = " . q($name) . ", @level2type = N'Column', @level2name = " . q($key));
|
||||
queries("EXEC sp_addextendedproperty @name = N'MS_Description', @value = " . $comment . ", @level0type = N'Schema', @level0name = " . q(get_schema()) . ", @level1type = N'Table', @level1name = " . q($name) . ", @level2type = N'Column', @level2name = " . q($key));
|
||||
queries("EXEC sp_addextendedproperty
|
||||
@name = N'MS_Description',
|
||||
@value = $comment,
|
||||
@level0type = N'Schema',
|
||||
@level0name = " . q(get_schema()) . ",
|
||||
@level1type = N'Table',
|
||||
@level1name = " . q($name) . ",
|
||||
@level2type = N'Column',
|
||||
@level2name = " . q($key))
|
||||
;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@@ -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
|
||||
@@ -330,6 +330,13 @@ if (!defined('Adminer\DRIVER')) {
|
||||
}
|
||||
}
|
||||
|
||||
function unconvertFunction($field) {
|
||||
return (preg_match("~binary~", $field["type"]) ? "<code class='jush-sql'>UNHEX</code>"
|
||||
: ($field["type"] == "bit" ? doc_link(array('sql' => 'bit-value-literals.html'), "<code>b''</code>")
|
||||
: (preg_match("~geometry|point|linestring|polygon~", $field["type"]) ? "<code class='jush-sql'>GeomFromText</code>"
|
||||
: "")));
|
||||
}
|
||||
|
||||
function insert($table, $set) {
|
||||
return ($set ? parent::insert($table, $set) : queries("INSERT INTO " . table($table) . " ()\nVALUES ()"));
|
||||
}
|
||||
@@ -361,7 +368,7 @@ if (!defined('Adminer\DRIVER')) {
|
||||
|
||||
function slowQuery($query, $timeout) {
|
||||
if (min_version('5.7.8', '10.1.2')) {
|
||||
if (preg_match('~MariaDB~', $this->conn->server_info)) {
|
||||
if ($this->conn->maria) {
|
||||
return "SET STATEMENT max_statement_time=$timeout FOR $query";
|
||||
} elseif (preg_match('~^(SELECT\b)(.+)~is', $query, $match)) {
|
||||
return "$match[1] /*+ MAX_EXECUTION_TIME(" . ($timeout * 1000) . ") */ $match[2]";
|
||||
@@ -386,7 +393,7 @@ if (!defined('Adminer\DRIVER')) {
|
||||
}
|
||||
|
||||
function tableHelp($name, $is_view = false) {
|
||||
$maria = preg_match('~MariaDB~', $this->conn->server_info);
|
||||
$maria = $this->conn->maria;
|
||||
if (information_schema(DB)) {
|
||||
return strtolower("information-schema-" . ($maria ? "$name-table/" : str_replace("_", "-", $name) . "-table.html"));
|
||||
}
|
||||
@@ -428,10 +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;
|
||||
@@ -587,11 +597,11 @@ if (!defined('Adminer\DRIVER')) {
|
||||
|
||||
/** Get information about fields
|
||||
* @param string
|
||||
* @return array [$name => ["field" => , "full_type" => , "type" => , "length" => , "unsigned" => , "default" => , "null" => , "auto_increment" => , "on_update" => , "collation" => , "privileges" => , "comment" => , "primary" => , "generated" => ]]
|
||||
* @return array [$name => ["field" =>, "full_type" =>, "type" =>, "length" =>, "unsigned" =>, "default" =>, "null" =>, "auto_increment" =>, "on_update" =>, "collation" =>, "privileges" =>, "comment" =>, "primary" =>, "generated" =>]]
|
||||
*/
|
||||
function fields($table) {
|
||||
global $connection;
|
||||
$maria = preg_match('~MariaDB~', $connection->server_info);
|
||||
$maria = $connection->maria;
|
||||
$return = array();
|
||||
foreach (get_rows("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . q($table) . " ORDER BY ORDINAL_POSITION") as $row) {
|
||||
$field = $row["COLUMN_NAME"];
|
||||
@@ -600,27 +610,32 @@ if (!defined('Adminer\DRIVER')) {
|
||||
$extra = $row["EXTRA"];
|
||||
// https://mariadb.com/kb/en/library/show-columns/, https://github.com/vrana/adminer/pull/359#pullrequestreview-276677186
|
||||
preg_match('~^(VIRTUAL|PERSISTENT|STORED)~', $extra, $generated);
|
||||
preg_match('~^([^( ]+)(?:\((.+)\))?( unsigned)?( zerofill)?$~', $type, $match);
|
||||
preg_match('~^([^( ]+)(?:\((.+)\))?( unsigned)?( zerofill)?$~', $type, $match_type);
|
||||
$default = $row["COLUMN_DEFAULT"];
|
||||
$is_text = preg_match('~text~', $match[1]);
|
||||
if (!$maria && $is_text) {
|
||||
// default value a'b of text column is stored as _utf8mb4\'a\\\'b\' in MySQL
|
||||
$default = preg_replace("~^(_\w+)?('.*')$~", '\2', stripslashes($default));
|
||||
}
|
||||
if ($maria || $is_text) {
|
||||
$default = preg_replace_callback("~^'(.*)'$~", function ($match) {
|
||||
return stripslashes(str_replace("''", "'", $match[1]));
|
||||
}, $default);
|
||||
if ($default != "") {
|
||||
$is_text = preg_match('~text|json~', $match_type[1]);
|
||||
if (!$maria && $is_text) {
|
||||
// default value a'b of text column is stored as _utf8mb4\'a\\\'b\' in MySQL
|
||||
$default = preg_replace("~^(_\w+)?('.*')$~", '\2', stripslashes($default));
|
||||
}
|
||||
if ($maria || $is_text) {
|
||||
$default = ($default == "NULL" ? null : preg_replace_callback("~^'(.*)'$~", function ($match) {
|
||||
return stripslashes(str_replace("''", "'", $match[1]));
|
||||
}, $default));
|
||||
}
|
||||
if (!$maria && preg_match('~binary~', $match_type[1]) && preg_match('~^0x(\w*)$~', $default, $match)) {
|
||||
$default = pack("H*", $match[1]);
|
||||
}
|
||||
}
|
||||
$return[$field] = array(
|
||||
"field" => $field,
|
||||
"full_type" => $type,
|
||||
"type" => $match[1],
|
||||
"length" => $match[2],
|
||||
"unsigned" => ltrim($match[3] . $match[4]),
|
||||
"type" => $match_type[1],
|
||||
"length" => $match_type[2],
|
||||
"unsigned" => ltrim($match_type[3] . $match_type[4]),
|
||||
"default" => ($generated
|
||||
? ($maria ? $generation : stripslashes($generation))
|
||||
: ($default != "" || preg_match("~char|set~", $match[1]) ? $default : null)
|
||||
: $default
|
||||
),
|
||||
"null" => ($row["IS_NULLABLE"] == "YES"),
|
||||
"auto_increment" => ($extra == "auto_increment"),
|
||||
@@ -662,7 +677,12 @@ if (!defined('Adminer\DRIVER')) {
|
||||
$return = array();
|
||||
$create_table = get_val("SHOW CREATE TABLE " . table($table), 1);
|
||||
if ($create_table) {
|
||||
preg_match_all("~CONSTRAINT ($pattern) FOREIGN KEY ?\\(((?:$pattern,? ?)+)\\) REFERENCES ($pattern)(?:\\.($pattern))? \\(((?:$pattern,? ?)+)\\)(?: ON DELETE ($driver->onActions))?(?: ON UPDATE ($driver->onActions))?~", $create_table, $matches, PREG_SET_ORDER);
|
||||
preg_match_all(
|
||||
"~CONSTRAINT ($pattern) FOREIGN KEY ?\\(((?:$pattern,? ?)+)\\) REFERENCES ($pattern)(?:\\.($pattern))? \\(((?:$pattern,? ?)+)\\)(?: ON DELETE ($driver->onActions))?(?: ON UPDATE ($driver->onActions))?~",
|
||||
$create_table,
|
||||
$matches,
|
||||
PREG_SET_ORDER
|
||||
);
|
||||
foreach ($matches as $match) {
|
||||
preg_match_all("~$pattern~", $match[2], $source);
|
||||
preg_match_all("~$pattern~", $match[5], $target);
|
||||
@@ -806,7 +826,7 @@ if (!defined('Adminer\DRIVER')) {
|
||||
$default = $field[1][3];
|
||||
if (preg_match('~ GENERATED~', $default)) {
|
||||
// swap default and null
|
||||
$field[1][3] = (preg_match('~MariaDB~', $connection->server_info) ? "" : $field[1][2]); // MariaDB doesn't support NULL on virtual columns
|
||||
$field[1][3] = ($connection->maria ? "" : $field[1][2]); // MariaDB doesn't support NULL on virtual columns
|
||||
$field[1][2] = $default;
|
||||
}
|
||||
$alter[] = ($table != "" ? ($field[0] != "" ? "CHANGE " . idf_escape($field[0]) : "ADD") : " ") . " " . implode($field[1]) . ($table != "" ? $field[2] : "");
|
||||
@@ -982,7 +1002,9 @@ if (!defined('Adminer\DRIVER')) {
|
||||
global $driver;
|
||||
$aliases = array("bool", "boolean", "integer", "double precision", "real", "dec", "numeric", "fixed", "national char", "national varchar");
|
||||
$space = "(?:\\s|/\\*[\s\S]*?\\*/|(?:#|-- )[^\n]*\n?|--\r?\n)";
|
||||
$type_pattern = "((" . implode("|", array_merge(array_keys($driver->types()), $aliases)) . ")\\b(?:\\s*\\(((?:[^'\")]|$driver->enumLength)++)\\))?\\s*(zerofill\\s*)?(unsigned(?:\\s+zerofill)?)?)(?:\\s*(?:CHARSET|CHARACTER\\s+SET)\\s*['\"]?([^'\"\\s,]+)['\"]?)?";
|
||||
$enum = $driver->enumLength;
|
||||
$type_pattern = "((" . implode("|", array_merge(array_keys($driver->types()), $aliases)) . ")\\b(?:\\s*\\(((?:[^'\")]|$enum)++)\\))?"
|
||||
. "\\s*(zerofill\\s*)?(unsigned(?:\\s+zerofill)?)?)(?:\\s*(?:CHARSET|CHARACTER\\s+SET)\\s*['\"]?([^'\"\\s,]+)['\"]?)?";
|
||||
$pattern = "$space*(" . ($type == "FUNCTION" ? "" : $driver->inout) . ")?\\s*(?:`((?:[^`]|``)*)`\\s*|\\b(\\S+)\\s+)$type_pattern";
|
||||
$create = get_val("SHOW CREATE $type " . idf_escape($name), 2);
|
||||
preg_match("~\\(((?:$pattern\\s*,?)*)\\)\\s*" . ($type == "FUNCTION" ? "RETURNS\\s+$type_pattern\\s+" : "") . "(.*)~is", $create, $match);
|
||||
@@ -992,7 +1014,7 @@ if (!defined('Adminer\DRIVER')) {
|
||||
$fields[] = array(
|
||||
"field" => str_replace("``", "`", $param[2]) . $param[3],
|
||||
"type" => strtolower($param[5]),
|
||||
"length" => preg_replace_callback("~$driver->enumLength~s", 'Adminer\normalize_enum', $param[6]),
|
||||
"length" => preg_replace_callback("~$enum~s", 'Adminer\normalize_enum', $param[6]),
|
||||
"unsigned" => strtolower(preg_replace('~\s+~', ' ', trim("$param[8] $param[7]"))),
|
||||
"null" => 1,
|
||||
"full_type" => $param[4],
|
||||
@@ -1192,7 +1214,7 @@ if (!defined('Adminer\DRIVER')) {
|
||||
}
|
||||
|
||||
/** Check whether a feature is supported
|
||||
* @param string "check", "comment", "copy", "database", "descidx", "drop_col", "dump", "event", "indexes", "kill", "materializedview", "partitioning", "privileges", "procedure", "processlist", "routine", "scheme", "sequence", "status", "table", "trigger", "type", "variables", "view", "view_trigger"
|
||||
* @param string "check|comment|copy|database|descidx|drop_col|dump|event|indexes|kill|materializedview|partitioning|privileges|procedure|processlist|routine|scheme|sequence|status|table|trigger|type|variables|view|view_trigger"
|
||||
* @return bool
|
||||
*/
|
||||
function support($feature) {
|
||||
|
@@ -521,7 +521,16 @@ AND c_src.TABLE_NAME = " . q($table);
|
||||
}
|
||||
|
||||
function process_list() {
|
||||
return get_rows('SELECT sess.process AS "process", sess.username AS "user", sess.schemaname AS "schema", sess.status AS "status", sess.wait_class AS "wait_class", sess.seconds_in_wait AS "seconds_in_wait", sql.sql_text AS "sql_text", sess.machine AS "machine", sess.port AS "port"
|
||||
return get_rows('SELECT
|
||||
sess.process AS "process",
|
||||
sess.username AS "user",
|
||||
sess.schemaname AS "schema",
|
||||
sess.status AS "status",
|
||||
sess.wait_class AS "wait_class",
|
||||
sess.seconds_in_wait AS "seconds_in_wait",
|
||||
sql.sql_text AS "sql_text",
|
||||
sess.machine AS "machine",
|
||||
sess.port AS "port"
|
||||
FROM v$session sess LEFT OUTER JOIN v$sql sql
|
||||
ON sql.sql_id = sess.sql_id
|
||||
WHERE sess.type = \'USER\'
|
||||
|
@@ -43,17 +43,16 @@ if (isset($_GET["pgsql"])) {
|
||||
}
|
||||
|
||||
function quote($string) {
|
||||
return pg_escape_literal($this->link, $string);
|
||||
return (function_exists('pg_escape_literal')
|
||||
? pg_escape_literal($this->link, $string) // available since PHP 5.4.4
|
||||
: "'" . pg_escape_string($this->link, $string) . "'"
|
||||
);
|
||||
}
|
||||
|
||||
function value($val, $field) {
|
||||
return ($field["type"] == "bytea" && $val !== null ? pg_unescape_bytea($val) : $val);
|
||||
}
|
||||
|
||||
function quoteBinary($string) {
|
||||
return "'" . pg_escape_bytea($this->link, $string) . "'";
|
||||
}
|
||||
|
||||
function select_db($database) {
|
||||
global $adminer;
|
||||
if ($database == $adminer->database()) {
|
||||
@@ -173,10 +172,6 @@ if (isset($_GET["pgsql"])) {
|
||||
return ($adminer->database() == $database);
|
||||
}
|
||||
|
||||
function quoteBinary($s) {
|
||||
return q($s);
|
||||
}
|
||||
|
||||
function query($query, $unbuffered = false) {
|
||||
$return = parent::query($query, $unbuffered);
|
||||
if ($this->timeout) {
|
||||
@@ -283,7 +278,7 @@ if (isset($_GET["pgsql"])) {
|
||||
}
|
||||
|
||||
function quoteBinary($s) {
|
||||
return $this->conn->quoteBinary($s);
|
||||
return "'\\x" . bin2hex($s) . "'"; // available since PostgreSQL 8.1
|
||||
}
|
||||
|
||||
function warnings() {
|
||||
@@ -326,11 +321,18 @@ 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)) {
|
||||
$connection->query("SET application_name = 'Adminer'");
|
||||
}
|
||||
$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;
|
||||
@@ -432,7 +434,14 @@ WHERE relkind IN ('r', 'm', 'v', 'f', 'p')
|
||||
'timestamp with time zone' => 'timestamptz',
|
||||
);
|
||||
foreach (
|
||||
get_rows("SELECT a.attname AS field, format_type(a.atttypid, a.atttypmod) AS full_type, pg_get_expr(d.adbin, d.adrelid) AS default, a.attnotnull::int, col_description(c.oid, a.attnum) AS comment" . (min_version(10) ? ", a.attidentity" . (min_version(12) ? ", a.attgenerated" : "") : "") . "
|
||||
get_rows("SELECT
|
||||
a.attname AS field,
|
||||
format_type(a.atttypid, a.atttypmod) AS full_type,
|
||||
pg_get_expr(d.adbin, d.adrelid) AS default,
|
||||
a.attnotnull::int,
|
||||
col_description(c.oid, a.attnum) AS comment" . (min_version(10) ? ",
|
||||
a.attidentity" . (min_version(12) ? ",
|
||||
a.attgenerated" : "") : "") . "
|
||||
FROM pg_class c
|
||||
JOIN pg_namespace n ON c.relnamespace = n.oid
|
||||
JOIN pg_attribute a ON c.oid = a.attrelid
|
||||
@@ -460,7 +469,8 @@ ORDER BY a.attnum") as $row
|
||||
}
|
||||
$row["generated"] = ($row["attgenerated"] == "s" ? "STORED" : "");
|
||||
$row["null"] = !$row["attnotnull"];
|
||||
$row["auto_increment"] = $row['attidentity'] || preg_match('~^nextval\(~i', $row["default"]);
|
||||
$row["auto_increment"] = $row['attidentity'] || preg_match('~^nextval\(~i', $row["default"])
|
||||
|| preg_match('~^unique_rowid\(~', $row["default"]); // CockroachDB
|
||||
$row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1, "where" => 1, "order" => 1);
|
||||
if (preg_match('~(.+)::[^,)]+(.*)~', $row["default"], $match)) {
|
||||
$row["default"] = ($match[1] == "NULL" ? null : idf_unescape($match[1]) . $match[2]);
|
||||
@@ -478,7 +488,12 @@ ORDER BY a.attnum") as $row
|
||||
$return = array();
|
||||
$table_oid = $connection2->result("SELECT oid FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema()) AND relname = " . q($table));
|
||||
$columns = get_key_vals("SELECT attnum, attname FROM pg_attribute WHERE attrelid = $table_oid AND attnum > 0", $connection2);
|
||||
foreach (get_rows("SELECT relname, indisunique::int, indisprimary::int, indkey, indoption, (indpred IS NOT NULL)::int as indispartial FROM pg_index i, pg_class ci WHERE i.indrelid = $table_oid AND ci.oid = i.indexrelid ORDER BY indisprimary DESC, indisunique DESC", $connection2) as $row) {
|
||||
foreach (
|
||||
get_rows("SELECT relname, indisunique::int, indisprimary::int, indkey, indoption, (indpred IS NOT NULL)::int as indispartial
|
||||
FROM pg_index i, pg_class ci
|
||||
WHERE i.indrelid = $table_oid AND ci.oid = i.indexrelid
|
||||
ORDER BY indisprimary DESC, indisunique DESC", $connection2) as $row
|
||||
) {
|
||||
$relname = $row["relname"];
|
||||
$return[$relname]["type"] = ($row["indispartial"] ? "INDEX" : ($row["indisprimary"] ? "PRIMARY" : ($row["indisunique"] ? "UNIQUE" : "INDEX")));
|
||||
$return[$relname]["columns"] = array();
|
||||
@@ -698,7 +713,12 @@ ORDER BY conkey, conname") as $row
|
||||
$columns[] = $row["event_object_column"];
|
||||
}
|
||||
$return = array();
|
||||
foreach (get_rows('SELECT trigger_name AS "Trigger", action_timing AS "Timing", event_manipulation AS "Event", \'FOR EACH \' || action_orientation AS "Type", action_statement AS "Statement" FROM information_schema.triggers ' . "$where ORDER BY event_manipulation DESC") as $row) {
|
||||
foreach (
|
||||
get_rows('SELECT trigger_name AS "Trigger", action_timing AS "Timing", event_manipulation AS "Event", \'FOR EACH \' || action_orientation AS "Type", action_statement AS "Statement"
|
||||
FROM information_schema.triggers' . "
|
||||
$where
|
||||
ORDER BY event_manipulation DESC") as $row
|
||||
) {
|
||||
if ($columns && $row["Event"] == "UPDATE") {
|
||||
$row["Event"] .= " OF";
|
||||
}
|
||||
@@ -938,7 +958,11 @@ AND typelem = 0"
|
||||
}
|
||||
|
||||
function support($feature) {
|
||||
return preg_match('~^(check|database|table|columns|sql|indexes|descidx|comment|view|' . (min_version(9.3) ? 'materializedview|' : '') . 'scheme|routine|processlist|sequence|trigger|type|variables|drop_col|kill|dump)$~', $feature);
|
||||
global $connection;
|
||||
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) {
|
||||
|
@@ -78,7 +78,7 @@ if (isset($_GET["sqlite"])) {
|
||||
);
|
||||
}
|
||||
|
||||
function __desctruct() {
|
||||
function __destruct() {
|
||||
return $this->result->finalize();
|
||||
}
|
||||
}
|
||||
|
@@ -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");
|
||||
@@ -9,6 +17,9 @@ if ($_GET["file"] == "favicon.ico") {
|
||||
} elseif ($_GET["file"] == "default.css") {
|
||||
header("Content-Type: text/css; charset=utf-8");
|
||||
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;../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" type="text/css" 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
|
||||
@@ -289,13 +294,14 @@ class Adminer {
|
||||
* @return string
|
||||
*/
|
||||
function selectVal($val, $link, $field, $original) {
|
||||
$return = ($val === null ? "<i>NULL</i>" : (preg_match("~char|binary|boolean~", $field["type"]) && !preg_match("~var~", $field["type"]) ? "<code>$val</code>" : $val));
|
||||
$return = ($val === null ? "<i>NULL</i>"
|
||||
: (preg_match("~char|binary|boolean~", $field["type"]) && !preg_match("~var~", $field["type"]) ? "<code>$val</code>"
|
||||
: (preg_match('~json~', $field["type"]) ? "<code class='jush-js'>$val</code>"
|
||||
: $val)
|
||||
));
|
||||
if (preg_match('~blob|bytea|raw|file~', $field["type"]) && !is_utf8($val)) {
|
||||
$return = "<i>" . lang('%d byte(s)', strlen($original)) . "</i>";
|
||||
}
|
||||
if (preg_match('~json~', $field["type"])) {
|
||||
$return = "<code class='jush-js'>$return</code>";
|
||||
}
|
||||
return ($link ? "<a href='" . h($link) . "'" . (is_url($link) ? target_blank() : "") . ">$return</a>" : $return);
|
||||
}
|
||||
|
||||
@@ -987,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";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1011,31 +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";
|
||||
}
|
||||
}
|
||||
$server_info = $connection->server_info;
|
||||
?>
|
||||
bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '\1', $server_info) : ""); ?>'<?php echo (preg_match('~MariaDB~', $server_info) ? ", 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
|
||||
@@ -1076,14 +1088,14 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
|
||||
<?php
|
||||
hidden_fields_get();
|
||||
$db_events = script("mixin(qsl('select'), {onmousedown: dbMouseDown, onchange: dbChange});");
|
||||
echo "<span title='" . lang('Database') . "'>" . lang('DB') . "</span>: " . ($databases
|
||||
echo "<span title='" . lang('Database') . "'>" . lang('DB') . ":</span> " . ($databases
|
||||
? html_select("db", array("" => "") + $databases, DB) . $db_events
|
||||
: "<input name='db' value='" . h(DB) . "' autocapitalize='off' size='19'>\n"
|
||||
);
|
||||
echo "<input type='submit' value='" . lang('Use') . "'" . ($databases ? " class='hidden'" : "") . ">\n";
|
||||
if (support("scheme")) {
|
||||
if ($missing != "db" && DB != "" && $connection->select_db(DB)) {
|
||||
echo "<br>" . lang('Schema') . ": " . html_select("ns", array("" => "") + $adminer->schemas(), $_GET["ns"]) . $db_events;
|
||||
echo "<br><span>" . lang('Schema') . ":</span> " . html_select("ns", array("" => "") + $adminer->schemas(), $_GET["ns"]) . $db_events;
|
||||
if ($_GET["ns"] != "") {
|
||||
set_schema($_GET["ns"]);
|
||||
}
|
||||
|
@@ -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"])));
|
||||
}
|
||||
@@ -62,7 +66,6 @@ if (function_exists("get_magic_quotes_runtime") && get_magic_quotes_runtime()) {
|
||||
set_magic_quotes_runtime(false);
|
||||
}
|
||||
@set_time_limit(0); // @ - can be disabled
|
||||
@ini_set("zend.ze1_compatibility_mode", false); // @ - deprecated
|
||||
@ini_set("precision", 15); // @ - can be disabled, 15 - internal PHP precision
|
||||
|
||||
include "../adminer/include/lang.inc.php";
|
||||
@@ -73,9 +76,9 @@ include "../adminer/drivers/sqlite.inc.php";
|
||||
include "../adminer/drivers/pgsql.inc.php";
|
||||
include "../adminer/drivers/oracle.inc.php";
|
||||
include "../adminer/drivers/mssql.inc.php";
|
||||
include "../adminer/drivers/mongo.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);
|
||||
|
@@ -8,7 +8,13 @@ if (isset($_GET["import"])) {
|
||||
$_GET["sql"] = $_GET["import"];
|
||||
}
|
||||
|
||||
if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]) || isset($_GET["variables"]) || $_GET["script"] == "connect" || $_GET["script"] == "kill")) {
|
||||
if (
|
||||
!(DB != ""
|
||||
? $connection->select_db(DB)
|
||||
: isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]) || isset($_GET["variables"])
|
||||
|| $_GET["script"] == "connect" || $_GET["script"] == "kill"
|
||||
)
|
||||
) {
|
||||
if (DB != "" || $_GET["refresh"]) {
|
||||
restart_session();
|
||||
set_session("dbs", null);
|
||||
|
@@ -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) {
|
||||
|
@@ -28,19 +28,25 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
|
||||
<meta name="robots" content="noindex">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title><?php echo $title_page; ?></title>
|
||||
<link rel="stylesheet" type="text/css" href="../adminer/static/default.css">
|
||||
<?php echo script_src("../adminer/static/functions.js"); ?>
|
||||
<?php 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 foreach ($adminer->css() as $css) { ?>
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo h($css); ?>">
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
|
||||
<body class="<?php echo lang('ltr'); ?> nojs">
|
||||
<link rel="stylesheet" href="../adminer/static/default.css">
|
||||
<?php
|
||||
$css = $adminer->css();
|
||||
$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");
|
||||
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));
|
||||
@@ -58,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> » ';
|
||||
|
@@ -66,6 +66,13 @@ abstract class SqlDriver {
|
||||
function enumLength($field) {
|
||||
}
|
||||
|
||||
/** Function used to convert the value inputted by user
|
||||
* @param array
|
||||
* @return string or null
|
||||
*/
|
||||
function unconvertFunction($field) {
|
||||
}
|
||||
|
||||
/** Select data from table
|
||||
* @param string
|
||||
* @param array result of $adminer->selectColumnsProcess()[0]
|
||||
|
@@ -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,19 +194,24 @@ 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 ($collations ? "<input list='collations' name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . " value='" . h($field["collation"]) . "' placeholder='(" . lang('collation') . ")'>" : '');
|
||||
echo "</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') . ")'>"
|
||||
: ''
|
||||
);
|
||||
echo ($driver->unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist($driver->unsigned, $field["unsigned"]) . '</select>' : '');
|
||||
echo (isset($field['on_update']) ? "<select name='" . h($key) . "[on_update]'" . (preg_match('~timestamp|datetime~', $type) ? "" : " class='hidden'") . '>'
|
||||
. optionlist(array("" => "(" . lang('ON UPDATE') . ")", "CURRENT_TIMESTAMP"), (preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"]) ? "CURRENT_TIMESTAMP" : $field["on_update"]))
|
||||
. '</select>' : ''
|
||||
);
|
||||
echo ($foreign_keys ? "<select name='" . h($key) . "[on_delete]'" . (preg_match("~`~", $type) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", $driver->onActions), $field["on_delete"]) . "</select> " : " "); // space for IE
|
||||
echo ($foreign_keys
|
||||
? "<select name='" . h($key) . "[on_delete]'" . (preg_match("~`~", $type) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", $driver->onActions), $field["on_delete"]) . "</select> "
|
||||
: " " // space for IE
|
||||
);
|
||||
}
|
||||
|
||||
/** Get partition info
|
||||
@@ -307,8 +288,8 @@ function default_value($field) {
|
||||
$generated = $field["generated"];
|
||||
return ($default === null ? "" : (in_array($generated, $driver->generated)
|
||||
? (JUSH == "mssql" ? " AS ($default)" . ($generated == "VIRTUAL" ? "" : " $generated") . "" : " GENERATED ALWAYS AS ($default) $generated")
|
||||
: " DEFAULT " . (!preg_match('~^GENERATED ~i', $default) && (preg_match('~char|binary|text|enum|set~', $field["type"]) || preg_match('~^(?![a-z])~i', $default))
|
||||
? (JUSH == "sql" && preg_match('~text~', $field["type"]) ? "(" . q($default) . ")" : q($default)) // MySQL requires () around default value of text column
|
||||
: " DEFAULT " . (!preg_match('~^GENERATED ~i', $default) && (preg_match('~char|binary|text|json|enum|set~', $field["type"]) || preg_match('~^(?![a-z])~i', $default))
|
||||
? (JUSH == "sql" && preg_match('~text|json~', $field["type"]) ? "(" . q($default) . ")" : q($default)) // MySQL requires () around default value of text column
|
||||
: str_ireplace("current_timestamp()", "CURRENT_TIMESTAMP", (JUSH == "sqlite" ? "($default)" : $default))
|
||||
)
|
||||
));
|
||||
@@ -343,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>";
|
||||
@@ -624,7 +602,7 @@ function doc_link($paths, $text = "<sup>?</sup>") {
|
||||
'mssql' => "https://learn.microsoft.com/en-us/sql/",
|
||||
'oracle' => "https://www.oracle.com/pls/topic/lookup?ctx=db" . preg_replace('~^.* (\d+)\.(\d+)\.\d+\.\d+\.\d+.*~s', '\1\2', $server_info) . "&id=",
|
||||
);
|
||||
if (preg_match('~MariaDB~', $server_info)) {
|
||||
if ($connection->maria) {
|
||||
$urls['sql'] = "https://mariadb.com/kb/en/";
|
||||
$paths['sql'] = (isset($paths['mariadb']) ? $paths['mariadb'] : str_replace(".html", "/", $paths['sql']));
|
||||
}
|
||||
|
@@ -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
|
||||
@@ -459,14 +302,14 @@ function where($where, $fields = array()) {
|
||||
foreach ((array) $where["where"] as $key => $val) {
|
||||
$key = bracket_escape($key, 1); // 1 - back
|
||||
$column = escape_key($key);
|
||||
$field_type = $fields[$key]["type"];
|
||||
$return[] = $column
|
||||
. (JUSH == "sql" && $fields[$key]["type"] == "json" ? " = CAST(" . q($val) . " AS JSON)"
|
||||
. (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" ? " LIKE " . q(preg_replace('~[_%[]~', '[\0]', $val)) // LIKE because of text
|
||||
: " = " . unconvert_field($fields[$key], q($val))
|
||||
)))
|
||||
: (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)))))
|
||||
; //! enum and set
|
||||
if (JUSH == "sql" && preg_match('~char|text~', $fields[$key]["type"]) && preg_match("~[^ -@]~", $val)) { // not just [a-z] to catch non-ASCII characters
|
||||
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";
|
||||
}
|
||||
}
|
||||
@@ -536,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
|
||||
*/
|
||||
@@ -720,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
|
||||
@@ -832,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
|
||||
@@ -887,172 +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;
|
||||
}
|
||||
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
|
||||
*/
|
||||
@@ -1078,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
|
||||
@@ -1166,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;
|
||||
}
|
||||
|
||||
@@ -1186,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);
|
||||
}
|
||||
@@ -1196,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;
|
||||
}
|
||||
@@ -1315,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();
|
||||
@@ -1388,123 +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;
|
||||
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];
|
||||
}
|
||||
}
|
||||
$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 ($field["auto_increment"] || $function == "now" || $function == "uuid") {
|
||||
$first++;
|
||||
}
|
||||
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
|
||||
@@ -74,9 +76,9 @@ function lang($idf, $number = null) {
|
||||
: ($LANG == 'sl' ? ($number % 100 == 1 ? 0 : ($number % 100 == 2 ? 1 : ($number % 100 == 3 || $number % 100 == 4 ? 2 : 3))) // different forms for 1, 2, 3-4, other
|
||||
: ($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
|
||||
: ($LANG == 'bs' || $LANG == 'ru' || $LANG == 'sr' || $LANG == '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
|
||||
: (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
|
||||
$translation = $translation[$pos];
|
||||
}
|
||||
$args = func_get_args();
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
$VERSION = "5.0.3";
|
||||
$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">
|
||||
|
@@ -302,4 +302,10 @@ $translations = array(
|
||||
'Unknown error.' => 'Unbekannter Fehler.',
|
||||
'Database does not support password.' => 'Die Datenbank unterstützt kein Passwort.',
|
||||
'Disable %s or enable %s or %s extensions.' => 'Deaktivieren Sie %s oder aktivieren Sie die Erweiterungen %s oder %s.',
|
||||
'Check has been dropped.' => 'Check wurde abgebrochen.',
|
||||
'Check has been altered.' => 'Check wurde geändert.',
|
||||
'Check has been created.' => 'Check wurde erstellt.',
|
||||
'Alter check' => 'Check ändern',
|
||||
'Create check' => 'Check erstellen',
|
||||
'Checks' => 'Checks',
|
||||
);
|
||||
|
@@ -74,7 +74,9 @@ foreach ($schema as $name => $table) {
|
||||
$left1 = $left - $table_pos[$name][1];
|
||||
$i = 0;
|
||||
foreach ($ref[0] as $source) {
|
||||
echo "\n<div class='references' title='" . h($target_name) . "' id='refs$left-" . ($i++) . "' style='left: $left1" . "em; top: " . $table["fields"][$source]["pos"] . "em; padding-top: .5em;'><div style='border-top: 1px solid Gray; width: " . (-$left1) . "em;'></div></div>";
|
||||
echo "\n<div class='references' title='" . h($target_name) . "' id='refs$left-" . ($i++) . "' style='left: $left1" . "em; top: " . $table["fields"][$source]["pos"] . "em; padding-top: .5em;'>"
|
||||
. "<div style='border-top: 1px solid gray; width: " . (-$left1) . "em;'></div></div>"
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,8 +86,9 @@ foreach ($schema as $name => $table) {
|
||||
$left1 = $left - $table_pos[$name][1];
|
||||
$i = 0;
|
||||
foreach ($columns as $target) {
|
||||
echo "\n<div class='references' title='" . h($target_name) . "' id='refd$left-" . ($i++) . "' style='left: $left1" . "em; top: " . $table["fields"][$target]["pos"] . "em; height: 1.25em; background: url(../adminer/static/arrow.gif) no-repeat right center;'>"
|
||||
. "<div style='height: .5em; border-bottom: 1px solid Gray; width: " . (-$left1) . "em;'></div>"
|
||||
echo "\n<div class='references' title='" . h($target_name) . "' id='refd$left-" . ($i++) . "'"
|
||||
. " style='left: $left1" . "em; top: " . $table["fields"][$target]["pos"] . "em; height: 1.25em; background: url(../adminer/static/arrow.gif) no-repeat right center;'>"
|
||||
. "<div style='height: .5em; border-bottom: 1px solid gray; width: " . (-$left1) . "em;'></div>"
|
||||
. "</div>"
|
||||
;
|
||||
}
|
||||
@@ -106,7 +109,7 @@ foreach ($schema as $name => $table) {
|
||||
$min_pos = min($min_pos, $pos1, $pos2);
|
||||
$max_pos = max($max_pos, $pos1, $pos2);
|
||||
}
|
||||
echo "<div class='references' id='refl$left' style='left: $left" . "em; top: $min_pos" . "em; padding: .5em 0;'><div style='border-right: 1px solid Gray; margin-top: 1px; height: " . ($max_pos - $min_pos) . "em;'></div></div>\n";
|
||||
echo "<div class='references' id='refl$left' style='left: $left" . "em; top: $min_pos" . "em; padding: .5em 0;'><div style='border-right: 1px solid gray; margin-top: 1px; height: " . ($max_pos - $min_pos) . "em;'></div></div>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ if ($_GET["script"] == "db") {
|
||||
$sums[$key] += ($table_status["Engine"] != "InnoDB" || $key != "Data_free" ? $table_status[$key] : 0);
|
||||
}
|
||||
} elseif (array_key_exists($key, $table_status)) {
|
||||
json_row("$key-$name");
|
||||
json_row("$key-$name", "?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
@@ -452,8 +452,8 @@ if (!$columns && support("table")) {
|
||||
$id = h("val[$unique_idf][" . bracket_escape($key) . "]");
|
||||
$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|lob~', $field["type"]);
|
||||
echo "<td id='$id'";
|
||||
$text = preg_match('~text|json|lob~', $field["type"]);
|
||||
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];
|
||||
|
46
adminer/static/dark.css
Normal file
46
adminer/static/dark.css
Normal file
@@ -0,0 +1,46 @@
|
||||
/** @author Robert Mesaros, https://www.rmsoft.sk */
|
||||
|
||||
body { color: #829bb0; background: #002240; }
|
||||
a { color: #517fa8; }
|
||||
a:visited { color: #517fa8; }
|
||||
a:link:hover, a:visited:hover { color: #9bc0e1; }
|
||||
h1 { border-color: #5e94c1; color: #ffddbf; background: #154269; }
|
||||
h2 { border-color: #a3bdd3; color: #000; background: #3c678d; }
|
||||
td, th { border-color: #0e416d; }
|
||||
th { background: #11385a; }
|
||||
thead td, thead th { color: #a8b05f; background: #011d35; }
|
||||
thead th a { color: #a8b05f; }
|
||||
fieldset { border-color: #16548a; }
|
||||
code { background: #11385a; }
|
||||
tbody tr:hover td, tbody tr:hover th { background: #133553; }
|
||||
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; }
|
||||
.js .column { background: #011d35; }
|
||||
.error { color: red; background: #efdada; border: 1px solid #e76f6f; }
|
||||
.error b { background: #002240; }
|
||||
.message { color: #0b860b; background: #efe; border: 1px solid #7fbd7f; }
|
||||
.message table { color: #829bb0; background: #002240; }
|
||||
.char { color: #a949a9; }
|
||||
.date { color: #59c159; }
|
||||
.enum { color: #d55c5c; }
|
||||
.binary { color: #9bc0e1; }
|
||||
.odds tbody tr:nth-child(2n) { background: #042541; }
|
||||
.js .checkable .checked td, .js .checkable .checked th { background: #10395c; color: #67a4a5; }
|
||||
.js .checkable .checked:hover td, .js .checkable .checked:hover th { background: #133553; }
|
||||
.js .checkable .checked a { color: #67a4a5; }
|
||||
.icon { background-color: #062642; }
|
||||
.icon:hover { background-color: #d1394e; }
|
||||
.footer { border-top-color: rgba(0, 34, 64, .7); border-image-source: linear-gradient(rgba(0, 34, 64, 0.2), #002240); }
|
||||
.footer > div { background: #002240; }
|
||||
#menu p, #logins, #tables { border-color: #326b9c; }
|
||||
#logins a, #tables a, #tables span { background: #002240; }
|
||||
#breadcrumb { background: #154269; }
|
||||
#h1 { color: #ffddbf; }
|
||||
#version { color: #d2b397; }
|
||||
#schema .table { border-color: #093459; }
|
||||
#help { border-color: #666; background: #c7e4fe; }
|
||||
#schema div.table a { color: #3c7bb3; }
|
||||
#menu .active { color: #398c8d; }
|
||||
#edit-fields tbody tr:hover td, #edit-fields tbody tr:hover th { background: #3b6f9d; }
|
@@ -1,4 +1,5 @@
|
||||
/** @author Ondrej Valka, http://valka.info */
|
||||
|
||||
body { color: #000; background: #fff; font: 90%/1.25 Verdana, Arial, Helvetica, sans-serif; margin: 0; min-width: fit-content; }
|
||||
a { color: blue; text-decoration: none; }
|
||||
a:visited { color: navy; }
|
||||
@@ -25,12 +26,12 @@ pre { margin: 1em 0 0; }
|
||||
td pre { margin: 0; }
|
||||
pre, textarea { font: 100%/1.25 monospace; }
|
||||
pre.jush { background: #fff; }
|
||||
pre code { display: block; }
|
||||
input, textarea { box-sizing: border-box; }
|
||||
input, select { vertical-align: middle; }
|
||||
input[type="radio"] { vertical-align: text-bottom; }
|
||||
input.default { box-shadow: 1px 1px 1px #777; }
|
||||
input.required { box-shadow: 1px 1px 1px red; }
|
||||
input.maxlength { box-shadow: 1px 1px 1px red; }
|
||||
input.required, input.maxlength { box-shadow: 1px 1px 1px red; }
|
||||
input.wayoff { left: -1000px; position: absolute; }
|
||||
.block { display: block; }
|
||||
.version { color: #777; font-size: 62%; }
|
||||
@@ -47,12 +48,10 @@ input.wayoff { left: -1000px; position: absolute; }
|
||||
.date { color: #7F007F; }
|
||||
.enum { color: #007F7F; }
|
||||
.binary { color: red; }
|
||||
.odds tbody tr:nth-child(2n) td { background: #F5F5F5; }
|
||||
.odds tbody tr:nth-child(2n) { background: #F5F5F5; }
|
||||
.js .checkable .checked td, .js .checkable .checked th { background: #ddf; }
|
||||
.time { color: silver; font-size: 70%; }
|
||||
.function { text-align: right; }
|
||||
.number { text-align: right; }
|
||||
.datetime { text-align: right; }
|
||||
.function, .number, .datetime { text-align: right; }
|
||||
.type { width: 15ex; }
|
||||
.options select, .options input { width: 20ex; }
|
||||
.view { font-style: italic; }
|
||||
|
@@ -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 : '')
|
||||
|
@@ -568,7 +568,7 @@ function functionChange() {
|
||||
* @this HTMLTableCellElement
|
||||
*/
|
||||
function skipOriginal(first) {
|
||||
var fnSelect = this.previousSibling.firstChild;
|
||||
var fnSelect = qs('select', this.previousSibling);
|
||||
if (fnSelect.selectedIndex < first) {
|
||||
fnSelect.selectedIndex = first;
|
||||
}
|
||||
@@ -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
|
||||
|
@@ -45,7 +45,11 @@ if (!is_view($table_status)) {
|
||||
foreach ($foreign_keys as $name => $foreign_key) {
|
||||
echo "<tr title='" . h($name) . "'>";
|
||||
echo "<th><i>" . implode("</i>, <i>", array_map('Adminer\h', $foreign_key["source"])) . "</i>";
|
||||
echo "<td><a href='" . h($foreign_key["db"] != "" ? preg_replace('~db=[^&]*~', "db=" . urlencode($foreign_key["db"]), ME) : ($foreign_key["ns"] != "" ? preg_replace('~ns=[^&]*~', "ns=" . urlencode($foreign_key["ns"]), ME) : ME)) . "table=" . urlencode($foreign_key["table"]) . "'>"
|
||||
$link = ($foreign_key["db"] != ""
|
||||
? preg_replace('~db=[^&]*~', "db=" . urlencode($foreign_key["db"]), ME)
|
||||
: ($foreign_key["ns"] != "" ? preg_replace('~ns=[^&]*~', "ns=" . urlencode($foreign_key["ns"]), ME) : ME)
|
||||
);
|
||||
echo "<td><a href='" . h($link . "table=" . urlencode($foreign_key["table"])) . "'>"
|
||||
. ($foreign_key["db"] != "" && $foreign_key["db"] != DB ? "<b>" . h($foreign_key["db"]) . "</b>." : "")
|
||||
. ($foreign_key["ns"] != "" && $foreign_key["ns"] != $_GET["ns"] ? "<b>" . h($foreign_key["ns"]) . "</b>." : "")
|
||||
. h($foreign_key["table"])
|
||||
|
@@ -148,7 +148,10 @@ echo "<table class='odds'>\n";
|
||||
echo "<thead><tr><th colspan='2'>" . lang('Privileges') . doc_link(array('sql' => "grant.html#priv_level"));
|
||||
$i = 0;
|
||||
foreach ($grants as $object => $grant) {
|
||||
echo '<th>' . ($object != "*.*" ? "<input name='objects[$i]' value='" . h($object) . "' size='10' autocapitalize='off'>" : "<input type='hidden' name='objects[$i]' value='*.*' size='10'>*.*"); //! separate db, table, columns, PROCEDURE|FUNCTION, routine
|
||||
echo '<th>' . ($object != "*.*"
|
||||
? "<input name='objects[$i]' value='" . h($object) . "' size='10' autocapitalize='off'>"
|
||||
: "<input type='hidden' name='objects[$i]' value='*.*' size='10'>*.*"
|
||||
); //! separate db, table, columns, PROCEDURE|FUNCTION, routine
|
||||
$i++;
|
||||
}
|
||||
echo "</thead>\n";
|
||||
|
294
changes.txt
294
changes.txt
@@ -1,9 +1,37 @@
|
||||
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 SF-218)
|
||||
CockroachDB: Display version
|
||||
CockroachDB: Recognize unique_rowid() as auto_increment
|
||||
MS SQL: Fix editing rows with datetime column in primary key
|
||||
MongoDB: Move to plugin
|
||||
CSS: Add dark theme
|
||||
|
||||
Adminer 5.0.4 (released 2025-03-11):
|
||||
Compile: Fix shortening in private methods (regression from 5.0.3)
|
||||
|
||||
Adminer 5.0.3 (released 2025-03-11):
|
||||
Fix gzip export (bug #896, regression from 5.0.0)
|
||||
Fix importing multiple SQL files not terminated by semicolon
|
||||
Use <datalist> for altering collations
|
||||
MySQL: Allow setting default values of text column
|
||||
MySQL: Stop treating enum and set as numbers (bug #475)
|
||||
MySQL: 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)
|
||||
@@ -13,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
|
||||
@@ -45,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
|
||||
@@ -67,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
|
||||
|
||||
@@ -155,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
|
||||
@@ -187,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
|
||||
@@ -209,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@
|
||||
@@ -223,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
|
||||
|
||||
@@ -239,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
|
||||
@@ -280,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
|
||||
@@ -301,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):
|
||||
@@ -329,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
|
||||
@@ -355,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
|
||||
@@ -402,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)
|
||||
@@ -449,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
|
||||
@@ -466,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
|
||||
@@ -479,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
|
||||
@@ -549,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
|
||||
@@ -560,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):
|
||||
@@ -573,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
|
||||
@@ -598,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
|
||||
@@ -687,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
|
||||
@@ -703,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
|
||||
|
||||
@@ -733,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
|
||||
@@ -748,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)
|
||||
@@ -760,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
|
||||
@@ -784,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
|
||||
@@ -798,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
|
||||
|
||||
@@ -811,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
|
||||
@@ -862,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)
|
||||
@@ -891,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)
|
||||
@@ -910,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
|
||||
|
||||
@@ -966,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):
|
||||
@@ -974,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
|
||||
@@ -1053,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):
|
||||
|
207
compile.php
207
compile.php
@@ -3,6 +3,7 @@
|
||||
include __DIR__ . "/adminer/include/version.inc.php";
|
||||
include __DIR__ . "/adminer/include/errors.inc.php";
|
||||
include __DIR__ . "/externals/JsShrink/jsShrink.php";
|
||||
include __DIR__ . "/externals/PhpShrink/phpShrink.php";
|
||||
|
||||
function add_apo_slashes($s) {
|
||||
return addcslashes($s, "\\'");
|
||||
@@ -36,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")),
|
||||
@@ -88,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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,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];
|
||||
}
|
||||
@@ -212,129 +198,8 @@ if (!$translations) {
|
||||
';
|
||||
}
|
||||
|
||||
function short_identifier($number, $chars) {
|
||||
$return = '';
|
||||
while ($number >= 0) {
|
||||
$return .= $chars[$number % strlen($chars)];
|
||||
$number = floor($number / strlen($chars)) - 1;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
// based on http://latrine.dgx.cz/jak-zredukovat-php-skripty
|
||||
function php_shrink($input) {
|
||||
global $VERSION;
|
||||
$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;
|
||||
$token[1] = substr_replace($token[1], "* @version $VERSION\n", -2, 0);
|
||||
}
|
||||
if ($token[0] == T_VAR || $token[0] == T_PUBLIC || $token[0] == T_PROTECTED || $token[0] == T_PRIVATE) {
|
||||
if ($token[0] == T_PUBLIC && $tokens[$i+2][1][0] == '$') {
|
||||
$token[1] = 'var';
|
||||
}
|
||||
$shortening = false;
|
||||
} elseif (!$shortening) {
|
||||
if ($token[1] == ';') {
|
||||
$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 minify_css($file) {
|
||||
return lzw_compress(preg_replace('~\s*([:;{},])\s*~', '\1', preg_replace('~/\*.*\*/~sU', '', $file)));
|
||||
return lzw_compress(preg_replace('~\s*([:;{},])\s*~', '\1', preg_replace('~/\*.*?\*/\s*~s', '', $file)));
|
||||
}
|
||||
|
||||
function minify_js($file) {
|
||||
@@ -359,14 +224,6 @@ function compile_file($match) {
|
||||
return '"' . add_quo_slashes($file) . '"';
|
||||
}
|
||||
|
||||
if (!function_exists("each")) {
|
||||
function each(&$arr) {
|
||||
$key = key($arr);
|
||||
next($arr);
|
||||
return $key === null ? false : array($key, $arr[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
function min_version() {
|
||||
return true;
|
||||
}
|
||||
@@ -385,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"]);
|
||||
}
|
||||
|
||||
@@ -411,11 +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");
|
||||
if ($driver) {
|
||||
$_GET[$driver] = true; // to load the driver
|
||||
$file = preg_replace('~\*/~', "* @version $VERSION\n*/", $file, 1);
|
||||
if ($vendor) {
|
||||
$_GET[$vendor] = true; // to load the driver
|
||||
include_once __DIR__ . $driver_path;
|
||||
foreach ($features as $key => $feature) {
|
||||
if (!Adminer\support($feature)) {
|
||||
@@ -431,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 ($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);
|
||||
@@ -472,18 +334,19 @@ if ($_SESSION["lang"]) {
|
||||
$file = str_replace("switch_lang();", "", $file);
|
||||
$file = str_replace('<?php echo $LANG; ?>', $_SESSION["lang"], $file);
|
||||
}
|
||||
$file = str_replace('<?php echo script_src("static/editing.js"); ?>' . "\n", "", $file);
|
||||
$file = preg_replace('~\s+echo script_src\("\.\./externals/jush/modules/jush-(textarea|txt|js|" \. JUSH \. ")\.js"\);~', '', $file);
|
||||
$file = str_replace('<link rel="stylesheet" type="text/css" href="../externals/jush/jush.css">' . "\n", "", $file);
|
||||
$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 = 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 = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $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";
|
||||
|
33
coverage.php
33
coverage.php
@@ -1,13 +1,14 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="cs">
|
||||
<!DOCTYPE html>
|
||||
<html lang="cs">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>Coverage</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<?php
|
||||
include "./adminer/include/errors.inc.php";
|
||||
|
||||
function xhtml_open_tags($s) {
|
||||
// returns array of opened tags in $s
|
||||
$return = array();
|
||||
@@ -22,19 +23,20 @@ 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.</p>\n";
|
||||
echo "<p class='error'>Xdebug has to be enabled.\n";
|
||||
} elseif ($_GET["coverage"] === "0") {
|
||||
file_put_contents($coverage_filename, serialize(array()));
|
||||
echo "<p class='message'>Coverage started.</p>\n";
|
||||
} elseif (preg_match('~^(adminer|editor)/(include/)?[-_.a-z0-9]+$~i', $_GET["coverage"])) {
|
||||
echo "<p class='message'>Coverage started.\n";
|
||||
} elseif (preg_match('~^(adminer|editor)/(include/|drivers/)?[-_.a-z0-9]+$~i', $_GET["coverage"])) {
|
||||
// highlight single file
|
||||
$filename = $_GET["coverage"];
|
||||
$coverage = (file_exists($coverage_filename) ? unserialize(file_get_contents($coverage_filename)) : array());
|
||||
$file = explode("<br />", highlight_file($filename, true));
|
||||
$file = explode("\n", substr(highlight_file($filename, true), 5, -6)); // unwrap <pre></pre>
|
||||
$prev_color = null;
|
||||
$s = "";
|
||||
echo "<pre>";
|
||||
for ($l=0; $l <= count($file); $l++) {
|
||||
$line = $file[$l];
|
||||
$color = "#C0FFC0"; // tested
|
||||
@@ -58,31 +60,28 @@ if (!extension_loaded("xdebug")) {
|
||||
foreach (array_reverse($open_tags) as $tag) {
|
||||
echo "</" . preg_replace('~ .*~', '', $tag) . ">";
|
||||
}
|
||||
echo "</div>\n";
|
||||
echo "</div>";
|
||||
$s = ($open_tags ? "<" . implode("><", $open_tags) . ">" : "");
|
||||
$prev_color = $color;
|
||||
}
|
||||
$s .= "$line<br />\n";
|
||||
$s .= "$line\n";
|
||||
}
|
||||
echo "</pre>";
|
||||
} else {
|
||||
if (file_exists($coverage_filename)) {
|
||||
// display list of files
|
||||
$coverage = unserialize(file_get_contents($coverage_filename));
|
||||
echo "<table border='1' cellspacing='0'>\n";
|
||||
foreach (array_merge(glob("adminer/*.php"), glob("adminer/include/*.php"), glob("editor/*.php"), glob("editor/include/*.php")) as $filename) {
|
||||
foreach (array_merge(glob("adminer/*.php"), glob("adminer/drivers/*.php"), glob("adminer/include/*.php"), glob("editor/*.php"), glob("editor/include/*.php")) as $filename) {
|
||||
$cov = $coverage[realpath($filename)];
|
||||
$ratio = 0;
|
||||
if (is_array($cov)) {
|
||||
$values = array_count_values($cov);
|
||||
$ratio = round(100 - 100 * $values[-1] / (count($cov) - $values[-2]));
|
||||
}
|
||||
echo "<tr><td align='right' style='background-color: " . ($ratio < 50 ? "Red" : ($ratio < 75 ? "#FFEA20" : "#A7FC9D")) . ";'>$ratio%</td><td><a href='coverage.php?coverage=$filename'>$filename</a></td></tr>\n";
|
||||
echo "<tr><td align='right' style='background-color: " . ($ratio < 50 ? "Red" : ($ratio < 75 ? "#FFEA20" : "#A7FC9D")) . ";'>$ratio%<td><a href='coverage.php?coverage=$filename'>$filename</a>\n";
|
||||
}
|
||||
echo "</table>\n";
|
||||
}
|
||||
echo "<p><a href='coverage.php?coverage=0'>Start new coverage</a></p>\n";
|
||||
echo "<p><a href='coverage.php?coverage=0'>Start new coverage</a>\n";
|
||||
}
|
||||
?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -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) td,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;}
|
@@ -112,7 +112,7 @@ border-bottom: 1px #BBB solid;
|
||||
thead tr:hover td, thead tr:hover th {
|
||||
background-color: #DDD !important;
|
||||
}
|
||||
tr:nth-child(2n) td, tr:nth-child(2n) th, .odd td, .odd th, tr.odd {
|
||||
tr:nth-child(2n) td, tr:nth-child(2n) th {
|
||||
background-color: #F1F1F1;
|
||||
}
|
||||
tr:hover td, tr:hover th {
|
||||
|
@@ -175,8 +175,7 @@
|
||||
background: var(--color-darkPurple);
|
||||
}
|
||||
|
||||
.odds tbody tr:nth-child(2n) th,
|
||||
.odds tbody tr:nth-child(2n) td {
|
||||
.odds tbody tr:nth-child(2n) {
|
||||
background: var(--color-darkDraculaVSCode);
|
||||
}
|
||||
|
@@ -133,7 +133,7 @@ th {
|
||||
background:white;
|
||||
}
|
||||
|
||||
.odds tbody tr:nth-child(2n) td {
|
||||
.odds tbody tr:nth-child(2n) {
|
||||
background:#fcfaf5;
|
||||
}
|
||||
|
||||
|
@@ -72,7 +72,7 @@ tr:first-child th {padding-right: 30px;}
|
||||
td:first-child, th:first-child {border-left-width: 0;}
|
||||
thead td, thead th {background-color: #DFDFDF; border: none; border-bottom: 1px #BBB solid;}
|
||||
thead tr:hover td, thead tr:hover th {background-color: #DDD !important;}
|
||||
tr:nth-child(2n) td, tr:nth-child(2n) th, .odds tbody tr:nth-child(2n) td, .odds tbody tr:nth-child(2n) th, .odds tbody tr:nth-child(2n) {background-color: #F1F1F1;}
|
||||
tr:nth-child(2n) td, tr:nth-child(2n) th, .odds tbody tr:nth-child(2n), .odds tbody tr:nth-child(2n):not(.checked, :hover) {background-color: #F1F1F1;}
|
||||
tr:hover td, tr:hover th {background-color: #BCD;}
|
||||
fieldset {display: inline; vertical-align: top; padding: 2px 12px; margin: 25px 12px 12px 0; border: none; background-color: #F1F1F1; border: 1px solid #E3E3E3; position: relative;}
|
||||
fieldset, x:-moz-any-link {padding-top: 4px;}
|
||||
|
@@ -378,7 +378,7 @@ thead td abbr, thead td sup, thead th acronym, thead th sup {
|
||||
color: #cdf
|
||||
}
|
||||
|
||||
.odds tbody tr:nth-child(2n) td {
|
||||
.odds tbody tr:nth-child(2n) {
|
||||
background: #fcfaf5
|
||||
}
|
||||
|
||||
|
@@ -153,7 +153,7 @@ th, td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.odds tbody tr:nth-child(2n) th, .odds tbody tr:nth-child(2n) td {
|
||||
.odds tbody tr:nth-child(2n) {
|
||||
background: #FCFAF5;
|
||||
}
|
||||
|
||||
|
@@ -132,7 +132,7 @@ th {
|
||||
background:white;
|
||||
}
|
||||
|
||||
.odds tbody tr:nth-child(2n) td {
|
||||
.odds tbody tr:nth-child(2n) {
|
||||
background:#fcfaf5;
|
||||
}
|
||||
|
||||
|
@@ -187,7 +187,7 @@ td.nowrap {
|
||||
.binary {
|
||||
color: red;
|
||||
}
|
||||
.odds tbody tr:nth-child(2n) td {
|
||||
.odds tbody tr:nth-child(2n) {
|
||||
background: transparent;
|
||||
}
|
||||
.js .checkable .checked td,
|
||||
|
@@ -169,7 +169,7 @@ th {
|
||||
background:white;
|
||||
}
|
||||
|
||||
.odds tbody tr:nth-child(2n) td {
|
||||
.odds tbody tr:nth-child(2n) {
|
||||
background:#fcfaf5;
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ th {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
|
||||
#content tbody tr.checked td, .odds tbody tr:nth-child(2n).checked td {
|
||||
#content tbody tr.checked td {
|
||||
background:#fbe2e2;
|
||||
color:red;
|
||||
}
|
||||
|
@@ -65,7 +65,7 @@ thead td, thead th {
|
||||
border-bottom: 1px #DDD solid; }
|
||||
.nowrap tr:nth-child(2n) td, .nowrap tr:nth-child(2n) th {
|
||||
background-color: #DEF; }
|
||||
.odds tbody tr:nth-child(2n) td, .odds tbody tr:nth-child(2n) th {
|
||||
.odds tbody tr:nth-child(2n) {
|
||||
background-color: #DEF; } /* IEx */
|
||||
tr.selected td, tr.selected th {
|
||||
background-color: #ABC !important; }
|
||||
|
@@ -136,8 +136,7 @@ table.checkable tbody tr:hover th {
|
||||
background: #bfb008;
|
||||
}
|
||||
|
||||
.odds tbody tr:nth-child(2n) th,
|
||||
.odds tbody tr:nth-child(2n) td {
|
||||
.odds tbody tr:nth-child(2n) {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
|
@@ -58,7 +58,7 @@ table{-moz-border-bottom-colors:none;-moz-border-left-colors:none;-moz-border-ri
|
||||
td,th{-moz-border-bottom-colors:none;-moz-border-left-colors:none;-moz-border-right-colors:none;-moz-border-top-colors:none;border-color:-moz-use-text-color #999 #999 -moz-use-text-color;border-image:none;border-style:none solid solid none;border-width:0 1px 1px 0;padding:.2em .3em}
|
||||
thead td,thead th{background:#eee;background:-moz-linear-gradient(top,#eee 0,#ccc 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#eee),color-stop(100%,#ccc));background:-webkit-linear-gradient(top,#eee 0,#ccc 100%);background:-o-linear-gradient(top,#eee 0,#ccc 100%);background:-ms-linear-gradient(top,#eee 0,#ccc 100%);background:linear-gradient(to bottom,#eee 0,#ccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee',endColorstr='#cccccc',GradientType=0)}
|
||||
td{background-color:#f4f8ff}
|
||||
.odds tbody tr:nth-child(2n) td{background-color:#fff}
|
||||
.odds tbody tr:nth-child(2n){background-color:#fff}
|
||||
tbody tr:hover td,tbody tr:hover th{background-color:#FFE}
|
||||
p.tabs{margin:0 20px 0 0}
|
||||
.jush-sql{background:0}
|
||||
@@ -70,6 +70,7 @@ a:hover{color:#28c}
|
||||
#logout:hover,#logins a:hover,#tables a:hover,#breadcrumb a:hover,.logout a:hover,.tabs a:hover{color:#fff;text-decoration:none;background:#93c9ff;background:-moz-linear-gradient(top,#93c9ff 0,#79b8f7 44%,#57a2ed 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#93c9ff),color-stop(44%,#79b8f7),color-stop(100%,#57a2ed));background:-webkit-linear-gradient(top,#93c9ff 0,#79b8f7 44%,#57a2ed 100%);background:-o-linear-gradient(top,#93c9ff 0,#79b8f7 44%,#57a2ed 100%);background:-ms-linear-gradient(top,#93c9ff 0,#79b8f7 44%,#57a2ed 100%);background:linear-gradient(to bottom,#93c9ff 0,#79b8f7 44%,#57a2ed 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#93c9ff',endColorstr='#57a2ed',GradientType=0)}
|
||||
#breadcrumb a,#breadcrumb a:link{border:1px solid #246;padding:2px 6px;margin:1px auto;line-height:1.6em}
|
||||
#logins a,#tables a{background:none repeat scroll 0 0 #fff;padding:2px 6px;margin:1px 0;font-size:.8em}
|
||||
#lang{top:-4.5em;}
|
||||
a[title='Show structure'],#tables a[title='Show structure']{border:0;background:0;color:#369}
|
||||
.jush a{border:0;background:0;margin:0;padding:0}
|
||||
a.active,a.active:link,a.active:hover{text-decoration:underline}
|
||||
|
@@ -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.
|
||||
|
@@ -2,8 +2,8 @@
|
||||
* @package Adminer.css - Theme CSS for Adminer --- [theme light] gray - orange B (with icons)
|
||||
*
|
||||
*//*!
|
||||
* @version 4.17.1.2
|
||||
* @date Thu, 27 Feb 2025 09:28:32 +0100
|
||||
* @version 5.0.4.1
|
||||
* @date Wed, 12 Mar 2025 21:35:32 +0100
|
||||
* @author Robert Mesaros
|
||||
* @copyright Copyright 2025 Robert Mesaros, rmSOFT, Slovakia
|
||||
* @web https://www.rmsoft.sk
|
||||
@@ -35,10 +35,6 @@
|
||||
* Modified icons by Robert Mesaros
|
||||
*
|
||||
*/
|
||||
#menu{padding:0 0 30px 0}
|
||||
.ltr .logout{right:0;left:auto;margin-top:.5em}
|
||||
.rtl .logout{left:0;right:auto;margin-top:.5em}
|
||||
.rtl table.layout tbody{direction:ltr}
|
||||
html{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}
|
||||
*,*:before,*:after{box-sizing:inherit}
|
||||
body{color:#000;background:#f0f0f0;font-family:Verdana,Arial,Helvetica,sans-serif;font-weight:normal;cursor:default;margin:0}
|
||||
@@ -49,6 +45,9 @@ img{width:100%;max-width:100%}
|
||||
#menu #h1{margin-left:10px}
|
||||
#menu h1{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozNDA3NDEwQ0Y0MkQxMUVGODA4RUNENTRFQzJENUU4RCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozNDA3NDEwQkY0MkQxMUVGODA4RUNENTRFQzJENUU4RCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRTREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Ph59M4AAAAPFSURBVHja7JZrSFNRHMDvvVvq1mNlucBK0g/lh+Us6oPrU0ERRFgRUqYUVEb2qTJ0vko0ZbMHiBT0sizSXEUfJGzN1CjBQLPCR/RwSYKp23RO3e527/r/57mxxpblhCD8w59z7t2553f+zx36Ulk5FYxkZpyiijVahUgkqnc62cu5arUGXrMl2tIkhmGuu91uGp4HXre0qB490A3C3IXfMVSQojl/QQYAHUzlNtvYPBhl2Xn5672gqBFxSmXF0WPpCTCfg+/EwUDBwkixeM4TmqZjzSbTFU1J8W00RiaTtUxMTJSfzctFd4Yq49eGJ6ekNETHxGyG50jQkWDAcoA+BqjSbDaXA/QqvBtFBWg6QGuJtSaapr7jB7AWrV0C6pguWAZurIeNFCaTqUxbUnwd3lkRAjoO0JswStApEGs1jJs4jusw9vTcEcI7LTBA3wA02mI2X/WFgvIIxCQC6EmIdQ7P898qb1Xs7O7qGiVrWWaa4C5PZopEy6RSKQfTYS8oRUYO1i3Hh4e6mlSA2sjhLHgwMdkoA04lI1noV8BVn/Nzsu/iFHTP2cIiHSTR9tNZaqYgP28/iecv4nA4ajmXi7NYLKPkcFbiDYomdcxNVVoul6s9JytzC/mYWxEVtfDQkbQKiUSyw26368/k5iTBexvZSxA0bD4Zx0An0E4B3Nfz5cu+zs4OJ+tgQwOBlfHxcSujo7MHBwfTLpZq69Cdq2NjFyWnpFaGhYVtA3hdU2PD4ecGQ78AhxjnQi6o29va1lVX3TNibAUwniSyq7PT+qKxcQjmduEHX0lQqSIgUZaOj4+FwyM2ipEP3d1msHRvQdG5GoQnqDYWAviEYDmErw/G1t7e3hAYQwiY+tm5Pn36aCdusATS+QsWDOBa8ArWInqGga6FltnQzcPDlrKvRmMTKSMRroXQ3AXd3fzq5ZCvQZ7kOnb8ONQXbYd+6/pNmBd70pXnfHPBAy8pKsojUNYruzmSEwzp0e5fwNCBFIFc7CXMZHbzIn9JT9wrJA/nVVasv8084PvVVVvftLbavIPvK6kHDqoUa9Zc+03J8V6WTike8FzpXJ4UtzUQOEIux98oCAdHzYCIJzsQw5M6s0LC+D01NIPxmQQz1D+SWfAs+D8FO1mn6w9uHUJ90zPSQOAvcdWOxERD4q5dSwjA/0KxuNmg1294/+7tGLlFuIOy+NbNG0b4s3YSSwIqyzr4Z/qnlv7+/iE/N42/FjokJBQ3lmI7JteUQK5E0Ajp6fZgLUaw0LNDp7juuomL2WCtRfkhwACjULOQ0RiwkAAAAABJRU5ErkJggg==");background-repeat:no-repeat}
|
||||
#menu h1:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQUNCOTdFQkY0MkQxMUVGOUM0OUMyQTRDNjAyNzhENiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQUNCOTdFQUY0MkQxMUVGOUM0OUMyQTRDNjAyNzhENiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRTREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pq1mg9cAAAQtSURBVHja7JZdTFxFFIDP3J9dCgqUQimQIlBSWNoCNfVBYmo0jX9Jg014aYrWFzWGRl9MTHzpiy8k2kbrm9qUWtMaY9S2RqV9ADQm9o/+pHsvhW5Lw8/iLu6PC9yfvTOeWWbbC9ktlPWRk5ydvWfmzjfnzJkzlxz+7HNYSpIeD1QEAtB2+kew8vKgwdXn9Wsw1uR7tQTg+zhjfRs0fTeazWCT71ARwLt8jANgn0nMNO+9d+82nw6VSZCj3PE1VhcDnJIBpDnG8tC0TmvYvC8N5YJ9yq6C/L4/6je9jo8eVJITOMjY9lJCdBUdn6D0Sq0+9B6alTpZ7okwNrjGrzWjPnkwHO4oJKR8h8fzJfaXcLiUA3TLWkJ+x+WvQeglhL6N5jhqZIqxbyo1vQP/z6GOW5QN8nfI/KtrOVhZLogwllIuE4xVo6eXEJo3TumFOn2oS0D/Rv23WtPfxPYxVCvU5DuL41pMAOOWbf+ENu4sWR4YgUlVBUdRQHIcKJPlEQyvGqT02mLofC6BhRrFBPuhEOAZG20HJoOvHItEJtEeQ7WXFWrFtmGq+gm4+NLL6DUF23Ei3O4hpLRKVXkY/nFBRSKDjUlVxR8+Coc7BTSEGuZZr8w7xN6nlBZhS7LBqWHc3n/kyAkxaV2osWG4RJKqrtRvOluu6S0PtvCBxCg9iZtsBSwrJBYXEdFgKTAhpFuW5aW8v4p6RoTV7Bwb23F848aLxYRUhn2NN0o13Sf6kukX6vWhT7E5zoMm+mwOTTGxgIzfCQT2+v03bcu0vNmoLa2tzTW1tR+GpsNvHeru/pVP0FlcXHG4YsMFflSweEwdjUaf/2AyeEtEhWFincMM2/XzzOxzHaOjf6HNSIP5Sio1vz8+0NcXdncslqfb2sokSSqfTSRKRMbGTkSjE6hb0GM/h+8rKvoOwTtFAiUtxkYNQqI3TYNHkztlusEwMjJsiDMXzQZ+vLCQZy1gVFQxiWQ+u9P29g/EMMxNdxsbfhm2rH4+FHWWg6s0/QC2B0W1WjBvCvxOV9fXGHUD9zn5kD1el0oy6tzPhdM1tQD9A/ydWI0+9KKA8uShYogtkkpKJ9UCsKKoW7N56pIU0HGonDaMtG4H6OkBkVBxETUmgOljNZfxiPKfb0+dfGHw8uXE4lW55bX9b7Rt3bbtC/eR4wXFJY7rHC9dG/hPQX4BD820WHVGcNn69fHUTSPL9ydXDWPFF0wKLMkSB89wcPfHn9BMA03TnF0MxgKwYnDO9/EqeBW8Cl4Ati07ufTXD0ufb/J/gBW8Ejfvbm8/375nT6kAZB6oKH+e7+196sb1azPuC33FHh87+tVd/AKxhSdZ1bJMeq73t0gwGOT3duJR6nLGr1aPx8snzuflWFxr2ULpiAt++mEfDI8CTtdsb7p2Z9tmEWIrV2+5/CfAAOVxxSK4gGWJAAAAAElFTkSuQmCC")}
|
||||
.rtl table.layout tbody td{display:flex}
|
||||
.rtl table.layout~table thead th:first-child,.rtl table.layout~table tbody td:first-child{text-align:right !important}
|
||||
.rtl table.layout~table thead th:last-child,.rtl table.layout~table tbody td:last-child{text-align:left !important}
|
||||
h1{padding:.6em .4em;background:#c60;border:1px solid #894501;text-align:left}
|
||||
#h1{color:#fff}
|
||||
.version{color:#ddd;margin-left:8px}
|
||||
@@ -99,7 +98,7 @@ code{background:#f0d6d6;padding:.2em .5em}
|
||||
table code{font-size:130%;background:#f5e8ce;padding:.1em .3em}
|
||||
code.jush-sql{background:#f0e8d6}
|
||||
.rtl p code.jush-sql{background-position:right;clear:right;float:right}
|
||||
pre.sqlarea{background:#e0e0e0;padding:5px}
|
||||
pre{background:#e0e0e0 !important;padding:5px}
|
||||
textarea{font-size:120%}
|
||||
.ltr p.count{font-size:90%;margin:.8em 20px 8px 0}
|
||||
.rtl p.count{font-size:90%;margin:.8em 0 8px 20px}
|
||||
@@ -119,12 +118,12 @@ table{border-spacing:0}
|
||||
table,td,th{border:0;border-collapse:separate}
|
||||
.ltr table{margin:1.9em 0 0 0}
|
||||
.rtl table{margin:1.9em 0 0 0}
|
||||
.rtl table tbody td,.rtl table tbody th{text-align:right}
|
||||
.rtl table tbody td,.rtl table tbody th{text-align:right !important}
|
||||
.ltr table thead td:first-child,.ltr table thead th:first-child{border-left:1px solid #999}
|
||||
.rtl table thead td:first-child,.rtl table thead th:first-child{border-right:1px solid #999}
|
||||
table thead td,table thead th{height:1.6em;border-top:1px solid #999;border-bottom:1px solid #999}
|
||||
.ltr table thead td,.ltr table thead th{border-right:1px solid #999}
|
||||
.rtl table thead td,.rtl table thead th{border-left:1px solid #999;text-align:right !important}
|
||||
.rtl table thead td,.rtl table thead th{border-left:1px solid #999}
|
||||
table tbody tr:first-child td,table tbody tr:first-child th{border-top:1px solid #999}
|
||||
.ltr table tbody td:first-child,.ltr table tbody th:first-child{border-left:1px solid #999}
|
||||
.rtl table tbody td:first-child,.rtl table tbody th:first-child{border-right:1px solid #999}
|
||||
@@ -421,9 +420,12 @@ input[type=radio]{margin-bottom:5px}
|
||||
.rtl input[type=checkbox],.rtl input[type=radio],.rtl input[type=range],.rtl progress{margin-left:5px}
|
||||
.ltr input[type=submit]{margin-right:10px}
|
||||
.rtl input[type=submit]{margin-left:10px}
|
||||
.ltr table.layout label,.ltr label.jsonly{margin-left:8px}
|
||||
.rtl table.layout label,.rtl label.jsonly{margin-right:8px}
|
||||
input,button,select,.sqlarea{border-radius:3px}
|
||||
.sqlarea{background:#e0e0e0;font-size:105%}
|
||||
fieldset a{line-height:unset}
|
||||
input[type=submit]{padding:2px 6px}
|
||||
.ltr table.layout label,.ltr label.jsonly{margin-left:8px}
|
||||
.rtl table.layout label,.rtl label.jsonly{margin-right:8px}
|
||||
#menu{padding:0 0 30px 0}
|
||||
.ltr .logout{right:0;left:auto;margin-top:.5em}
|
||||
.rtl .logout{left:0;right:auto;margin-top:.5em}
|
||||
|
@@ -2,8 +2,8 @@
|
||||
* @package Adminer.css - Theme CSS for Adminer --- [theme dark] blue B (with icons)
|
||||
*
|
||||
*//*!
|
||||
* @version 4.17.1.2
|
||||
* @date Thu, 27 Feb 2025 09:28:32 +0100
|
||||
* @version 5.0.4.1
|
||||
* @date Wed, 12 Mar 2025 21:35:32 +0100
|
||||
* @author Robert Mesaros
|
||||
* @copyright Copyright 2025 Robert Mesaros, rmSOFT, Slovakia
|
||||
* @web https://www.rmsoft.sk
|
||||
@@ -35,10 +35,6 @@
|
||||
* Modified icons by Robert Mesaros
|
||||
*
|
||||
*/
|
||||
#menu{padding:0 0 30px 0}
|
||||
.ltr .logout{right:0;left:auto;margin-top:.5em}
|
||||
.rtl .logout{left:0;right:auto;margin-top:.5em}
|
||||
.rtl table.layout tbody{direction:ltr}
|
||||
html{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}
|
||||
*,*:before,*:after{box-sizing:inherit}
|
||||
body{color:#829bb0;background:#002240;font-family:Verdana,Arial,Helvetica,sans-serif;font-weight:normal;cursor:default;margin:0}
|
||||
@@ -50,6 +46,9 @@ img{width:100%;max-width:100%}
|
||||
#menu h1{background-color:#1d4e78}
|
||||
#menu h1{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozNDA3NDEwQ0Y0MkQxMUVGODA4RUNENTRFQzJENUU4RCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozNDA3NDEwQkY0MkQxMUVGODA4RUNENTRFQzJENUU4RCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRTREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Ph59M4AAAAPFSURBVHja7JZrSFNRHMDvvVvq1mNlucBK0g/lh+Us6oPrU0ERRFgRUqYUVEb2qTJ0vko0ZbMHiBT0sizSXEUfJGzN1CjBQLPCR/RwSYKp23RO3e527/r/57mxxpblhCD8w59z7t2553f+zx36Ulk5FYxkZpyiijVahUgkqnc62cu5arUGXrMl2tIkhmGuu91uGp4HXre0qB490A3C3IXfMVSQojl/QQYAHUzlNtvYPBhl2Xn5672gqBFxSmXF0WPpCTCfg+/EwUDBwkixeM4TmqZjzSbTFU1J8W00RiaTtUxMTJSfzctFd4Yq49eGJ6ekNETHxGyG50jQkWDAcoA+BqjSbDaXA/QqvBtFBWg6QGuJtSaapr7jB7AWrV0C6pguWAZurIeNFCaTqUxbUnwd3lkRAjoO0JswStApEGs1jJs4jusw9vTcEcI7LTBA3wA02mI2X/WFgvIIxCQC6EmIdQ7P898qb1Xs7O7qGiVrWWaa4C5PZopEy6RSKQfTYS8oRUYO1i3Hh4e6mlSA2sjhLHgwMdkoA04lI1noV8BVn/Nzsu/iFHTP2cIiHSTR9tNZaqYgP28/iecv4nA4ajmXi7NYLKPkcFbiDYomdcxNVVoul6s9JytzC/mYWxEVtfDQkbQKiUSyw26368/k5iTBexvZSxA0bD4Zx0An0E4B3Nfz5cu+zs4OJ+tgQwOBlfHxcSujo7MHBwfTLpZq69Cdq2NjFyWnpFaGhYVtA3hdU2PD4ecGQ78AhxjnQi6o29va1lVX3TNibAUwniSyq7PT+qKxcQjmduEHX0lQqSIgUZaOj4+FwyM2ipEP3d1msHRvQdG5GoQnqDYWAviEYDmErw/G1t7e3hAYQwiY+tm5Pn36aCdusATS+QsWDOBa8ArWInqGga6FltnQzcPDlrKvRmMTKSMRroXQ3AXd3fzq5ZCvQZ7kOnb8ONQXbYd+6/pNmBd70pXnfHPBAy8pKsojUNYruzmSEwzp0e5fwNCBFIFc7CXMZHbzIn9JT9wrJA/nVVasv8084PvVVVvftLbavIPvK6kHDqoUa9Zc+03J8V6WTike8FzpXJ4UtzUQOEIux98oCAdHzYCIJzsQw5M6s0LC+D01NIPxmQQz1D+SWfAs+D8FO1mn6w9uHUJ90zPSQOAvcdWOxERD4q5dSwjA/0KxuNmg1294/+7tGLlFuIOy+NbNG0b4s3YSSwIqyzr4Z/qnlv7+/iE/N42/FjokJBQ3lmI7JteUQK5E0Ajp6fZgLUaw0LNDp7juuomL2WCtRfkhwACjULOQ0RiwkAAAAABJRU5ErkJggg==");background-repeat:no-repeat;mix-blend-mode:difference}
|
||||
#menu h1:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQUNCOTdFQkY0MkQxMUVGOUM0OUMyQTRDNjAyNzhENiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQUNCOTdFQUY0MkQxMUVGOUM0OUMyQTRDNjAyNzhENiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRTREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pq1mg9cAAAQtSURBVHja7JZdTFxFFIDP3J9dCgqUQimQIlBSWNoCNfVBYmo0jX9Jg014aYrWFzWGRl9MTHzpiy8k2kbrm9qUWtMaY9S2RqV9ADQm9o/+pHsvhW5Lw8/iLu6PC9yfvTOeWWbbC9ktlPWRk5ydvWfmzjfnzJkzlxz+7HNYSpIeD1QEAtB2+kew8vKgwdXn9Wsw1uR7tQTg+zhjfRs0fTeazWCT71ARwLt8jANgn0nMNO+9d+82nw6VSZCj3PE1VhcDnJIBpDnG8tC0TmvYvC8N5YJ9yq6C/L4/6je9jo8eVJITOMjY9lJCdBUdn6D0Sq0+9B6alTpZ7okwNrjGrzWjPnkwHO4oJKR8h8fzJfaXcLiUA3TLWkJ+x+WvQeglhL6N5jhqZIqxbyo1vQP/z6GOW5QN8nfI/KtrOVhZLogwllIuE4xVo6eXEJo3TumFOn2oS0D/Rv23WtPfxPYxVCvU5DuL41pMAOOWbf+ENu4sWR4YgUlVBUdRQHIcKJPlEQyvGqT02mLofC6BhRrFBPuhEOAZG20HJoOvHItEJtEeQ7WXFWrFtmGq+gm4+NLL6DUF23Ei3O4hpLRKVXkY/nFBRSKDjUlVxR8+Coc7BTSEGuZZr8w7xN6nlBZhS7LBqWHc3n/kyAkxaV2osWG4RJKqrtRvOluu6S0PtvCBxCg9iZtsBSwrJBYXEdFgKTAhpFuW5aW8v4p6RoTV7Bwb23F848aLxYRUhn2NN0o13Sf6kukX6vWhT7E5zoMm+mwOTTGxgIzfCQT2+v03bcu0vNmoLa2tzTW1tR+GpsNvHeru/pVP0FlcXHG4YsMFflSweEwdjUaf/2AyeEtEhWFincMM2/XzzOxzHaOjf6HNSIP5Sio1vz8+0NcXdncslqfb2sokSSqfTSRKRMbGTkSjE6hb0GM/h+8rKvoOwTtFAiUtxkYNQqI3TYNHkztlusEwMjJsiDMXzQZ+vLCQZy1gVFQxiWQ+u9P29g/EMMxNdxsbfhm2rH4+FHWWg6s0/QC2B0W1WjBvCvxOV9fXGHUD9zn5kD1el0oy6tzPhdM1tQD9A/ydWI0+9KKA8uShYogtkkpKJ9UCsKKoW7N56pIU0HGonDaMtG4H6OkBkVBxETUmgOljNZfxiPKfb0+dfGHw8uXE4lW55bX9b7Rt3bbtC/eR4wXFJY7rHC9dG/hPQX4BD820WHVGcNn69fHUTSPL9ydXDWPFF0wKLMkSB89wcPfHn9BMA03TnF0MxgKwYnDO9/EqeBW8Cl4Ati07ufTXD0ufb/J/gBW8Ejfvbm8/375nT6kAZB6oKH+e7+196sb1azPuC33FHh87+tVd/AKxhSdZ1bJMeq73t0gwGOT3duJR6nLGr1aPx8snzuflWFxr2ULpiAt++mEfDI8CTtdsb7p2Z9tmEWIrV2+5/CfAAOVxxSK4gGWJAAAAAElFTkSuQmCC");mask-image:linear-gradient(black, transparent);-webkit-mask-image:linear-gradient(black, transparent);mix-blend-mode:unset;background-color:unset}
|
||||
.rtl table.layout tbody td{display:flex}
|
||||
.rtl table.layout~table thead th:first-child,.rtl table.layout~table tbody td:first-child{text-align:right !important}
|
||||
.rtl table.layout~table thead th:last-child,.rtl table.layout~table tbody td:last-child{text-align:left !important}
|
||||
h1{padding:.6em .4em;background:#1d4e78;border:1px solid #f2ddaf;text-align:left}
|
||||
#h1{color:#fff}
|
||||
.version{color:#ddd;margin-left:8px}
|
||||
@@ -100,7 +99,7 @@ code{background:#81a0bc;padding:.2em .5em}
|
||||
table code{font-size:130%;background:#154167;padding:.1em .3em}
|
||||
code.jush-sql{background:#c5d8e9}
|
||||
.rtl p code.jush-sql{background-position:right;clear:right;float:right}
|
||||
pre.sqlarea{background:#a7c3dc;padding:5px}
|
||||
pre{background:#a7c3dc !important;padding:5px}
|
||||
textarea{font-size:120%}
|
||||
.ltr p.count{font-size:90%;margin:.8em 20px 8px 0}
|
||||
.rtl p.count{font-size:90%;margin:.8em 0 8px 20px}
|
||||
@@ -120,12 +119,12 @@ table{border-spacing:0}
|
||||
table,td,th{border:0;border-collapse:separate}
|
||||
.ltr table{margin:1.9em 0 0 0}
|
||||
.rtl table{margin:1.9em 0 0 0}
|
||||
.rtl table tbody td,.rtl table tbody th{text-align:right}
|
||||
.rtl table tbody td,.rtl table tbody th{text-align:right !important}
|
||||
.ltr table thead td:first-child,.ltr table thead th:first-child{border-left:1px solid #1e5687}
|
||||
.rtl table thead td:first-child,.rtl table thead th:first-child{border-right:1px solid #1e5687}
|
||||
table thead td,table thead th{height:1.6em;border-top:1px solid #1e5687;border-bottom:1px solid #1e5687}
|
||||
.ltr table thead td,.ltr table thead th{border-right:1px solid #1e5687}
|
||||
.rtl table thead td,.rtl table thead th{border-left:1px solid #1e5687;text-align:right !important}
|
||||
.rtl table thead td,.rtl table thead th{border-left:1px solid #1e5687}
|
||||
table tbody tr:first-child td,table tbody tr:first-child th{border-top:1px solid #1e5687}
|
||||
.ltr table tbody td:first-child,.ltr table tbody th:first-child{border-left:1px solid #1e5687}
|
||||
.rtl table tbody td:first-child,.rtl table tbody th:first-child{border-right:1px solid #1e5687}
|
||||
@@ -422,9 +421,12 @@ input[type=radio]{margin-bottom:5px}
|
||||
.rtl input[type=checkbox],.rtl input[type=radio],.rtl input[type=range],.rtl progress{margin-left:5px}
|
||||
.ltr input[type=submit]{margin-right:10px}
|
||||
.rtl input[type=submit]{margin-left:10px}
|
||||
.ltr table.layout label,.ltr label.jsonly{margin-left:8px}
|
||||
.rtl table.layout label,.rtl label.jsonly{margin-right:8px}
|
||||
input,button,select,.sqlarea{border-radius:3px}
|
||||
.sqlarea{background:#a7c3dc;font-size:105%}
|
||||
fieldset a{line-height:unset}
|
||||
input[type=submit]{padding:2px 6px}
|
||||
.ltr table.layout label,.ltr label.jsonly{margin-left:8px}
|
||||
.rtl table.layout label,.rtl label.jsonly{margin-right:8px}
|
||||
#menu{padding:0 0 30px 0}
|
||||
.ltr .logout{right:0;left:auto;margin-top:.5em}
|
||||
.rtl .logout{left:0;right:auto;margin-top:.5em}
|
@@ -2,8 +2,8 @@
|
||||
* @package Adminer.css - Theme CSS for Adminer --- [theme light] blue B (with icons)
|
||||
*
|
||||
*//*!
|
||||
* @version 4.17.1.2
|
||||
* @date Thu, 27 Feb 2025 09:28:32 +0100
|
||||
* @version 5.0.4.1
|
||||
* @date Wed, 12 Mar 2025 21:35:32 +0100
|
||||
* @author Robert Mesaros
|
||||
* @copyright Copyright 2025 Robert Mesaros, rmSOFT, Slovakia
|
||||
* @web https://www.rmsoft.sk
|
||||
@@ -35,10 +35,6 @@
|
||||
* Modified icons by Robert Mesaros
|
||||
*
|
||||
*/
|
||||
#menu{padding:0 0 30px 0}
|
||||
.ltr .logout{right:0;left:auto;margin-top:.5em}
|
||||
.rtl .logout{left:0;right:auto;margin-top:.5em}
|
||||
.rtl table.layout tbody{direction:ltr}
|
||||
html{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}
|
||||
*,*:before,*:after{box-sizing:inherit}
|
||||
body{color:#000;background:#82a7c0;font-family:Verdana,Arial,Helvetica,sans-serif;font-weight:normal;cursor:default;margin:0}
|
||||
@@ -49,6 +45,9 @@ img{width:100%;max-width:100%}
|
||||
#menu #h1{margin-left:10px}
|
||||
#menu h1{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozNDA3NDEwQ0Y0MkQxMUVGODA4RUNENTRFQzJENUU4RCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozNDA3NDEwQkY0MkQxMUVGODA4RUNENTRFQzJENUU4RCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRTREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Ph59M4AAAAPFSURBVHja7JZrSFNRHMDvvVvq1mNlucBK0g/lh+Us6oPrU0ERRFgRUqYUVEb2qTJ0vko0ZbMHiBT0sizSXEUfJGzN1CjBQLPCR/RwSYKp23RO3e527/r/57mxxpblhCD8w59z7t2553f+zx36Ulk5FYxkZpyiijVahUgkqnc62cu5arUGXrMl2tIkhmGuu91uGp4HXre0qB490A3C3IXfMVSQojl/QQYAHUzlNtvYPBhl2Xn5672gqBFxSmXF0WPpCTCfg+/EwUDBwkixeM4TmqZjzSbTFU1J8W00RiaTtUxMTJSfzctFd4Yq49eGJ6ekNETHxGyG50jQkWDAcoA+BqjSbDaXA/QqvBtFBWg6QGuJtSaapr7jB7AWrV0C6pguWAZurIeNFCaTqUxbUnwd3lkRAjoO0JswStApEGs1jJs4jusw9vTcEcI7LTBA3wA02mI2X/WFgvIIxCQC6EmIdQ7P898qb1Xs7O7qGiVrWWaa4C5PZopEy6RSKQfTYS8oRUYO1i3Hh4e6mlSA2sjhLHgwMdkoA04lI1noV8BVn/Nzsu/iFHTP2cIiHSTR9tNZaqYgP28/iecv4nA4ajmXi7NYLKPkcFbiDYomdcxNVVoul6s9JytzC/mYWxEVtfDQkbQKiUSyw26368/k5iTBexvZSxA0bD4Zx0An0E4B3Nfz5cu+zs4OJ+tgQwOBlfHxcSujo7MHBwfTLpZq69Cdq2NjFyWnpFaGhYVtA3hdU2PD4ecGQ78AhxjnQi6o29va1lVX3TNibAUwniSyq7PT+qKxcQjmduEHX0lQqSIgUZaOj4+FwyM2ipEP3d1msHRvQdG5GoQnqDYWAviEYDmErw/G1t7e3hAYQwiY+tm5Pn36aCdusATS+QsWDOBa8ArWInqGga6FltnQzcPDlrKvRmMTKSMRroXQ3AXd3fzq5ZCvQZ7kOnb8ONQXbYd+6/pNmBd70pXnfHPBAy8pKsojUNYruzmSEwzp0e5fwNCBFIFc7CXMZHbzIn9JT9wrJA/nVVasv8084PvVVVvftLbavIPvK6kHDqoUa9Zc+03J8V6WTike8FzpXJ4UtzUQOEIux98oCAdHzYCIJzsQw5M6s0LC+D01NIPxmQQz1D+SWfAs+D8FO1mn6w9uHUJ90zPSQOAvcdWOxERD4q5dSwjA/0KxuNmg1294/+7tGLlFuIOy+NbNG0b4s3YSSwIqyzr4Z/qnlv7+/iE/N42/FjokJBQ3lmI7JteUQK5E0Ajp6fZgLUaw0LNDp7juuomL2WCtRfkhwACjULOQ0RiwkAAAAABJRU5ErkJggg==");background-repeat:no-repeat}
|
||||
#menu h1:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQUNCOTdFQkY0MkQxMUVGOUM0OUMyQTRDNjAyNzhENiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQUNCOTdFQUY0MkQxMUVGOUM0OUMyQTRDNjAyNzhENiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRTREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pq1mg9cAAAQtSURBVHja7JZdTFxFFIDP3J9dCgqUQimQIlBSWNoCNfVBYmo0jX9Jg014aYrWFzWGRl9MTHzpiy8k2kbrm9qUWtMaY9S2RqV9ADQm9o/+pHsvhW5Lw8/iLu6PC9yfvTOeWWbbC9ktlPWRk5ydvWfmzjfnzJkzlxz+7HNYSpIeD1QEAtB2+kew8vKgwdXn9Wsw1uR7tQTg+zhjfRs0fTeazWCT71ARwLt8jANgn0nMNO+9d+82nw6VSZCj3PE1VhcDnJIBpDnG8tC0TmvYvC8N5YJ9yq6C/L4/6je9jo8eVJITOMjY9lJCdBUdn6D0Sq0+9B6alTpZ7okwNrjGrzWjPnkwHO4oJKR8h8fzJfaXcLiUA3TLWkJ+x+WvQeglhL6N5jhqZIqxbyo1vQP/z6GOW5QN8nfI/KtrOVhZLogwllIuE4xVo6eXEJo3TumFOn2oS0D/Rv23WtPfxPYxVCvU5DuL41pMAOOWbf+ENu4sWR4YgUlVBUdRQHIcKJPlEQyvGqT02mLofC6BhRrFBPuhEOAZG20HJoOvHItEJtEeQ7WXFWrFtmGq+gm4+NLL6DUF23Ei3O4hpLRKVXkY/nFBRSKDjUlVxR8+Coc7BTSEGuZZr8w7xN6nlBZhS7LBqWHc3n/kyAkxaV2osWG4RJKqrtRvOluu6S0PtvCBxCg9iZtsBSwrJBYXEdFgKTAhpFuW5aW8v4p6RoTV7Bwb23F848aLxYRUhn2NN0o13Sf6kukX6vWhT7E5zoMm+mwOTTGxgIzfCQT2+v03bcu0vNmoLa2tzTW1tR+GpsNvHeru/pVP0FlcXHG4YsMFflSweEwdjUaf/2AyeEtEhWFincMM2/XzzOxzHaOjf6HNSIP5Sio1vz8+0NcXdncslqfb2sokSSqfTSRKRMbGTkSjE6hb0GM/h+8rKvoOwTtFAiUtxkYNQqI3TYNHkztlusEwMjJsiDMXzQZ+vLCQZy1gVFQxiWQ+u9P29g/EMMxNdxsbfhm2rH4+FHWWg6s0/QC2B0W1WjBvCvxOV9fXGHUD9zn5kD1el0oy6tzPhdM1tQD9A/ydWI0+9KKA8uShYogtkkpKJ9UCsKKoW7N56pIU0HGonDaMtG4H6OkBkVBxETUmgOljNZfxiPKfb0+dfGHw8uXE4lW55bX9b7Rt3bbtC/eR4wXFJY7rHC9dG/hPQX4BD820WHVGcNn69fHUTSPL9ydXDWPFF0wKLMkSB89wcPfHn9BMA03TnF0MxgKwYnDO9/EqeBW8Cl4Ati07ufTXD0ufb/J/gBW8Ejfvbm8/375nT6kAZB6oKH+e7+196sb1azPuC33FHh87+tVd/AKxhSdZ1bJMeq73t0gwGOT3duJR6nLGr1aPx8snzuflWFxr2ULpiAt++mEfDI8CTtdsb7p2Z9tmEWIrV2+5/CfAAOVxxSK4gGWJAAAAAElFTkSuQmCC")}
|
||||
.rtl table.layout tbody td{display:flex}
|
||||
.rtl table.layout~table thead th:first-child,.rtl table.layout~table tbody td:first-child{text-align:right !important}
|
||||
.rtl table.layout~table thead th:last-child,.rtl table.layout~table tbody td:last-child{text-align:left !important}
|
||||
h1{padding:.6em .4em;background:#1d5377;border:1px solid #f2ddaf;text-align:left}
|
||||
#h1{color:#fff}
|
||||
.version{color:#ddd;margin-left:8px}
|
||||
@@ -99,7 +98,7 @@ code{background:#93b3c8;padding:.2em .5em}
|
||||
table code{font-size:130%;background:#bfd9eb;padding:.1em .3em}
|
||||
code.jush-sql{background:#d8e9f4}
|
||||
.rtl p code.jush-sql{background-position:right;clear:right;float:right}
|
||||
pre.sqlarea{background:#aac6d8;padding:5px}
|
||||
pre{background:#aac6d8 !important;padding:5px}
|
||||
textarea{font-size:120%}
|
||||
.ltr p.count{font-size:90%;margin:.8em 20px 8px 0}
|
||||
.rtl p.count{font-size:90%;margin:.8em 0 8px 20px}
|
||||
@@ -119,12 +118,12 @@ table{border-spacing:0}
|
||||
table,td,th{border:0;border-collapse:separate}
|
||||
.ltr table{margin:1.9em 0 0 0}
|
||||
.rtl table{margin:1.9em 0 0 0}
|
||||
.rtl table tbody td,.rtl table tbody th{text-align:right}
|
||||
.rtl table tbody td,.rtl table tbody th{text-align:right !important}
|
||||
.ltr table thead td:first-child,.ltr table thead th:first-child{border-left:1px solid #0e344e}
|
||||
.rtl table thead td:first-child,.rtl table thead th:first-child{border-right:1px solid #0e344e}
|
||||
table thead td,table thead th{height:1.6em;border-top:1px solid #0e344e;border-bottom:1px solid #0e344e}
|
||||
.ltr table thead td,.ltr table thead th{border-right:1px solid #0e344e}
|
||||
.rtl table thead td,.rtl table thead th{border-left:1px solid #0e344e;text-align:right !important}
|
||||
.rtl table thead td,.rtl table thead th{border-left:1px solid #0e344e}
|
||||
table tbody tr:first-child td,table tbody tr:first-child th{border-top:1px solid #527d9a}
|
||||
.ltr table tbody td:first-child,.ltr table tbody th:first-child{border-left:1px solid #527d9a}
|
||||
.rtl table tbody td:first-child,.rtl table tbody th:first-child{border-right:1px solid #527d9a}
|
||||
@@ -421,9 +420,12 @@ input[type=radio]{margin-bottom:5px}
|
||||
.rtl input[type=checkbox],.rtl input[type=radio],.rtl input[type=range],.rtl progress{margin-left:5px}
|
||||
.ltr input[type=submit]{margin-right:10px}
|
||||
.rtl input[type=submit]{margin-left:10px}
|
||||
.ltr table.layout label,.ltr label.jsonly{margin-left:8px}
|
||||
.rtl table.layout label,.rtl label.jsonly{margin-right:8px}
|
||||
input,button,select,.sqlarea{border-radius:3px}
|
||||
.sqlarea{background:#aac6d8;font-size:105%}
|
||||
fieldset a{line-height:unset}
|
||||
input[type=submit]{padding:2px 6px}
|
||||
.ltr table.layout label,.ltr label.jsonly{margin-left:8px}
|
||||
.rtl table.layout label,.rtl label.jsonly{margin-right:8px}
|
||||
#menu{padding:0 0 30px 0}
|
||||
.ltr .logout{right:0;left:auto;margin-top:.5em}
|
||||
.rtl .logout{left:0;right:auto;margin-top:.5em}
|
||||
|
@@ -20,7 +20,7 @@ if ($adminer->homepage()) {
|
||||
|
||||
foreach (table_status() as $table => $row) {
|
||||
$name = $adminer->tableName($row);
|
||||
if (isset($row["Engine"]) && $name != "") {
|
||||
if ($name != "") {
|
||||
echo '<tr><td>' . checkbox("tables[]", $table, in_array($table, (array) $_POST["tables"], true));
|
||||
echo "<th><a href='" . h(ME) . 'select=' . urlencode($table) . "'>$name</a>";
|
||||
$val = format_number($row["Rows"]);
|
||||
|
@@ -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;
|
||||
}
|
||||
@@ -90,7 +92,10 @@ class Adminer {
|
||||
}
|
||||
|
||||
function tableName($tableStatus) {
|
||||
return h($tableStatus["Comment"] != "" ? $tableStatus["Comment"] : $tableStatus["Name"]);
|
||||
return h(isset($tableStatus["Engine"])
|
||||
? ($tableStatus["Comment"] != "" ? $tableStatus["Comment"] : $tableStatus["Name"])
|
||||
: "" // ignore views
|
||||
);
|
||||
}
|
||||
|
||||
function fieldName($field, $order = 0) {
|
||||
@@ -208,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;
|
||||
@@ -623,6 +627,9 @@ qsl('div').onclick = whisperClick;", "")
|
||||
}
|
||||
}
|
||||
|
||||
function syntaxHighlighting($tables) {
|
||||
}
|
||||
|
||||
function databasesPrint($missing) {
|
||||
}
|
||||
|
||||
@@ -632,7 +639,7 @@ qsl('div').onclick = whisperClick;", "")
|
||||
foreach ($tables as $row) {
|
||||
echo '<li>';
|
||||
$name = $this->tableName($row);
|
||||
if (isset($row["Engine"]) && $name != "") { // ignore views and tables without name
|
||||
if ($name != "") { // ignore tables without name
|
||||
echo "<a href='" . h(ME) . 'select=' . urlencode($row["Name"]) . "'"
|
||||
. bold($_GET["select"] == $row["Name"] || $_GET["edit"] == $row["Name"], "select")
|
||||
. " title='" . lang('Select data') . "'>$name</a>\n"
|
||||
|
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: 792086f0fd...a80237e93e
33
phpcs.xml
33
phpcs.xml
@@ -12,8 +12,6 @@
|
||||
<rule ref="PSR12">
|
||||
<exclude name="Generic.Whitespace.DisallowTabIndent"/><!-- Replaced by: Generic.Whitespace.DisallowSpaceIndent -->
|
||||
<exclude name="PSR1.Files.SideEffects.FoundWithSymbols"/>
|
||||
<exclude name="PSR12.Operators.OperatorSpacing.NoSpaceBefore"/>
|
||||
<exclude name="PSR12.Operators.OperatorSpacing.NoSpaceAfter"/>
|
||||
<exclude name="PSR1.Classes.ClassDeclaration.MultipleClasses"/>
|
||||
<exclude name="PSR2.Classes.ClassDeclaration.OpenBraceNewLine"/><!-- Replaced by: Generic.Classes.OpeningBraceSameLine -->
|
||||
<exclude name="PSR2.Classes.PropertyDeclaration.Underscore"/>
|
||||
@@ -24,6 +22,8 @@
|
||||
<!-- More readable. -->
|
||||
<exclude name="PSR12.Files.FileHeader.SpacingAfterBlock"/>
|
||||
<exclude name="PSR12.Classes.OpeningBraceSpace.Found"/>
|
||||
<exclude name="PSR12.Operators.OperatorSpacing.NoSpaceBefore"/>
|
||||
<exclude name="PSR12.Operators.OperatorSpacing.NoSpaceAfter"/>
|
||||
<exclude name="Squiz.WhiteSpace.ControlStructureSpacing.SpacingBeforeClose"/>
|
||||
|
||||
<!-- Saves bytes. -->
|
||||
@@ -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>
|
||||
@@ -45,7 +53,7 @@
|
||||
|
||||
<rule ref="Generic.Files.LineLength">
|
||||
<properties>
|
||||
<property name="lineLimit" value="310"/>
|
||||
<property name="lineLimit" value="250"/>
|
||||
</properties>
|
||||
<exclude-pattern>adminer/lang/</exclude-pattern>
|
||||
</rule>
|
||||
@@ -108,4 +116,21 @@
|
||||
<rule ref="Squiz.WhiteSpace.LanguageConstructSpacing"/>
|
||||
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
|
||||
<rule ref="Squiz.WhiteSpace.ObjectOperatorSpacing"/>
|
||||
|
||||
<!--
|
||||
This is slow and has false positives but it's useful occasionally.
|
||||
https://github.com/PHPCompatibility/PHPCompatibility
|
||||
<rule ref="PHPCompatibility"/>
|
||||
<config name="testVersion" value="5.3-"/>
|
||||
<rule ref="PHPCompatibility.Extensions.RemovedExtensions">
|
||||
<exclude name="PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved"/>
|
||||
<exclude name="PHPCompatibility.Extensions.RemovedExtensions.ibaseRemoved"/>
|
||||
</rule>
|
||||
<rule ref="PHPCompatibility.Constants.RemovedConstants">
|
||||
<exclude-pattern>adminer/plugins/drivers/firebird.php</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="PHPCompatibility.FunctionUse.RemovedFunctions">
|
||||
<exclude-pattern>adminer/plugins/drivers/firebird.php</exclude-pattern>
|
||||
</rule>
|
||||
-->
|
||||
</ruleset>
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -143,7 +143,12 @@ if (isset($_GET["clickhouse"])) {
|
||||
function __construct($connection) {
|
||||
parent::__construct($connection);
|
||||
$this->types = array( //! arrays
|
||||
lang('Numbers') => array("Int8" => 3, "Int16" => 5, "Int32" => 10, "Int64" => 19, "UInt8" => 3, "UInt16" => 5, "UInt32" => 10, "UInt64" => 20, "Float32" => 7, "Float64" => 16, 'Decimal' => 38, 'Decimal32' => 9, 'Decimal64' => 18, 'Decimal128' => 38),
|
||||
lang('Numbers') => array(
|
||||
"Int8" => 3, "Int16" => 5, "Int32" => 10, "Int64" => 19,
|
||||
"UInt8" => 3, "UInt16" => 5, "UInt32" => 10, "UInt64" => 20,
|
||||
"Float32" => 7, "Float64" => 16,
|
||||
'Decimal' => 38, 'Decimal32' => 9, 'Decimal64' => 18, 'Decimal128' => 38,
|
||||
),
|
||||
lang('Date and time') => array("Date" => 13, "DateTime" => 20),
|
||||
lang('Strings') => array("String" => 0),
|
||||
lang('Binary') => array("FixedString" => 0),
|
||||
|
@@ -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]);
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
$drivers["mongo"] = "MongoDB (alpha)";
|
||||
add_driver("mongo", "MongoDB (alpha)");
|
||||
|
||||
if (isset($_GET["mongo"])) {
|
||||
define('Adminer\DRIVER', "mongo");
|
||||
@@ -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) {
|
||||
@@ -120,9 +120,8 @@ if (isset($_GET["mongo"])) {
|
||||
|
||||
|
||||
function get_databases($flush) {
|
||||
global $connection;
|
||||
$return = array();
|
||||
foreach ($connection->executeCommand(array('listDatabases' => 1)) as $dbs) {
|
||||
foreach (connection()->executeCommand(array('listDatabases' => 1)) as $dbs) {
|
||||
foreach ($dbs->databases as $db) {
|
||||
$return[] = $db->name;
|
||||
}
|
||||
@@ -136,9 +135,8 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
function tables_list() {
|
||||
global $connection;
|
||||
$collections = array();
|
||||
foreach ($connection->executeCommand(array('listCollections' => 1)) as $result) {
|
||||
foreach (connection()->executeCommand(array('listCollections' => 1)) as $result) {
|
||||
$collections[$result->name] = 'table';
|
||||
}
|
||||
return $collections;
|
||||
@@ -149,9 +147,8 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
function indexes($table, $connection2 = null) {
|
||||
global $connection;
|
||||
$return = array();
|
||||
foreach ($connection->executeCommand(array('listIndexes' => $table)) as $index) {
|
||||
foreach (connection()->executeCommand(array('listIndexes' => $table)) as $index) {
|
||||
$descs = array();
|
||||
$columns = array();
|
||||
foreach (get_object_vars($index->key) as $column => $type) {
|
||||
@@ -169,7 +166,7 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
function fields($table) {
|
||||
global $driver;
|
||||
$driver = driver();
|
||||
$fields = fields_from_edit();
|
||||
if (!$fields) {
|
||||
$result = $driver->select($table, array("*"), null, null, array(), 10);
|
||||
@@ -198,9 +195,8 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
function found_rows($table_status, $where) {
|
||||
global $connection;
|
||||
$where = where_to_query($where);
|
||||
$toArray = $connection->executeCommand(array('count' => $table_status['Name'], 'query' => $where))->toArray();
|
||||
$toArray = connection()->executeCommand(array('count' => $table_status['Name'], 'query' => $where))->toArray();
|
||||
return $toArray[0]->n;
|
||||
}
|
||||
|
||||
@@ -225,7 +221,6 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
function where_to_query($whereAnd = array(), $whereOr = array()) {
|
||||
global $adminer;
|
||||
$data = array();
|
||||
foreach (array('and' => $whereAnd, 'or' => $whereOr) as $type => $where) {
|
||||
if (is_array($where)) {
|
||||
@@ -235,7 +230,7 @@ if (isset($_GET["mongo"])) {
|
||||
list(, $class, $val) = $match;
|
||||
$val = new $class($val);
|
||||
}
|
||||
if (!in_array($op, $adminer->operators)) {
|
||||
if (!in_array($op, adminer()->operators)) {
|
||||
continue;
|
||||
}
|
||||
if (preg_match('~^\(f\)(.+)~', $op, $match)) {
|
||||
@@ -409,13 +404,11 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
function last_id() {
|
||||
global $connection;
|
||||
return $connection->last_id;
|
||||
return connection()->last_id;
|
||||
}
|
||||
|
||||
function error() {
|
||||
global $connection;
|
||||
return h($connection->error);
|
||||
return h(connection()->error);
|
||||
}
|
||||
|
||||
function collations() {
|
||||
@@ -423,13 +416,11 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
function logged_user() {
|
||||
global $adminer;
|
||||
$credentials = $adminer->credentials();
|
||||
$credentials = adminer()->credentials();
|
||||
return $credentials[1];
|
||||
}
|
||||
|
||||
function connect($credentials) {
|
||||
global $adminer;
|
||||
$connection = new Db;
|
||||
list($server, $username, $password) = $credentials;
|
||||
|
||||
@@ -442,7 +433,7 @@ if (isset($_GET["mongo"])) {
|
||||
$options["username"] = $username;
|
||||
$options["password"] = $password;
|
||||
}
|
||||
$db = $adminer->database();
|
||||
$db = adminer()->database();
|
||||
if ($db != "") {
|
||||
$options["db"] = $db;
|
||||
}
|
||||
@@ -457,7 +448,7 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
function alter_indexes($table, $alter) {
|
||||
global $connection;
|
||||
$connection = connection();
|
||||
foreach ($alter as $val) {
|
||||
list($type, $name, $set) = $val;
|
||||
if ($set == "DROP") {
|
||||
@@ -514,17 +505,15 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
|
||||
global $connection;
|
||||
if ($table == "") {
|
||||
$connection->_db->createCollection($name);
|
||||
connection()->_db->createCollection($name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function drop_tables($tables) {
|
||||
global $connection;
|
||||
foreach ($tables as $table) {
|
||||
$response = $connection->_db->selectCollection($table)->drop();
|
||||
$response = connection()->_db->selectCollection($table)->drop();
|
||||
if (!$response['ok']) {
|
||||
return false;
|
||||
}
|
||||
@@ -533,9 +522,8 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
function truncate_tables($tables) {
|
||||
global $connection;
|
||||
foreach ($tables as $table) {
|
||||
$response = $connection->_db->selectCollection($table)->remove();
|
||||
$response = connection()->_db->selectCollection($table)->remove();
|
||||
if (!$response['ok']) {
|
||||
return false;
|
||||
}
|
@@ -422,7 +422,7 @@ if (isset($_GET["simpledb"])) {
|
||||
'max_redirects' => 0,
|
||||
))));
|
||||
if (!$file) {
|
||||
$this->error = lang('Invalid credentials.');
|
||||
$connection->error = lang('Invalid credentials.');
|
||||
return false;
|
||||
}
|
||||
libxml_use_internal_errors(true);
|
||||
|
@@ -14,7 +14,7 @@ class AdminerDumpAlter {
|
||||
}
|
||||
}
|
||||
|
||||
function _database() {
|
||||
private function database() {
|
||||
// drop old tables
|
||||
$query = "SELECT TABLE_NAME, ENGINE, TABLE_COLLATION, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()";
|
||||
echo "DELIMITER ;;
|
||||
@@ -59,9 +59,8 @@ SELECT @adminer_alter;
|
||||
if ($first) {
|
||||
$first = false;
|
||||
echo "SET @adminer_alter = '';\n\n";
|
||||
register_shutdown_function(array($this, '_database'));
|
||||
} else {
|
||||
$this->_database();
|
||||
$this->database();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -75,7 +74,10 @@ SELECT @adminer_alter;
|
||||
} else {
|
||||
echo substr_replace($create, " IF NOT EXISTS", 12, 0) . ";\n\n";
|
||||
// create procedure which iterates over original columns and adds new and removes old
|
||||
$query = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, COLLATION_NAME, COLUMN_TYPE, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . Adminer\q($table) . " ORDER BY ORDINAL_POSITION";
|
||||
$query = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, COLLATION_NAME, COLUMN_TYPE, EXTRA, COLUMN_COMMENT
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . Adminer\q($table) . "
|
||||
ORDER BY ORDINAL_POSITION";
|
||||
echo "DELIMITER ;;
|
||||
CREATE PROCEDURE adminer_alter (INOUT alter_command text) BEGIN
|
||||
DECLARE _column_name, _collation_name, after varchar(64) DEFAULT '';
|
||||
@@ -159,4 +161,10 @@ DROP PROCEDURE adminer_alter;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function dumpFooter() {
|
||||
if ($_POST["format"] == "sql_alter") {
|
||||
$this->database();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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();
|
||||
|
14
plugins/editor-views.php
Normal file
14
plugins/editor-views.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
/** Display views in Adminer Editor
|
||||
* @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 AdminerEditorViews {
|
||||
|
||||
function tableName($tableStatus) {
|
||||
return Adminer\h($tableStatus["Comment"] != "" ? $tableStatus["Comment"] : $tableStatus["Name"]);
|
||||
}
|
||||
}
|
@@ -14,12 +14,18 @@ class AdminerForeignSystem {
|
||||
"columns_priv" => array(array("table" => "user", "source" => array("Host", "User"), "target" => array("Host", "User"))),
|
||||
"db" => array(array("table" => "user", "source" => array("Host", "User"), "target" => array("Host", "User"))),
|
||||
"help_category" => array(array("table" => "help_category", "source" => array("parent_category_id"), "target" => array("help_category_id"))),
|
||||
"help_relation" => array(array("table" => "help_topic", "source" => array("help_topic_id"), "target" => array("help_topic_id")), array("table" => "help_keyword", "source" => array("help_keyword_id"), "target" => array("help_keyword_id"))),
|
||||
"help_relation" => array(
|
||||
array("table" => "help_topic", "source" => array("help_topic_id"), "target" => array("help_topic_id")),
|
||||
array("table" => "help_keyword", "source" => array("help_keyword_id"), "target" => array("help_keyword_id")),
|
||||
),
|
||||
"help_topic" => array(array("table" => "help_category", "source" => array("help_category_id"), "target" => array("help_category_id"))),
|
||||
"procs_priv" => array(array("table" => "user", "source" => array("Host", "User"), "target" => array("Host", "User")), array("table" => "proc", "source" => array("Db", "Routine_name"), "target" => array("db", "name"))),
|
||||
"tables_priv" => array(array("table" => "user", "source" => array("Host", "User"), "target" => array("Host", "User"))),
|
||||
"time_zone_name" => array(array("table" => "time_zone", "source" => array("Time_zone_id"), "target" => array("Time_zone_id"))),
|
||||
"time_zone_transition" => array(array("table" => "time_zone", "source" => array("Time_zone_id"), "target" => array("Time_zone_id")), array("table" => "time_zone_transition_type", "source" => array("Time_zone_id", "Transition_type_id"), "target" => array("Time_zone_id", "Transition_type_id"))),
|
||||
"time_zone_transition" => array(
|
||||
array("table" => "time_zone", "source" => array("Time_zone_id"), "target" => array("Time_zone_id")),
|
||||
array("table" => "time_zone_transition_type", "source" => array("Time_zone_id", "Transition_type_id"), "target" => array("Time_zone_id", "Transition_type_id")),
|
||||
),
|
||||
"time_zone_transition_type" => array(array("table" => "time_zone", "source" => array("Time_zone_id"), "target" => array("Time_zone_id"))),
|
||||
);
|
||||
return $return[$table];
|
||||
|
@@ -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);
|
||||
|
@@ -1,15 +1,12 @@
|
||||
<?php
|
||||
|
||||
/** Pretty print JSON values in edit
|
||||
* @link https://www.adminer.org/plugins/#use
|
||||
* @author Christopher Chen
|
||||
* @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 AdminerPrettyJsonColumn {
|
||||
/** @var AdminerPlugin */
|
||||
protected $adminer;
|
||||
|
||||
public function __construct($adminer) {
|
||||
$this->adminer = $adminer;
|
||||
}
|
||||
|
||||
private function testJson($value) {
|
||||
if ((substr($value, 0, 1) == '{' || substr($value, 0, 1) == '[') && ($json = json_decode($value, true))) {
|
||||
return $json;
|
||||
@@ -21,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 '';
|
||||
}
|
||||
@@ -33,6 +30,5 @@ class AdminerPrettyJsonColumn {
|
||||
$value = json_encode($json);
|
||||
}
|
||||
}
|
||||
return $this->adminer->_callParent('processInput', array($field, $value, $function));
|
||||
}
|
||||
}
|
||||
|
@@ -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>';
|
||||
}
|
||||
}
|
@@ -15,7 +15,15 @@ class AdminerTableStructure {
|
||||
function tableStructurePrint($fields) {
|
||||
echo "<div class='scrollable'>\n";
|
||||
echo "<table class='nowrap odds'>\n";
|
||||
echo "<thead><tr><th>" . Adminer\lang('Column') . "<th>" . Adminer\lang('Type') . "<th>" . Adminer\lang('Collation') . "<th>" . Adminer\lang('Nullable') . "<th>" . Adminer\lang('Default') . (Adminer\support("comment") ? "<th>" . Adminer\lang('Comment') : "") . "</thead>\n";
|
||||
echo "<thead><tr>"
|
||||
. "<th>" . Adminer\lang('Column')
|
||||
. "<th>" . Adminer\lang('Type')
|
||||
. "<th>" . Adminer\lang('Collation')
|
||||
. "<th>" . Adminer\lang('Nullable')
|
||||
. "<th>" . Adminer\lang('Default')
|
||||
. (Adminer\support("comment") ? "<th>" . Adminer\lang('Comment') : "")
|
||||
. "</thead>\n"
|
||||
;
|
||||
foreach ($fields as $field) {
|
||||
echo "<tr><th>" . Adminer\h($field["field"]) . ($field["primary"] ? " (PRIMARY)" : "");
|
||||
echo "<td><span>" . Adminer\h($field["full_type"]) . "</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);
|
||||
}
|
||||
|
@@ -2,7 +2,9 @@ Adminer - Database management in a single PHP file
|
||||
Adminer Editor - Data manipulation for end-users
|
||||
|
||||
https://www.adminer.org/
|
||||
Supports: MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, MongoDB, Elasticsearch (plugin), SimpleDB (plugin), Firebird (plugin), ClickHouse (plugin)
|
||||
|
||||
Supports: MySQL, MariaDB, PostgreSQL, CockroachDB, SQLite, MS SQL, Oracle
|
||||
Plugins for: Elasticsearch, SimpleDB, MongoDB, Firebird, ClickHouse
|
||||
Requirements: PHP 5.3+
|
||||
|
||||
adminer/index.php - Run development version of Adminer
|
||||
@@ -15,6 +17,6 @@ editor/sqlite.php - Development version of Editor with SQLite allowed
|
||||
adminer/designs.php - Development version of Adminer with adminer.css switcher
|
||||
compile.php - Create a single file version
|
||||
lang.php - Update translations
|
||||
tests/katalon.html - Katalon Automation Recorder test suite
|
||||
tests/*.html - Katalon Recorder test suites
|
||||
|
||||
If downloaded from Git then run: git submodule update --init
|
||||
|
352
tests/cocroachdb.html
Normal file
352
tests/cocroachdb.html
Normal file
@@ -0,0 +1,352 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
|
||||
<title>Katalon CockroachDB</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<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>
|
||||
<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=PostgreSQL</td></tr>
|
||||
<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>//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>
|
||||
<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>
|
||||
<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=character varying</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][length]</td><td>50</td></tr>
|
||||
<tr><td>uncheck</td><td>name=comments</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>name=comments</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][comment]</td><td>Interpret</td></tr>
|
||||
<tr><td>type</td><td>Comment</td><td>Interprets</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">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>
|
||||
<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>multiple primary keys for table "interprets" are not allowed</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/?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>
|
||||
<tr><td>type</td><td>name</td><td>albums</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=character varying</td></tr>
|
||||
<tr><td>type</td><td>fields[1.11][length]</td><td>50</td></tr>
|
||||
<tr><td>check</td><td>name=comments</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][comment]</td><td>Interpret</td></tr>
|
||||
<tr><td>type</td><td>fields[1.11][comment]</td><td>Album</td></tr>
|
||||
<tr><td>type</td><td>Comment</td><td>Albums</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/?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>
|
||||
<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/?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>
|
||||
<tr><td>click</td><td>add[2]</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[3][field]</td><td>albums</td></tr>
|
||||
<tr><td>select</td><td>fields[3][type]</td><td>label=integer</td></tr>
|
||||
<tr><td>type</td><td>fields[3][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[3][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">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>//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>
|
||||
<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>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">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>
|
||||
<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 has been inserted.</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&username=ODBC&db=adminer_test&ns=public&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 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/?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>
|
||||
<tr><td>clickAndWait</td><td>clone</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[id]</td><td>2</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>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" 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>
|
||||
<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>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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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/?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>
|
||||
<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/?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>
|
||||
<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 "public"."interprets"</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">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>
|
||||
<tr><td>type</td><td>fields[1][field]</td><td>interpret_name</td></tr>
|
||||
<tr><td>select</td><td>fields[1][type]</td><td>label=character varying</td></tr>
|
||||
<tr><td>type</td><td>fields[1][length]</td><td>50</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][field]</td><td>album_title</td></tr>
|
||||
<tr><td>select</td><td>fields[1.1][type]</td><td>label=character varying</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][length]</td><td>50</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="definition"]').value = 'SELECT id FROM interprets;'</td><td></td></tr>
|
||||
<tr><td>type</td><td>name</td><td>insert_album</td></tr>
|
||||
<tr><td>select</td><td>name=language</td><td>label=sql</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Routine has been created.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=insert_album</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[interpret_name]</td><td>Michael Jackson</td></tr>
|
||||
<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>
|
||||
<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" 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>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Are you sure?</td><td></td></tr>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
408
tests/mariadb.html
Normal file
408
tests/mariadb.html
Normal file
@@ -0,0 +1,408 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
|
||||
<title>Katalon MariaDB</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<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>
|
||||
<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[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>//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>
|
||||
<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>
|
||||
<tr><td>type</td><td>name</td><td>adminer_test</td></tr>
|
||||
<tr><td>select</td><td>collation</td><td>label=utf8mb4_general_ci</td></tr>
|
||||
<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>
|
||||
<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>
|
||||
<tr><td>type</td><td>name</td><td>interprets</td></tr>
|
||||
<tr><td>select</td><td>Engine</td><td>label=InnoDB</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=int</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=varchar</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][length]</td><td>50</td></tr>
|
||||
<tr><td>uncheck</td><td>name=comments</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>name=comments</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][comment]</td><td>Interpret</td></tr>
|
||||
<tr><td>type</td><td>Comment</td><td>Interprets</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">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>
|
||||
<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>name</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Multiple primary key defined</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">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>
|
||||
<tr><td>select</td><td>partition_by</td><td>label=HASH</td></tr>
|
||||
<tr><td>click</td><td>link=Partition by</td><td></td></tr>
|
||||
<tr><td>type</td><td>partition</td><td>id</td></tr>
|
||||
<tr><td>type</td><td>partitions</td><td>2</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>
|
||||
<tr><td>clickAndWait</td><td>link=Alter table</td><td></td></tr>
|
||||
<tr><td>select</td><td>partition_by</td><td>label=RANGE</td></tr>
|
||||
<tr><td>type</td><td>partition_values[]</td><td>10</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>
|
||||
<tr><td>clickAndWait</td><td>link=Alter table</td><td></td></tr>
|
||||
<tr><td>select</td><td>partition_by</td><td>label=</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 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>
|
||||
<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=int</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=int</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=varchar</td></tr>
|
||||
<tr><td>type</td><td>fields[1.11][length]</td><td>50</td></tr>
|
||||
<tr><td>check</td><td>name=comments</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][comment]</td><td>Interpret</td></tr>
|
||||
<tr><td>type</td><td>fields[1.11][comment]</td><td>Album</td></tr>
|
||||
<tr><td>type</td><td>Comment</td><td>Albums</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/?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>
|
||||
<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/?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>
|
||||
<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=int</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/?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>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="Statement"]').value = 'UPDATE interprets SET albums = albums + 1 WHERE id = NEW.interpret'</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/?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>//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>
|
||||
<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>
|
||||
<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/?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>
|
||||
<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>open</td><td>/adminer/?server=localhost:3307&username=ODBC&db=adminer_test&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/?server=localhost:3307&username=ODBC&db=adminer_test&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/?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>
|
||||
<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>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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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/?server=localhost:3307&username=ODBC&db=adminer_test&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">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>
|
||||
<tr><td>type</td><td>objects[0]</td><td>adminer_test.*</td></tr>
|
||||
<tr><td>click</td><td>grants[0][ALTER]</td><td></td></tr>
|
||||
<tr><td>click</td><td>grants[0][CREATE]</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@name='grants[0][CREATE VIEW]']</td><td></td></tr>
|
||||
<tr><td>click</td><td>grants[0][DELETE]</td><td></td></tr>
|
||||
<tr><td>click</td><td>grants[0][DROP]</td><td></td></tr>
|
||||
<tr><td>click</td><td>grants[0][INDEX]</td><td></td></tr>
|
||||
<tr><td>click</td><td>grants[0][INSERT]</td><td></td></tr>
|
||||
<tr><td>click</td><td>grants[0][REFERENCES]</td><td></td></tr>
|
||||
<tr><td>click</td><td>grants[0][SELECT]</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@name='grants[0][SHOW VIEW]']</td><td></td></tr>
|
||||
<tr><td>click</td><td>grants[0][UPDATE]</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@name='grants[0][CREATE TEMPORARY TABLES]']</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@name='grants[0][LOCK TABLES]']</td><td></td></tr>
|
||||
<tr><td>click</td><td>//input[@name='grants[0][CREATE ROUTINE]']</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>User has been created.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//div[@id='content']/form/table/tbody/tr[td[1]='adminer_test']/td[3]/a</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop adminer_test@localhost?</td><td></td></tr>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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">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>
|
||||
<tr><td>select</td><td>INTERVAL_FIELD</td><td>label=DAY</td></tr>
|
||||
<tr><td>type</td><td>INTERVAL_VALUE</td><td>1</td></tr>
|
||||
<tr><td>click</td><td>ON_COMPLETION</td><td></td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="EVENT_DEFINITION"]').value = 'DELETE FROM albums WHERE interprets = 0'</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Event has been created.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter</td><td></td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop no_albums?</td><td></td></tr>
|
||||
<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>
|
||||
<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>
|
||||
<tr><td>type</td><td>fields[1][field]</td><td>interpret_name</td></tr>
|
||||
<tr><td>select</td><td>fields[1][type]</td><td>label=varchar</td></tr>
|
||||
<tr><td>type</td><td>fields[1][length]</td><td>50</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][field]</td><td>album_title</td></tr>
|
||||
<tr><td>select</td><td>fields[1.1][type]</td><td>label=varchar</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][length]</td><td>50</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="definition"]').value = 'BEGIN\nSELECT id INTO @interpret FROM interprets WHERE name = interpret_name;\nIF @interpret IS NULL THEN\n INSERT INTO interprets (name) VALUES (interpret_name);\n SET @interpret = LAST_INSERT_ID();\nEND IF;\nINSERT INTO albums (interpret, title) VALUES (@interpret, album_title);\nEND'</td><td></td></tr>
|
||||
<tr><td>type</td><td>name</td><td>insert_album</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Routine has been created.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=insert_album</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[interpret_name]</td><td>Michael Jackson</td></tr>
|
||||
<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>
|
||||
<tr><td>clickAndWait</td><td>link=adminer_test</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>
|
||||
<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" 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>
|
||||
<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>
|
||||
<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>
|
280
tests/mssql.html
Normal file
280
tests/mssql.html
Normal file
@@ -0,0 +1,280 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
|
||||
<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>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/</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=MS SQL</td></tr>
|
||||
<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>//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>
|
||||
<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>
|
||||
<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=int</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=varchar</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][length]</td><td>50</td></tr>
|
||||
<tr><td>uncheck</td><td>name=comments</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>name=comments</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][comment]</td><td>Interpret</td></tr>
|
||||
<tr><td>type</td><td>Comment</td><td>Interprets</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">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>
|
||||
<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>Table 'interprets' already has a primary key defined on it.</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/?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>
|
||||
<tr><td>type</td><td>name</td><td>albums</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=int</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=varchar</td></tr>
|
||||
<tr><td>type</td><td>fields[1.11][length]</td><td>50</td></tr>
|
||||
<tr><td>check</td><td>name=comments</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][comment]</td><td>Interpret</td></tr>
|
||||
<tr><td>type</td><td>fields[1.11][comment]</td><td>Album</td></tr>
|
||||
<tr><td>type</td><td>Comment</td><td>Albums</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/?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>
|
||||
<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/?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>
|
||||
<tr><td>click</td><td>add[2]</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[3][field]</td><td>albums</td></tr>
|
||||
<tr><td>select</td><td>fields[3][type]</td><td>label=int</td></tr>
|
||||
<tr><td>type</td><td>fields[3][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[3][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">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>//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>
|
||||
<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>
|
||||
<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/?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>
|
||||
<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>open</td><td>/adminer/?mssql=%28local%29&username=ODBC&db=adminer_test&ns=dbo&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/?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>
|
||||
<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/?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>
|
||||
<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>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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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/?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>
|
||||
<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/?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>
|
||||
<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 [dbo].[interprets]</td><td></td></tr>
|
||||
<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" 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>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Are you sure?</td><td></td></tr>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
@@ -3,14 +3,12 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
|
||||
<title>katalon</title>
|
||||
<title>Katalon MySQL</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- The tests don't work with jush-textarea.js. Delete it first. -->
|
||||
|
||||
<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>
|
||||
@@ -18,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>
|
||||
@@ -37,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>
|
||||
@@ -59,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>
|
||||
@@ -75,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>
|
||||
@@ -98,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>
|
||||
@@ -121,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>
|
||||
@@ -133,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>
|
||||
@@ -150,50 +141,49 @@
|
||||
<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>
|
||||
<tr><td>type</td><td>name=Statement</td><td>UPDATE interprets SET albums = albums + 1 WHERE id = NEW.interpret</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="Statement"]').value = 'UPDATE interprets SET albums = albums + 1 WHERE id = NEW.interpret'</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>
|
||||
<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=clause</td><td>interpret > 0</td></tr>
|
||||
<tr><td>click</td><td>xpath=//input[@value='Save']</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>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Check has been created.</td><td></td></tr>
|
||||
<tr><td>open</td><td>/adminer/?username=ODBC&db=adminer_test&check=albums&name=albums_chk_1</td><td></td></tr>
|
||||
<tr><td>verifyText</td><td>name=clause</td><td>(`interpret` > 0)</td></tr>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Drop albums_chk_1?</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>type</td><td>select</td><td>SELECT albums.id, albums.title, interprets.name
|
||||
FROM albums
|
||||
LEFT JOIN interprets ON albums.interpret = interprets.id</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>
|
||||
<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>
|
||||
@@ -205,10 +195,9 @@ LEFT JOIN interprets ON albums.interpret = interprets.id</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>
|
||||
<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>
|
||||
@@ -217,10 +206,9 @@ LEFT JOIN interprets ON albums.interpret = interprets.id</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>
|
||||
<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>
|
||||
@@ -228,29 +216,26 @@ LEFT JOIN interprets ON albums.interpret = interprets.id</td></tr>
|
||||
<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>
|
||||
@@ -259,10 +244,9 @@ LEFT JOIN interprets ON albums.interpret = interprets.id</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>
|
||||
<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>
|
||||
@@ -271,10 +255,9 @@ LEFT JOIN interprets ON albums.interpret = interprets.id</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">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>
|
||||
@@ -300,18 +283,16 @@ LEFT JOIN interprets ON albums.interpret = interprets.id</td></tr>
|
||||
<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>
|
||||
@@ -324,17 +305,16 @@ LEFT JOIN interprets ON albums.interpret = interprets.id</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">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>
|
||||
<tr><td>select</td><td>INTERVAL_FIELD</td><td>label=DAY</td></tr>
|
||||
<tr><td>type</td><td>INTERVAL_VALUE</td><td>1</td></tr>
|
||||
<tr><td>click</td><td>ON_COMPLETION</td><td></td></tr>
|
||||
<tr><td>type</td><td>EVENT_DEFINITION</td><td>DELETE FROM albums WHERE interprets = 0</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="EVENT_DEFINITION"]').value = 'DELETE FROM albums WHERE interprets = 0'</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Event has been created.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=Alter</td><td></td></tr>
|
||||
@@ -342,10 +322,9 @@ LEFT JOIN interprets ON albums.interpret = interprets.id</td></tr>
|
||||
<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>
|
||||
@@ -355,14 +334,7 @@ LEFT JOIN interprets ON albums.interpret = interprets.id</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][field]</td><td>album_title</td></tr>
|
||||
<tr><td>select</td><td>fields[1.1][type]</td><td>label=varchar</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][length]</td><td>50</td></tr>
|
||||
<tr><td>type</td><td>definition</td><td>BEGIN
|
||||
SELECT id INTO @interpret FROM interprets WHERE name = interpret_name;
|
||||
IF @interpret IS NULL THEN
|
||||
INSERT INTO interprets (name) VALUES (interpret_name);
|
||||
SET @interpret = LAST_INSERT_ID();
|
||||
END IF;
|
||||
INSERT INTO albums (interpret, title) VALUES (@interpret, album_title);
|
||||
END</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="definition"]').value = 'BEGIN\nSELECT id INTO @interpret FROM interprets WHERE name = interpret_name;\nIF @interpret IS NULL THEN\n INSERT INTO interprets (name) VALUES (interpret_name);\n SET @interpret = LAST_INSERT_ID();\nEND IF;\nINSERT INTO albums (interpret, title) VALUES (@interpret, album_title);\nEND'</td><td></td></tr>
|
||||
<tr><td>type</td><td>name</td><td>insert_album</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Routine has been created.</td><td></td></tr>
|
||||
@@ -370,51 +342,78 @@ END</td></tr>
|
||||
<tr><td>type</td><td>fields[interpret_name]</td><td>Michael Jackson</td></tr>
|
||||
<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, 1 row affected.</td><td></td></tr>
|
||||
<tr><td>assertTextPresent</td><td>Routine has been called,</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=adminer_test</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>
|
||||
<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>
|
||||
@@ -426,61 +425,9 @@ END</td></tr>
|
||||
<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">SQLite</td></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>open</td><td>/adminer/sqlite.php</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>name=auth[password]</td><td></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>
|
||||
<tr><td>type</td><td>name=name</td><td>adminer_test</td></tr>
|
||||
<tr><td>click</td><td>css=input[type="submit"]</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Please use one of the extensions</td><td></td></tr>
|
||||
<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>
|
||||
<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>
|
||||
<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>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>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>
|
||||
<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>
|
||||
@@ -489,5 +436,6 @@ END</td></tr>
|
||||
<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>
|
||||
</html>
|
352
tests/pgsql.html
Normal file
352
tests/pgsql.html
Normal file
@@ -0,0 +1,352 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
|
||||
<title>Katalon PostgreSQL</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<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>
|
||||
<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=PostgreSQL</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>type</td><td>name=auth[db]</td><td>adminer_test</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>
|
||||
<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>
|
||||
<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=character varying</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][length]</td><td>50</td></tr>
|
||||
<tr><td>uncheck</td><td>name=comments</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>name=comments</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][comment]</td><td>Interpret</td></tr>
|
||||
<tr><td>type</td><td>Comment</td><td>Interprets</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">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>
|
||||
<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>multiple primary keys for table "interprets" are not allowed</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/?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>
|
||||
<tr><td>type</td><td>name</td><td>albums</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=character varying</td></tr>
|
||||
<tr><td>type</td><td>fields[1.11][length]</td><td>50</td></tr>
|
||||
<tr><td>check</td><td>name=comments</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][comment]</td><td>Interpret</td></tr>
|
||||
<tr><td>type</td><td>fields[1.11][comment]</td><td>Album</td></tr>
|
||||
<tr><td>type</td><td>Comment</td><td>Albums</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/?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>
|
||||
<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/?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>
|
||||
<tr><td>click</td><td>add[2]</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[3][field]</td><td>albums</td></tr>
|
||||
<tr><td>select</td><td>fields[3][type]</td><td>label=integer</td></tr>
|
||||
<tr><td>type</td><td>fields[3][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[3][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">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>//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>
|
||||
<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>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">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>
|
||||
<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>
|
||||
<tr><td>open</td><td>/adminer/?pgsql=&username=ODBC&db=adminer_test&ns=public&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 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/?pgsql=&username=ODBC&db=adminer_test&ns=public&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>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" 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>
|
||||
<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>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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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/?pgsql=&username=ODBC&db=adminer_test&ns=public&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">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>
|
||||
<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>
|
||||
<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 "public"."interprets"</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">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>
|
||||
<tr><td>type</td><td>fields[1][field]</td><td>interpret_name</td></tr>
|
||||
<tr><td>select</td><td>fields[1][type]</td><td>label=character varying</td></tr>
|
||||
<tr><td>type</td><td>fields[1][length]</td><td>50</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][field]</td><td>album_title</td></tr>
|
||||
<tr><td>select</td><td>fields[1.1][type]</td><td>label=character varying</td></tr>
|
||||
<tr><td>type</td><td>fields[1.1][length]</td><td>50</td></tr>
|
||||
<tr><td>runScript</td><td>document.querySelector('[name="definition"]').value = 'SELECT id FROM interprets;'</td><td></td></tr>
|
||||
<tr><td>type</td><td>name</td><td>insert_album</td></tr>
|
||||
<tr><td>select</td><td>name=language</td><td>label=sql</td></tr>
|
||||
<tr><td>clickAndWait</td><td>//input[@value='Save']</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Routine has been created.</td><td></td></tr>
|
||||
<tr><td>clickAndWait</td><td>link=insert_album</td><td></td></tr>
|
||||
<tr><td>type</td><td>fields[interpret_name]</td><td>Michael Jackson</td></tr>
|
||||
<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>
|
||||
<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>
|
||||
<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" 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>
|
||||
<tr><td>chooseOkOnNextConfirmation</td><td>Are you sure?</td><td></td></tr>
|
||||
<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>
|
||||
<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>
|
||||
<tbody>
|
||||
<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>
|
||||
<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>
|
276
tests/sqlite.html
Normal file
276
tests/sqlite.html
Normal file
@@ -0,0 +1,276 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
|
||||
<title>Katalon SQLite</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table cellpadding="1" cellspacing="1" border="1">
|
||||
<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>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>
|
||||
<tr><td>type</td><td>name=name</td><td>adminer_test</td></tr>
|
||||
<tr><td>click</td><td>css=input[type="submit"]</td><td></td></tr>
|
||||
<tr><td>verifyTextPresent</td><td>Please use one of the extensions</td><td></td></tr>
|
||||
<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>
|
||||
</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>
|
||||
</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>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>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