1
0
mirror of https://github.com/vrana/adminer.git synced 2025-09-04 03:35:41 +02:00

Compare commits

..

71 Commits

Author SHA1 Message Date
Jakub Vrana
967647759e Release 5.0.5 2025-03-13 18:28:43 +01:00
Jakub Vrana
e4323ced55 Tests: Fix CockroachDB after 48308f3 2025-03-13 18:22:06 +01:00
Jakub Vrana
85c6af6f87 Compile: strip space after CSS comment 2025-03-13 18:00:54 +01:00
Jakub Vrana
9226804aa2 CSS: Move media selector to <link> 2025-03-13 17:55:42 +01:00
Jakub Vrana
041e7064ca php_shrink: Simplify test 2025-03-13 17:45:16 +01:00
Jakub Vrana
4c2a8b0050 Compile: Move ?><? removal to php_shrink 2025-03-13 17:43:20 +01:00
Jakub Vrana
9afbf1a465 Compile: dark.css 2025-03-13 17:33:19 +01:00
Jakub Vrana
352ef9c778 CSS: Don't use dark theme with adminer.css 2025-03-13 17:11:40 +01:00
Jakub Vrana
45107dc46e Don't highlight NULL as JSON 2025-03-13 16:55:17 +01:00
Jakub Vrana
21f3426adb Design: Update dark mode (by rmsoft) 2025-03-13 16:48:56 +01:00
Jakub Vrana
95dccfe9fb MongoDB: Rename file 2025-03-13 15:21:19 +01:00
Jakub Vrana
fe88f83c95 Elastic: Fix number of rows in group queries 2025-03-13 14:34:26 +01:00
Jakub Vrana
078957fe32 MongoDB: Move to plugin 2025-03-13 14:27:54 +01:00
Jakub Vrana
61f07867f9 Update readme 2025-03-13 14:09:45 +01:00
Jakub Vrana
0135dd5b81 Tests: Add tests for MS SQL 2025-03-13 14:07:31 +01:00
Jakub Vrana
773a2253d3 Export: Display unknown number of rows as ? 2025-03-13 13:29:10 +01:00
Jakub Vrana
272042a30e Fix skipOriginal after unconvertFunction 2025-03-13 13:13:06 +01:00
Jakub Vrana
48308f3357 CockroachDB: Recognize unique_rowid() as auto_increment 2025-03-13 13:09:05 +01:00
Jakub Vrana
c90033a962 Test PostgreSQL: SQL command 2025-03-13 13:03:24 +01:00
Jakub Vrana
8bd022f974 CockroachDB: Fix test 2025-03-13 13:02:53 +01:00
Jakub Vrana
b1550b052d MySQL: Simplify checking for MariaDB 2025-03-13 12:24:35 +01:00
Jakub Vrana
9862846a7c CockroachDB: Declare support 2025-03-13 12:15:37 +01:00
Jakub Vrana
f14e3e38f6 CockroachDB: Disable processlist 2025-03-13 12:12:44 +01:00
Jakub Vrana
95262c4215 CSS: Fix style 2025-03-13 12:08:01 +01:00
Jakub Vrana
dacfdc4608 Tests: Work with JUSH textarea 2025-03-13 12:07:49 +01:00
Jakub Vrana
7636c253fb CockroachDB: Display version 2025-03-13 11:51:03 +01:00
Jakub Vrana
44d26a9dd3 Tests: Add tests for CockroachDB 2025-03-13 11:08:42 +01:00
Jakub Vrana
b229e7b583 Tests: Add tests for MariaDB and PostgreSQL 2025-03-13 10:45:53 +01:00
Jakub Vrana
8e91417be1 MySQL: Display converting function for binary, bit or geometry fields 2025-03-13 07:50:20 +01:00
Peter Knut
db7202fcf0 MySQL: Fix saving string default value of json field 2025-03-13 07:19:27 +01:00
Jakub Vrana
260487fbc2 Designs: Update rmsoft (fix #911) 2025-03-13 07:10:23 +01:00
Jakub Vrana
3ae964c915 Designs: Fix price 2025-03-13 07:06:43 +01:00
Jakub Vrana
d56c8cbaae CSS: Simplify .odds 2025-03-13 07:03:42 +01:00
Jakub Vrana
d347f88c54 Design: Update rmsoft (fix #911) 2025-03-13 06:38:32 +01:00
Jakub Vrana
b9b4db0c8e Compile: Add more php_shrink tests 2025-03-13 06:10:58 +01:00
Jakub Vrana
818b9ad903 Compile: Strip public 2025-03-12 23:15:24 +01:00
Jakub Vrana
4a6436773f Compile: Add tests for php_shrink 2025-03-12 23:15:22 +01:00
Jakub Vrana
81594e4a2d Issues: Prefer MySQLi 2025-03-12 18:28:56 +01:00
Jakub Vrana
f0bdb0e6ca Designs: Update .odds 2025-03-12 17:50:24 +01:00
Jakub Vrana
b9e4806d3c CSS: lowercase color names 2025-03-12 17:43:58 +01:00
Jakub Vrana
7e708dae57 CSS: Add dark theme 2025-03-12 17:42:53 +01:00
Jakub Vrana
a0fe44ec18 CSS: Expand <code> in <pre> 2025-03-12 17:35:44 +01:00
Jakub Vrana
eb0f280776 CSS: Fix highlighting checked odd rows 2025-03-12 17:35:34 +01:00
Jakub Vrana
3b1189cd3c MySQL: Allow setting default values of json column 2025-03-12 14:25:19 +01:00
Jakub Vrana
434a8f7705 CSS: Disable odd on hover 2025-03-12 13:58:20 +01:00
Jakub Vrana
f9478c67d2 CSS: Merge rules 2025-03-12 12:57:59 +01:00
Jakub Vrana
f2ce6c0a71 Wrap long lines 2025-03-12 11:43:21 +01:00
Jakub Vrana
a50b3d6385 MS SQL: Fix editing rows with datetime column in primary key
Inspired by adminneo-org@b4afc08.
This fixes https://sourceforge.net/p/adminer/discussion/960418/thread/a547e79622/.
2025-03-12 09:28:22 +01:00
Jakub Vrana
e39deca4f1 Wrap Schema: in navigation to <span> (fix #907) 2025-03-12 09:26:04 +01:00
Jakub Vrana
ce69970f54 Update German translation (by @wintstar) 2025-03-12 09:09:09 +01:00
Jakub Vrana
51ac1312a1 MariaDB: Don't display NULL as default value 2025-03-12 08:51:25 +01:00
Jakub Vrana
4505544953 Code style: exclude removed extensions 2025-03-12 08:12:28 +01:00
Jakub Vrana
fa75213ff6 Coverage: Fix newlines 2025-03-12 06:15:47 +01:00
Jakub Vrana
63acb37ea6 Coverage: Display drivers 2025-03-12 06:09:18 +01:00
Jakub Vrana
3ad6c16f59 Coverage: Modernize HTML 2025-03-12 06:06:28 +01:00
Jakub Vrana
22d08b4a50 Add comment 2025-03-12 06:01:29 +01:00
Jakub Vrana
dd3cc4e683 Add plugin AdminerEditorViews (fix #905) 2025-03-12 05:22:57 +01:00
Jakub Vrana
5504a617d0 Compile: Support private static 2025-03-12 05:03:42 +01:00
Jakub Vrana
2fdebfda29 Ensure PHP 5.3 compatibility 2025-03-11 21:43:59 +01:00
Jakub Vrana
dc2e945aef MySQL: Convert binary default value to hex when editing 2025-03-11 20:25:52 +01:00
Jakub Vrana
43d86287c4 Fix focusing first field 2025-03-11 20:16:49 +01:00
Jakub Vrana
a94a727af7 PostgreSQL PDO: Escape bytea values (bug #218) 2025-03-11 19:42:10 +01:00
Jakub Vrana
c2d29a6937 MySQL: Display default values of binary columns 2025-03-11 19:25:42 +01:00
Jakub Vrana
c082136558 Rename variable 2025-03-11 18:40:34 +01:00
Jakub Vrana
7b1ea5fa2c AdminerDumpAlter: Use dumpFooter 2025-03-11 18:20:11 +01:00
Jakub Vrana
156839142e Fix plugin AdminerPrettyJsonColumn 2025-03-11 18:16:44 +01:00
Jakub Vrana
2ee4e3b2e1 Compile: Fix shortening in protected functions 2025-03-11 17:56:21 +01:00
Jakub Vrana
8b4c8b0156 Fix coverage 2025-03-11 14:37:08 +01:00
Jakub Vrana
9702878297 Develop 2025-03-11 14:00:37 +01:00
Jakub Vrana
4a54648995 Release 5.0.4 2025-03-11 13:52:53 +01:00
Jakub Vrana
2e5027a1aa Compile: Fix shortening in private methods 2025-03-11 13:50:36 +01:00
66 changed files with 1979 additions and 429 deletions

View File

@@ -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.

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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"));
}
@@ -432,6 +439,7 @@ if (!defined('Adminer\DRIVER')) {
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
$connection->set_charset(charset($connection)); // available in MySQLi since PHP 5.0.5
$connection->query("SET sql_quote_show_create = 1, autocommit = 1");
$connection->maria = preg_match('~MariaDB~', $connection->server_info);
return $connection;
}
$return = $connection->error;
@@ -587,11 +595,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 +608,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 +675,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 +824,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 +1000,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 +1012,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 +1212,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) {

View File

@@ -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\'

View File

@@ -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() {
@@ -331,6 +326,8 @@ if (isset($_GET["pgsql"])) {
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) : "");
return $connection;
}
return $connection->error;
@@ -432,7 +429,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 +464,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 +483,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 +708,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 +953,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 ($feature == "processlist"
? !preg_match('~CockroachDB~', $connection->server_info) // https://github.com/cockroachdb/cockroach/issues/24745
: preg_match('~^(check|database|table|columns|sql|indexes|descidx|comment|view|' . (min_version(9.3) ? 'materializedview|' : '') . 'scheme|routine|sequence|trigger|type|variables|drop_col|kill|dump)$~', $feature)
);
}
function kill_process($val) {

View File

@@ -78,7 +78,7 @@ if (isset($_GET["sqlite"])) {
);
}
function __desctruct() {
function __destruct() {
return $this->result->finalize();
}
}

View File

@@ -9,6 +9,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', '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'));

View File

@@ -98,7 +98,7 @@ class Adminer {
*/
function head() {
?>
<link rel="stylesheet" type="text/css" href="../externals/jush/jush.css">
<link rel="stylesheet" href="../externals/jush/jush.css">
<?php
return true;
}
@@ -289,13 +289,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);
}
@@ -1030,9 +1031,8 @@ class Adminer {
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" : ""); ?>);
bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '\1', $connection->server_info) : ""); ?>'<?php echo ($connection->maria ? ", true" : ""); ?>);
</script>
<?php
}
@@ -1076,14 +1076,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"]);
}

