diff --git a/adminer/drivers/mssql.inc.php b/adminer/drivers/mssql.inc.php index c5ecfdec..88528e9a 100644 --- a/adminer/drivers/mssql.inc.php +++ b/adminer/drivers/mssql.inc.php @@ -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; } diff --git a/adminer/drivers/mysql.inc.php b/adminer/drivers/mysql.inc.php index dde060f8..0ff3cae5 100644 --- a/adminer/drivers/mysql.inc.php +++ b/adminer/drivers/mysql.inc.php @@ -587,7 +587,7 @@ 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; @@ -667,7 +667,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); @@ -987,7 +992,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); @@ -997,7 +1004,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], @@ -1197,7 +1204,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) { diff --git a/adminer/drivers/oracle.inc.php b/adminer/drivers/oracle.inc.php index 6b9726f9..d5e449c9 100644 --- a/adminer/drivers/oracle.inc.php +++ b/adminer/drivers/oracle.inc.php @@ -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\' diff --git a/adminer/drivers/pgsql.inc.php b/adminer/drivers/pgsql.inc.php index e6c3ca10..a62ab6fe 100644 --- a/adminer/drivers/pgsql.inc.php +++ b/adminer/drivers/pgsql.inc.php @@ -427,7 +427,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 @@ -473,7 +480,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(); @@ -693,7 +705,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"; } diff --git a/adminer/include/connect.inc.php b/adminer/include/connect.inc.php index df1bf7bb..474c19b0 100644 --- a/adminer/include/connect.inc.php +++ b/adminer/include/connect.inc.php @@ -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); diff --git a/adminer/include/editing.inc.php b/adminer/include/editing.inc.php index 6d1777dc..351868ae 100644 --- a/adminer/include/editing.inc.php +++ b/adminer/include/editing.inc.php @@ -224,13 +224,19 @@ function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_ty size="3" aria-labelledby="label-length">" : ''); + echo ($collations + ? "" + : '' + ); echo ($driver->unsigned ? "' : ''); echo (isset($field['on_update']) ? "' : '' ); - echo ($foreign_keys ? " " : " "); // space for IE + echo ($foreign_keys + ? " " + : " " // space for IE + ); } /** Get partition info diff --git a/adminer/include/lang.inc.php b/adminer/include/lang.inc.php index df0622d2..4477ccc5 100644 --- a/adminer/include/lang.inc.php +++ b/adminer/include/lang.inc.php @@ -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]; diff --git a/adminer/schema.inc.php b/adminer/schema.inc.php index 680ed288..fefcf661 100644 --- a/adminer/schema.inc.php +++ b/adminer/schema.inc.php @@ -74,7 +74,9 @@ foreach ($schema as $name => $table) { $left1 = $left - $table_pos[$name][1]; $i = 0; foreach ($ref[0] as $source) { - echo "\n
"; + echo "\n
" + . "
" + ; } } } @@ -84,7 +86,8 @@ foreach ($schema as $name => $table) { $left1 = $left - $table_pos[$name][1]; $i = 0; foreach ($columns as $target) { - echo "\n
" + echo "\n
" . "
" . "
" ; diff --git a/adminer/table.inc.php b/adminer/table.inc.php index f3f388a1..eda00fbb 100644 --- a/adminer/table.inc.php +++ b/adminer/table.inc.php @@ -45,7 +45,11 @@ if (!is_view($table_status)) { foreach ($foreign_keys as $name => $foreign_key) { echo ""; echo "" . implode(", ", array_map('Adminer\h', $foreign_key["source"])) . ""; - echo "" + $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 "" . ($foreign_key["db"] != "" && $foreign_key["db"] != DB ? "" . h($foreign_key["db"]) . "." : "") . ($foreign_key["ns"] != "" && $foreign_key["ns"] != $_GET["ns"] ? "" . h($foreign_key["ns"]) . "." : "") . h($foreign_key["table"]) diff --git a/adminer/user.inc.php b/adminer/user.inc.php index 8dd50289..07e3d61e 100644 --- a/adminer/user.inc.php +++ b/adminer/user.inc.php @@ -148,7 +148,10 @@ echo "\n"; echo "\n"; diff --git a/phpcs.xml b/phpcs.xml index 0c5c5351..bc76b8a1 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -12,8 +12,6 @@ - - @@ -24,6 +22,8 @@ + + @@ -45,7 +45,7 @@ - + adminer/lang/ diff --git a/plugins/drivers/clickhouse.php b/plugins/drivers/clickhouse.php index 7fee09ee..c0476e28 100644 --- a/plugins/drivers/clickhouse.php +++ b/plugins/drivers/clickhouse.php @@ -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), diff --git a/plugins/dump-alter.php b/plugins/dump-alter.php index 8c0d6884..1dd21ef1 100644 --- a/plugins/dump-alter.php +++ b/plugins/dump-alter.php @@ -74,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 ''; diff --git a/plugins/foreign-system.php b/plugins/foreign-system.php index 939a53e7..eac99cc9 100644 --- a/plugins/foreign-system.php +++ b/plugins/foreign-system.php @@ -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]; diff --git a/plugins/table-structure.php b/plugins/table-structure.php index fd0428ec..a2ef3d4a 100644 --- a/plugins/table-structure.php +++ b/plugins/table-structure.php @@ -15,7 +15,15 @@ class AdminerTableStructure { function tableStructurePrint($fields) { echo "
\n"; echo "
" . lang('Privileges') . doc_link(array('sql' => "grant.html#priv_level")); $i = 0; foreach ($grants as $object => $grant) { - echo '' . ($object != "*.*" ? "" : "*.*"); //! separate db, table, columns, PROCEDURE|FUNCTION, routine + echo '' . ($object != "*.*" + ? "" + : "*.*" + ); //! separate db, table, columns, PROCEDURE|FUNCTION, routine $i++; } echo "
\n"; - echo "\n"; + echo "" + . "\n" + ; foreach ($fields as $field) { echo "
" . Adminer\lang('Column') . "" . Adminer\lang('Type') . "" . Adminer\lang('Collation') . "" . Adminer\lang('Nullable') . "" . Adminer\lang('Default') . (Adminer\support("comment") ? "" . Adminer\lang('Comment') : "") . "
" . Adminer\lang('Column') + . "" . Adminer\lang('Type') + . "" . Adminer\lang('Collation') + . "" . Adminer\lang('Nullable') + . "" . Adminer\lang('Default') + . (Adminer\support("comment") ? "" . Adminer\lang('Comment') : "") + . "
" . Adminer\h($field["field"]) . ($field["primary"] ? " (PRIMARY)" : ""); echo "" . Adminer\h($field["full_type"]) . "";