View File

@@ -62,7 +62,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,7 +72,6 @@ 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);
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver

View File

@@ -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);

View File

@@ -28,15 +28,22 @@ 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"); ?>
<link rel="stylesheet" href="../adminer/static/default.css">
<?php
$css = $adminer->css();
if ($css) {
foreach ($css as $val) {
echo "<link rel='stylesheet' href='" . h($val) . "'>\n";
}
} else {
echo "<link rel='stylesheet' media='(prefers-color-scheme: dark)' href='../adminer/static/dark.css'>\n";
}
echo script_src("../adminer/static/functions.js");
echo script_src("static/editing.js");
?>
<?php if ($adminer->head()) { ?>
<link rel="shortcut icon" type="image/x-icon" href="../adminer/static/favicon.ico">
<link rel="apple-touch-icon" href="../adminer/static/favicon.ico">
<?php 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">

View File

@@ -13,13 +13,12 @@ function add_driver($id, $name) {
$drivers[$id] = $name;
}
/** Get driver name
* @param string
* @return string
/** Get driver
* @return Driver
*/
function get_driver($id) {
global $drivers;
return $drivers[$id];
function get_driver() {
global $driver;
return $driver;
}
abstract class SqlDriver {
@@ -66,6 +65,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]

View File

@@ -224,13 +224,19 @@ function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_ty
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 ($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 +313,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))
)
));
@@ -624,7 +630,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']));
}

View File

@@ -459,14 +459,15 @@ 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
: (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";
}
}
@@ -933,6 +934,7 @@ function input($field, $value, $function) {
$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 {
@@ -1423,6 +1425,7 @@ function edit_form($table, $fields, $row, $update) {
<form action="" method="post" enctype="multipart/form-data" id="form">
<?php
$first = 0;
$is_first = true;
if (!$fields) {
echo "<p class='error'>" . lang('You have no privileges to update this table.') . "\n";
} else {
@@ -1435,6 +1438,9 @@ function edit_form($table, $fields, $row, $update) {
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])
@@ -1467,8 +1473,10 @@ function edit_form($table, $fields, $row, $update) {
$value = "";
$function = "uuid";
}
if ($field["auto_increment"] || $function == "now" || $function == "uuid") {
if ($is_first && ($field["auto_increment"] || $function == "now" || $function == "uuid")) {
$first++;
} else {
$is_first = false;
}
input($field, $value, $function);
echo "\n";

View File

@@ -74,7 +74,7 @@ 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
: (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];

View File

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

View File

@@ -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',
);

View File

@@ -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";
}
}
}

View File

@@ -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", "?");
}
}
}

View File

@@ -452,7 +452,7 @@ 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"]);
$text = preg_match('~text|json|lob~', $field["type"]);
echo "<td id='$id'";
if (($_GET["modify"] && $editable) || $value !== null) {
$h_value = h($value !== null ? $value : $row[$key]);

47
adminer/static/dark.css Normal file
View File

@@ -0,0 +1,47 @@
/** @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; }
code[class^="jush-"] { color: #002240; background: #81a0bc; padding: .2em .5em; }
tbody tr:hover td, tbody tr:hover th { background: #133553; }
pre.jush { background: #a7c3dc; }
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; }

View File

@@ -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; }

View File

@@ -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;
}

View File

@@ -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"])

View File

@@ -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";

View File

@@ -1,3 +1,18 @@
Adminer 5.0.5 (released 2025-03-13):
MySQL: Display converting function for binary, bit or geometry fields
MySQL: Display default values of binary columns
MySQL: Allow setting default values of json column
MariaDB: Don't display NULL as default value (regression from 5.0.0)
PostgreSQL PDO: Escape bytea values (bug #218)
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
@@ -78,7 +93,7 @@ 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: 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 #847)
Mobile devices: Use device width
Adminer 4.16.0 (released 2025-02-20):

View File

@@ -2,12 +2,9 @@
<?php
include __DIR__ . "/adminer/include/version.inc.php";
include __DIR__ . "/adminer/include/errors.inc.php";
include __DIR__ . "/php_shrink.inc.php";
include __DIR__ . "/externals/JsShrink/jsShrink.php";
function add_apo_slashes($s) {
return addcslashes($s, "\\'");
}
function add_quo_slashes($s) {
$return = $s;
$return = addcslashes($return, "\n\r\$\"\\");
@@ -212,129 +209,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 +235,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;
}
@@ -414,6 +282,7 @@ include __DIR__ . "/adminer/include/driver.inc.php";
$features = array("check", "call" => "routine", "dump", "event", "privileges", "procedure" => "routine", "processlist", "routine", "scheme", "sequence", "status", "trigger", "type", "user" => "privileges", "variables", "view");
$lang_ids = array(); // global variable simplifies usage in a callback function
$file = file_get_contents(__DIR__ . "/$project/index.php");
$file = preg_replace('~\*/~', "* @version $VERSION\n*/", $file, 1);
if ($driver) {
$_GET[$driver] = true; // to load the driver
include_once __DIR__ . $driver_path;
@@ -446,7 +315,7 @@ if ($driver) {
}
if (count($drivers) == 1) {
$file = str_replace('html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);")', "\"<input type='hidden' name='auth[driver]' value='" . ($driver == "mysql" ? "server" : $driver) . "'>" . reset($drivers) . "\"", $file, $count);
if (!$count) {
if (!$count && $project != "editor") {
echo "auth[driver] form field not found\n";
}
$file = str_replace(" . script(\"qs('#username').form['auth[driver]'].onchange();\")", "", $file);
@@ -472,16 +341,15 @@ 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 = str_replace('<link rel="stylesheet" href="../externals/jush/jush.css">' . "\n", "", $file); // merged into default.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/(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);
$filename = $project . (preg_match('~-dev$~', $VERSION) ? "" : "-$VERSION") . ($driver ? "-$driver" : "") . ($_SESSION["lang"] ? "-$_SESSION[lang]" : "") . ".php";

View File

@@ -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();
@@ -24,17 +25,18 @@ function xhtml_open_tags($s) {
$coverage_filename = sys_get_temp_dir() . "/adminer_coverage.ser";
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>

View File

@@ -198,7 +198,7 @@ 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 td,thead th,.odds tbody tr:nth-child(2n),tbody tr:hover td,tbody tr:hover th,.js .checkable .checked td,.js .checkable .checked th{background:transparent}
thead tr{background:#282b2f;border-bottom:1px solid rgba(255,255,255,0.1)}
thead td,thead th{padding:7px 10px;background:transparent;text-align:left}
tbody th,tbody td{vertical-align:top}

View File

@@ -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 {

View File

@@ -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);
}

View File

@@ -133,7 +133,7 @@ th {
background:white;
}
.odds tbody tr:nth-child(2n) td {
.odds tbody tr:nth-child(2n) {
background:#fcfaf5;
}

View File

@@ -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;}

View File

@@ -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
}

View File

@@ -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;
}

View File

@@ -132,7 +132,7 @@ th {
background:white;
}
.odds tbody tr:nth-child(2n) td {
.odds tbody tr:nth-child(2n) {
background:#fcfaf5;
}

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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; }

View File

@@ -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;
}

View File

@@ -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}

View File

@@ -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}

View File

@@ -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}

View File

@@ -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}

View File

@@ -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"]);

View File

@@ -90,7 +90,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) {
@@ -632,7 +635,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/jush vendored

144
php_shrink.inc.php Normal file
View File

@@ -0,0 +1,144 @@
<?php
/** Minify PHP code with these operations:
* remove extra {}
* minify variables
* strip comments, preserve only the first doc-comment
* join consecutive echo
* change ?>HTML<?php to echo 'HTML' if it saves space
* strip public visibility or change it to var
*
* @param string PHP code including <?php
* @return string
*/
function php_shrink($input) {
// based on http://latrine.dgx.cz/jak-zredukovat-php-skripty
$input = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $input);
$special_variables = array_flip(array('$this', '$GLOBALS', '$_GET', '$_POST', '$_FILES', '$_COOKIE', '$_SESSION', '$_SERVER', '$http_response_header', '$php_errormsg'));
$short_variables = array();
$shortening = true;
$tokens = token_get_all($input);
// remove unnecessary { }
//! change also `while () { if () {;} }` to `while () if () ;` but be careful about `if () { if () { } } else { }
$shorten = 0;
$opening = -1;
foreach ($tokens as $i => $token) {
if (in_array($token[0], array(T_IF, T_ELSE, T_ELSEIF, T_WHILE, T_DO, T_FOR, T_FOREACH), true)) {
$shorten = ($token[0] == T_FOR ? 4 : 2);
$opening = -1;
} elseif (in_array($token[0], array(T_SWITCH, T_FUNCTION, T_CLASS, T_CLOSE_TAG), true)) {
$shorten = 0;
} elseif ($token === ';') {
$shorten--;
} elseif ($token === '{') {
if ($opening < 0) {
$opening = $i;
} elseif ($shorten > 1) {
$shorten = 0;
}
} elseif ($token === '}' && $opening >= 0 && $shorten == 1) {
unset($tokens[$opening]);
unset($tokens[$i]);
$shorten = 0;
$opening = -1;
}
}
$tokens = array_values($tokens);
foreach ($tokens as $i => $token) {
if ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
$short_variables[$token[1]]++;
}
}
arsort($short_variables);
$chars = implode(range('a', 'z')) . '_' . implode(range('A', 'Z'));
//! preserve variable names between versions if possible
$short_variables2 = array_splice($short_variables, strlen($chars));
ksort($short_variables);
ksort($short_variables2);
$short_variables += $short_variables2;
foreach (array_keys($short_variables) as $number => $key) {
$short_variables[$key] = short_identifier($number, $chars); // could use also numbers and \x7f-\xff
}
$set = array_flip(preg_split('//', '!"#$%&\'()*+,-./:;<=>?@[]^`{|}'));
$space = '';
$output = '';
$in_echo = false;
$doc_comment = false; // include only first /**
for (reset($tokens); list($i, $token) = each($tokens);) {
if (!is_array($token)) {
$token = array(0, $token);
}
if (
$tokens[$i+2][0] === T_CLOSE_TAG && $tokens[$i+3][0] === T_INLINE_HTML && $tokens[$i+4][0] === T_OPEN_TAG
&& strlen(add_apo_slashes($tokens[$i+3][1])) < strlen($tokens[$i+3][1]) + 3
) {
$tokens[$i+2] = array(T_ECHO, 'echo');
$tokens[$i+3] = array(T_CONSTANT_ENCAPSED_STRING, "'" . add_apo_slashes($tokens[$i+3][1]) . "'");
$tokens[$i+4] = array(0, ';');
}
if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE || ($token[0] == T_DOC_COMMENT && $doc_comment)) {
$space = "\n";
} else {
if ($token[0] == T_DOC_COMMENT) {
$doc_comment = true;
}
if ($token[0] == T_VAR || $token[0] == T_PUBLIC || $token[0] == T_PROTECTED || $token[0] == T_PRIVATE) {
if ($token[0] == T_PUBLIC) {
$token[1] = ($tokens[$i+2][1][0] == '$' ? 'var' : '');
}
$shortening = false;
} elseif (!$shortening) {
if ($token[1] == ';' || $token[0] == T_FUNCTION) {
$shortening = true;
}
} elseif ($token[0] == T_ECHO) {
$in_echo = true;
} elseif ($token[1] == ';' && $in_echo) {
if ($tokens[$i+1][0] === T_WHITESPACE && $tokens[$i+2][0] === T_ECHO) {
next($tokens);
$i++;
}
if ($tokens[$i+1][0] === T_ECHO) {
// join two consecutive echos
next($tokens);
$token[1] = ','; // '.' would conflict with "a".1+2 and would use more memory //! remove ',' and "," but not $var","
} else {
$in_echo = false;
}
} elseif ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
$token[1] = '$' . $short_variables[$token[1]];
}
if (isset($set[substr($output, -1)]) || isset($set[$token[1][0]])) {
$space = '';
}
$output .= $space . $token[1];
$space = '';
}
}
return $output;
}
function short_identifier($number, $chars) {
$return = '';
while ($number >= 0) {
$return .= $chars[$number % strlen($chars)];
$number = floor($number / strlen($chars)) - 1;
}
return $return;
}
function add_apo_slashes($s) {
return addcslashes($s, "\\'");
}
if (!function_exists("each")) {
function each(&$arr) {
$key = key($arr);
next($arr);
return $key === null ? false : array($key, $arr[$key]);
}
}

View File

@@ -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. -->
@@ -45,7 +45,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 +108,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>

View File

@@ -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),

View File

@@ -1,7 +1,7 @@
<?php
namespace Adminer;
$drivers["mongo"] = "MongoDB (alpha)";
add_driver("mongo", "MongoDB (alpha)");
if (isset($_GET["mongo"])) {
define('Adminer\DRIVER', "mongo");
@@ -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 = get_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;
}

View File

@@ -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);

View File

@@ -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();
}
}
}

14
plugins/editor-views.php Normal file
View 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"]);
}
}

View File

@@ -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];

View File

@@ -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;
@@ -33,6 +30,5 @@ class AdminerPrettyJsonColumn {
$value = json_encode($json);
}
}
return $this->adminer->_callParent('processInput', array($field, $value, $function));
}
}

View File

@@ -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>";

View File

@@ -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

307
tests/cocroachdb.html Normal file
View File

@@ -0,0 +1,307 @@
<?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 &gt; 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>xpath=//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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;table=albums</td><td></td></tr>
<tr><td>click</td><td>link=Create check</td><td></td></tr>
<tr><td>type</td><td>name=name</td><td>albums_interpret_check</td></tr>
<tr><td>runScript</td><td>document.querySelector('[name="clause"]').value = 'interpret > 0'</td><td></td></tr>
<tr><td>click</td><td>xpath=//input[@value='Save']</td><td></td></tr>
<tr><td>verifyTextPresent</td><td>Check has been created.</td><td></td></tr>
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;check=albums&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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/?pgsql=localhost:26257&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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">Explain</td></tr>
</thead>
<tbody>
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;edit=albums&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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>
<!-- This looks like a bug in CockroachDB, not Adminer. <tr><td>verifyTextPresent</td><td>Routine has been dropped.</td><td></td></tr> -->
<tr><td>open</td><td>/adminer/?pgsql=localhost%3A26257&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;sql=DROP+PROCEDURE+%22insert_album%22</td><td></td></tr>
<tr><td>clickAndWait</td><td>//input[@value='Execute']</td><td></td></tr>
</tbody></table>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Drop</td></tr>
</thead>
<tbody>
<tr><td>open</td><td>/adminer/?pgsql=localhost:26257&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;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&amp;username=ODBC&amp;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&amp;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>

398
tests/mariadb.html Normal file
View File

@@ -0,0 +1,398 @@
<?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 &gt; 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>xpath=//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&amp;username=ODBC&amp;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&amp;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&amp;username=ODBC&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;table=albums</td><td></td></tr>
<tr><td>click</td><td>link=Create check</td><td></td></tr>
<tr><td>type</td><td>name=name</td><td>albums_interpret_check</td></tr>
<tr><td>runScript</td><td>document.querySelector('[name="clause"]').value = 'interpret > 0'</td><td></td></tr>
<tr><td>click</td><td>xpath=//input[@value='Save']</td><td></td></tr>
<tr><td>verifyTextPresent</td><td>Check has been created.</td><td></td></tr>
<tr><td>open</td><td>/adminer/?server=localhost:3307&amp;username=ODBC&amp;db=adminer_test&amp;check=albums&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;edit=albums&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;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&amp;username=ODBC&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;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">Variables</td></tr>
</thead>
<tbody>
<tr><td>open</td><td>/adminer/?server=localhost:3307&amp;username=ODBC&amp;variables=</td><td></td></tr>
<tr><td>verifyTextPresent</td><td>basedir</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&amp;username=ODBC&amp;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&amp;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>

265
tests/mssql.html Normal file
View File

@@ -0,0 +1,265 @@
<?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 &gt; 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>xpath=//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&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;table=albums</td><td></td></tr>
<tr><td>click</td><td>link=Create check</td><td></td></tr>
<tr><td>type</td><td>name=name</td><td>albums_interpret_check</td></tr>
<tr><td>runScript</td><td>document.querySelector('[name="clause"]').value = 'interpret > 0'</td><td></td></tr>
<tr><td>click</td><td>xpath=//input[@value='Save']</td><td></td></tr>
<tr><td>verifyTextPresent</td><td>Check has been created.</td><td></td></tr>
<tr><td>open</td><td>/adminer/?mssql=%28local%29&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;check=albums&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;edit=albums&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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&amp;username=ODBC&amp;db=adminer_test&amp;ns=dbo&amp;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">Drop</td></tr>
</thead>
<tbody>
<tr><td>open</td><td>/adminer/?mssql=%28local%29&amp;username=ODBC&amp;db=adminer_test&amp;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&amp;username=ODBC&amp;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&amp;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>

View File

@@ -3,10 +3,9 @@
<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>
@@ -157,7 +156,7 @@
<tbody>
<tr><td>open</td><td>/adminer/?username=ODBC&amp;db=adminer_test&amp;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>
@@ -168,12 +167,13 @@
<tbody>
<tr><td>open</td><td>/adminer/?username=ODBC&amp;db=adminer_test&amp;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>type</td><td>name=name</td><td>albums_interpret_check</td></tr>
<tr><td>runScript</td><td>document.querySelector('[name="clause"]').value = 'interpret > 0'</td><td></td></tr>
<tr><td>click</td><td>xpath=//input[@value='Save']</td><td></td></tr>
<tr><td>verifyTextPresent</td><td>Check has been created.</td><td></td></tr>
<tr><td>open</td><td>/adminer/?username=ODBC&amp;db=adminer_test&amp;check=albums&amp;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>open</td><td>/adminer/?username=ODBC&amp;db=adminer_test&amp;check=albums&amp;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>
@@ -183,9 +183,7 @@
</thead>
<tbody>
<tr><td>open</td><td>/adminer/?username=ODBC&amp;db=adminer_test&amp;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>
@@ -334,7 +332,7 @@ LEFT JOIN interprets ON albums.interpret = interprets.id</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>
@@ -355,14 +353,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,7 +361,7 @@ 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>
@@ -428,57 +419,6 @@ END</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 &gt; 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 &gt; 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>
<tbody>
@@ -490,4 +430,4 @@ END</td></tr>
<tr><td>open</td><td>/coverage.php</td><td></td></tr>
</tbody></table>
</body>
</html>
</html>

310
tests/pgsql.html Normal file
View File

@@ -0,0 +1,310 @@
<?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 &gt; 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>xpath=//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=&amp;username=ODBC&amp;db=adminer_test&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;table=albums</td><td></td></tr>
<tr><td>click</td><td>link=Create check</td><td></td></tr>
<tr><td>type</td><td>name=name</td><td>albums_interpret_check</td></tr>
<tr><td>runScript</td><td>document.querySelector('[name="clause"]').value = 'interpret > 0'</td><td></td></tr>
<tr><td>click</td><td>xpath=//input[@value='Save']</td><td></td></tr>
<tr><td>verifyTextPresent</td><td>Check has been created.</td><td></td></tr>
<tr><td>open</td><td>/adminer/?pgsql=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;check=albums&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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/?pgsql=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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">Explain</td></tr>
</thead>
<tbody>
<tr><td>open</td><td>/adminer/?pgsql=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;edit=albums&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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=&amp;username=ODBC&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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=&amp;username=ODBC&amp;db=adminer_test&amp;ns=public&amp;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">Drop</td></tr>
</thead>
<tbody>
<tr><td>open</td><td>/adminer/?pgsql=&amp;username=ODBC&amp;db=adminer_test&amp;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=&amp;username=ODBC&amp;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=localhost:26257&amp;username=ODBC&amp;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=&amp;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>

36
tests/php_shrink.php Normal file
View File

@@ -0,0 +1,36 @@
<?php
include __DIR__ . "/../adminer/include/errors.inc.php";
include __DIR__ . "/../php_shrink.inc.php";
function check($code, $expected) {
$shrinked = str_replace("\n", " ", php_shrink("<?php\n$code"));
if ("<?php $expected" != $shrinked) {
$backtrace = reset(debug_backtrace());
echo "$backtrace[file]:$backtrace[line]:" . substr($shrinked, 6) . "\n";
}
}
check('$ab = 1; echo $ab;', '$a=1;echo$a;');
check('$ab = 1; $cd = 2;', '$a=1;$b=2;');
check('define("AB", 1);', 'define("AB",1);');
check('function f($ab, $cd = 1) { return $ab; }', 'function f($a,$b=1){return$a;}');
check('class C { var $ab = 1; }', 'class C{var$ab=1;}');
check('class C { public $ab = 1; }', 'class C{var$ab=1;}');
check('class C { protected $ab = 1; }', 'class C{protected$ab=1;}');
check('class C { private $ab = 1; }', 'class C{private$ab=1;}');
check('class C { private $ab = 1; }', 'class C{private$ab=1;}');
check('class C { private function f($ab) { return $ab; }}', 'class C{private function f($a){return$a;}}');
check('class C { public function f($ab) { return $ab; }}', 'class C{function f($a){return$a;}}');
check('class C { private static $ab; }', 'class C{private static$ab;}');
check('class C { const AB = 1; }', 'class C{const AB=1;}');
check('class C { private const AB = 1; }', 'class C{private const AB=1;}');
check('class C { public $ab; function f($cd) { return $cd . $this->ab; }}', 'class C{var$ab;function f($b){return$b.$this->ab;}}');
check('namespace NS { class C { public $ab = 1; } } new NS\C; $ab = 2;', 'namespace NS{class C{var$ab=1;}}new NS\C;$a=2;');
check('new \stdClass;', 'new \stdClass;');
check('if (true) { echo "a"; } else { echo "b"; }', 'if(true)echo"a";else echo"b";');
check('echo $_GET["a"];', 'echo$_GET["a"];');
check('$ab = 1; echo "$ab";', '$a=1;echo"$a";');
check('echo 1; echo 3;', 'echo 1,3;');
check('echo 1; ?>2<?php echo 3;', "echo 1,'2',3;");
check('/** preserve */ $a; /** ignore */ /* also ignore */ // ignore too', '/** preserve */$a;');
check('$a = 1; ?><?php ?><?php $a = 2;', '$a=1;$a=2;');

63
tests/sqlite.html Normal file
View File

@@ -0,0 +1,63 @@
<?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">SQLite</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 &gt; input[type="submit"]</td><td></td></tr>
<tr><td>select</td><td>name=auth[driver]</td><td>label=SQLite</td></tr>
<tr><td>type</td><td>id=username</td><td>admin</td></tr>
<tr><td>type</td><td>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>
<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 &gt; 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 &gt; 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>
</body>
</html>