diff --git a/adminer/database.inc.php b/adminer/database.inc.php index 90a2c158..0761609e 100644 --- a/adminer/database.inc.php +++ b/adminer/database.inc.php @@ -65,7 +65,7 @@ if ($collations) { \n"; } elseif (!$_POST["add_x"] && $_GET["db"] == "") { echo "\n"; diff --git a/adminer/db.inc.php b/adminer/db.inc.php index 13c210bc..1e4bf485 100644 --- a/adminer/db.inc.php +++ b/adminer/db.inc.php @@ -36,125 +36,128 @@ if ($tables_views && !$error && !$_POST["search"]) { queries_redirect(substr(ME, 0, -1), $message, $result); } -page_header(lang('Database') . ": " . h(DB), $error, true); -echo '

' . lang('Alter database') . "\n"; -echo '' . lang('Database schema') . "\n"; -$sums = array("Data_length" => 0, "Index_length" => 0, "Data_free" => 0); - -echo "

" . lang('Tables and views') . "

\n"; -$tables_list = tables_list(); -if (!$tables_list) { - echo "

" . lang('No tables.') . "\n"; -} else { - echo "

\n"; - echo "

\n"; - if ($_POST["search"] && $_POST["query"] != "") { - $_GET["where"][0]["op"] = "LIKE %%"; - $_GET["where"][0]["val"] = $_POST["query"]; - search_tables(); - } - echo "\n"; - echo '\n"; - foreach ($tables_list as $name => $type) { - $view = (isset($type) && !eregi("table", $type)); - echo '
' . lang('Table') . '' . lang('Engine') . '' . lang('Collation') . '' . lang('Data Length') . '' . lang('Index Length') . '' . lang('Data Free') . '' . lang('Auto Increment') . '' . lang('Rows') . (support("comment") ? '' . lang('Comment') : '') . "
' . checkbox(($view ? "views[]" : "tables[]"), $name, in_array($name, $tables_views, true), "", "formUncheck('check-all');"); - echo '' . h($name) . ''; - if ($view) { - echo '' . lang('View') . ''; - echo '?'; - } else { - echo "  "; - foreach (array("Data_length" => "create", "Index_length" => "indexes", "Data_free" => "edit", "Auto_increment" => "auto_increment=1&create", "Rows" => "select") as $key => $link) { - echo "?"; +page_header(($_GET["ns"] == "" ? lang('Database') . ": " . h(DB) : lang('Schema') . ": " . h($_GET["ns"])), $error, true); +echo '

' . ($_GET["ns"] == "" ? '' . lang('Alter database') . "\n" : ""); +echo (support("scheme") ? "" . ($_GET["ns"] != "" ? lang('Alter schema') : lang('Create schema')) . "\n" : ""); +if ($_GET["ns"] !== "") { + echo '' . lang('Database schema') . "\n"; + $sums = array("Data_length" => 0, "Index_length" => 0, "Data_free" => 0); + + echo "

" . lang('Tables and views') . "

\n"; + $tables_list = tables_list(); + if (!$tables_list) { + echo "

" . lang('No tables.') . "\n"; + } else { + echo "\n"; + echo "

\n"; + if ($_POST["search"] && $_POST["query"] != "") { + $_GET["where"][0]["op"] = "LIKE %%"; + $_GET["where"][0]["val"] = $_POST["query"]; + search_tables(); + } + echo "\n"; + echo '\n"; + foreach ($tables_list as $name => $type) { + $view = (isset($type) && !eregi("table", $type)); + echo '
' . lang('Table') . '' . lang('Engine') . '' . lang('Collation') . '' . lang('Data Length') . '' . lang('Index Length') . '' . lang('Data Free') . '' . lang('Auto Increment') . '' . lang('Rows') . (support("comment") ? '' . lang('Comment') : '') . "
' . checkbox(($view ? "views[]" : "tables[]"), $name, in_array($name, $tables_views, true), "", "formUncheck('check-all');"); + echo '' . h($name) . ''; + if ($view) { + echo '' . lang('View') . ''; + echo '?'; + } else { + echo "  "; + foreach (array("Data_length" => "create", "Index_length" => "indexes", "Data_free" => "edit", "Auto_increment" => "auto_increment=1&create", "Rows" => "select") as $key => $link) { + echo "?"; + } } + echo (support("comment") ? " " : ""); } - echo (support("comment") ? " " : ""); - } - echo "
 " . lang('%d in total', count($tables_list)); - echo "" . $connection->result("SELECT @@storage_engine"); - echo "" . db_collation(DB, collations()); - foreach ($sums as $key => $val) { - echo " "; - } - echo "
\n"; - if (!information_schema(DB)) { - echo "

" . ($driver == "sql" ? " " : "") . " \n"; - $dbs = get_databases(); - if (count($dbs) != 1) { - $db = (isset($_POST["target"]) ? $_POST["target"] : DB); - echo "

" . lang('Move to other database') . ($dbs ? ": " . html_select("target", $dbs, $db) : ': ') . " \n"; - } - } - echo "\n"; -} - -echo '

' . lang('Create table') . "\n"; -if (support("view")) { - echo '' . lang('Create view') . "\n"; -} -if (support("routine")) { - echo "

" . lang('Routines') . "

\n"; - $routines = routines(); - if ($routines) { - echo "\n"; - echo '\n"; - odd(''); - foreach ($routines as $row) { - echo ''; - echo '
' . lang('Name') . '' . lang('Type') . '' . lang('Return type') . " 
' . h($row["ROUTINE_NAME"]) . ''; - echo '' . h($row["ROUTINE_TYPE"]); - echo '' . h($row["DTD_IDENTIFIER"]); - echo '' . lang('Alter') . ""; + echo "
 " . lang('%d in total', count($tables_list)); + echo "" . $connection->result("SELECT @@storage_engine"); + echo "" . db_collation(DB, collations()); + foreach ($sums as $key => $val) { + echo " "; } echo "
\n"; - } - echo '

' . lang('Create procedure') . ' ' . lang('Create function') . "\n"; -} - -if (support("event")) { - echo "

" . lang('Events') . "

\n"; - $result = $connection->query("SHOW EVENTS"); - if ($result && $result->num_rows) { - echo "\n"; - echo "\n"; - while ($row = $result->fetch_assoc()) { - echo ""; - echo '
" . lang('Name') . "" . lang('Schedule') . "" . lang('Start') . "" . lang('End') . "
' . h($row["Name"]) . ""; - echo "" . ($row["Execute at"] ? lang('At given time') . "" . $row["Execute at"] : lang('Every') . " " . $row["Interval value"] . " " . $row["Interval field"] . "$row[Starts]"); - echo "$row[Ends]"; - } - echo "
\n"; - } - echo '

' . lang('Create event') . "\n"; -} - -page_footer(); -$table_status = table_status(); -if ($table_status) { - echo "\n"; } - foreach ($sums as $key => $val) { - echo "setHtml('sum-$key', '" . number_format($val, 0, '.', lang(',')) . "');\n"; - } - echo "\n"; + exit; // page_footer() already called } -exit; // page_footer() already called diff --git a/adminer/drivers/mssql.inc.php b/adminer/drivers/mssql.inc.php index c57af416..c5e6933e 100644 --- a/adminer/drivers/mssql.inc.php +++ b/adminer/drivers/mssql.inc.php @@ -490,7 +490,7 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . $connection->quote($table) } function support($feature) { - return ereg('^(trigger|drop_col)$', $feature); //! view|routine| + return ereg('^(trigger|drop_col)$', $feature); //! view|routine|scheme| } $driver = "mssql"; diff --git a/adminer/drivers/mysql.inc.php b/adminer/drivers/mysql.inc.php index f8b8b834..0bce831f 100644 --- a/adminer/drivers/mysql.inc.php +++ b/adminer/drivers/mysql.inc.php @@ -755,6 +755,28 @@ if (!defined("DRIVER")) { return $connection->query("EXPLAIN $query"); } + /** Get existing schemas + * @return array + */ + function schemas() { + return array(); + } + + /** Get current schema + * @return string + */ + function get_schema() { + return ""; + } + + /** Set current schema + * @param string + * @return bool + */ + function set_schema($schema) { + return true; + } + /** Get SQL command to create table * @param string * @return string @@ -810,7 +832,7 @@ if (!defined("DRIVER")) { */ function support($feature) { global $connection; - return ($connection->server_info >= 5.1 || ($connection->server_info >= 5 && !ereg("event|partitioning")) || !ereg("view|routine|trigger")); + return !ereg("scheme" . ($connection->server_info < 5.1 ? "|event|partitioning" . ($connection->server_info < 5 ? "|view|routine|trigger" : "") : ""), $feature); } $driver = "sql"; ///< @var string JUSH identifier diff --git a/adminer/drivers/pgsql.inc.php b/adminer/drivers/pgsql.inc.php index eaf3ee03..477cefb3 100644 --- a/adminer/drivers/pgsql.inc.php +++ b/adminer/drivers/pgsql.inc.php @@ -452,12 +452,26 @@ WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name = " . $connection->qu return $connection->query("EXPLAIN $query"); } + function schemas() { + return get_vals("SELECT nspname FROM pg_namespace"); + } + + function get_schema() { + global $connection; + return $connection->result("SELECT current_schema()"); + } + + function set_schema($schema) { + global $connection; + return $connection->query("SET search_path TO " . idf_escape($schema)); + } + function use_sql($database) { return "\connect " . idf_escape($database); } function support($feature) { - return ereg('^(comment|view|trigger|drop_col)$', $feature); //! routine| + return ereg('^(comment|view|scheme|trigger|drop_col)$', $feature); //! routine|sequence| } $driver = "pgsql"; diff --git a/adminer/drivers/sqlite.inc.php b/adminer/drivers/sqlite.inc.php index 785401e1..afb46d75 100644 --- a/adminer/drivers/sqlite.inc.php +++ b/adminer/drivers/sqlite.inc.php @@ -496,6 +496,18 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) { return $connection->query("EXPLAIN $query"); } + function schemas() { + return array(); + } + + function get_schema() { + return ""; + } + + function set_schema($scheme) { + return true; + } + function create_sql($table) { global $connection; return $connection->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . $connection->quote($table)); diff --git a/adminer/include/adminer.inc.php b/adminer/include/adminer.inc.php index 5d885606..e14b7eda 100644 --- a/adminer/include/adminer.inc.php +++ b/adminer/include/adminer.inc.php @@ -506,32 +506,40 @@ document.getElementById('username').focus();

"(" . lang('database') . ")") + $databases, DB, "this.form.submit();") : ''); ?> - - - > -

- select_db(DB)) { - $tables = tables_list(); - if (!$tables) { - echo "

" . lang('No tables.') . "\n"; - } else { - $this->tablesPrint($tables); - $links = array(); - foreach ($tables as $table => $type) { - $links[] = preg_quote($table, '/'); + if (support("scheme")) { + echo "
" . html_select("ns", array("" => "(" . lang('schema') . ")") + schemas(), $_GET["ns"], "this.form.submit();"); + if ($_GET["ns"] != "") { + set_schema($_GET["ns"]); } - echo "\n"; } - echo '

' . bold(lang('Create new table'), $_GET["create"] === "") . "\n"; + if ($_GET["ns"] !== "") { + $tables = tables_list(); + if (!$tables) { + echo "

" . lang('No tables.') . "\n"; + } else { + $this->tablesPrint($tables); + $links = array(); + foreach ($tables as $table => $type) { + $links[] = preg_quote($table, '/'); + } + echo "\n"; + } + echo '

' . bold(lang('Create new table'), $_GET["create"] === "") . "\n"; + } } + echo (isset($_GET["sql"]) ? '' + : (isset($_GET["schema"]) ? '' + : (isset($_GET["dump"]) ? '' + : ""))); + echo "\n"; } } diff --git a/adminer/include/auth.inc.php b/adminer/include/auth.inc.php index 592cbce4..6bf8af10 100644 --- a/adminer/include/auth.inc.php +++ b/adminer/include/auth.inc.php @@ -46,7 +46,7 @@ if (isset($_POST["server"])) { set_session($key, null); } cookie("adminer_permanent", ""); - redirect(substr(preg_replace('~(username|db)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.')); + redirect(substr(preg_replace('~(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.')); } } elseif ($_COOKIE["adminer_permanent"]) { list($server, $username, $cipher, $system) = array_map('base64_decode', explode(":", $_COOKIE["adminer_permanent"])); // $driver is a global variable diff --git a/adminer/include/bootstrap.inc.php b/adminer/include/bootstrap.inc.php index b059b529..608e1b5f 100644 --- a/adminer/include/bootstrap.inc.php +++ b/adminer/include/bootstrap.inc.php @@ -71,7 +71,7 @@ define("ME", preg_replace('~^[^?]*/([^?]*).*~', '\\1', $_SERVER["REQUEST_URI"]) . (SID && !$_COOKIE ? SID . '&' : '') // !$_COOKIE - don't pass SID with permanent login . (SERVER !== null ? DRIVER . "=" . urlencode(SERVER) . '&' : '') . (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '') - . (DB != "" ? 'db=' . urlencode(DB) . '&' : '') + . (DB != "" ? 'db=' . urlencode(DB) . '&' . (isset($_GET["ns"]) ? "ns=" . urlencode($_GET["ns"]) . "&" : "") : '') ); include "../adminer/include/version.inc.php"; diff --git a/adminer/include/connect.inc.php b/adminer/include/connect.inc.php index 29e79f7a..71fe13c8 100644 --- a/adminer/include/connect.inc.php +++ b/adminer/include/connect.inc.php @@ -61,3 +61,7 @@ if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET connect_error(); // separate function to catch SQLite error exit; } + +if (support("scheme") && DB != "" && $_GET["ns"] !== "" && (!isset($_GET["ns"]) || !set_schema($_GET["ns"]))) { + redirect(preg_replace('~ns=[^&]*&~', '', ME) . "ns=" . get_schema()); +} diff --git a/adminer/include/design.inc.php b/adminer/include/design.inc.php index a0b39477..ea03384c 100644 --- a/adminer/include/design.inc.php +++ b/adminer/include/design.inc.php @@ -31,17 +31,20 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {

' . $drivers[DRIVER] . ' » '; - $link = substr(preg_replace('~db=[^&]*&~', '', ME), 0, -1); + $link = substr(preg_replace('~(db|ns)=[^&]*&~', '', ME), 0, -1); $server = (SERVER != "" ? h(SERVER) : lang('Server')); if ($breadcrumb === false) { echo "$server\n"; } else { echo "$server » "; + if ($_GET["ns"] != "" || (DB != "" && is_array($breadcrumb))) { + echo '' . h(DB) . ' » '; + } if (is_array($breadcrumb)) { - if (DB != "") { - echo '' . h(DB) . ' » '; + if ($_GET["ns"] != "") { + echo '' . h($_GET["ns"]) . ' » '; } foreach ($breadcrumb as $key => $val) { $desc = (is_array($val) ? $val[1] : $val); diff --git a/adminer/index.php b/adminer/index.php index 2c9f5f51..cac42a40 100644 --- a/adminer/index.php +++ b/adminer/index.php @@ -40,6 +40,8 @@ if (isset($_GET["download"])) { include "./indexes.inc.php"; } elseif (isset($_GET["database"])) { include "./database.inc.php"; +} elseif (isset($_GET["scheme"])) { + include "./scheme.inc.php"; } elseif (isset($_GET["call"])) { include "./call.inc.php"; } elseif (isset($_GET["foreign"])) { diff --git a/adminer/lang/cs.inc.php b/adminer/lang/cs.inc.php index 3c822536..e37ed644 100644 --- a/adminer/lang/cs.inc.php +++ b/adminer/lang/cs.inc.php @@ -237,4 +237,11 @@ $translations = array( 'Double click on a value to modify it.' => 'Dvojklikněte na políčko, které chcete změnit.', 'Increase text length to modify this value.' => 'Ke změně této hodnoty zvyšte délku textů.', 'Use edit link to modify this value.' => 'Ke změně této hodnoty použijte odkaz upravit.', + 'Alter schema' => 'Pozměnit schéma', + 'Create schema' => 'Vytvořit schéma', + 'Schema has been dropped.' => 'Schéma bylo odstraněno.', + 'Schema has been created.' => 'Schéma bylo vytvořeno.', + 'Schema has been altered.' => 'Schéma bylo změněno.', + 'schema' => 'schéma', + 'Schema' => 'Schéma', ); diff --git a/adminer/scheme.inc.php b/adminer/scheme.inc.php new file mode 100644 index 00000000..7423e4aa --- /dev/null +++ b/adminer/scheme.inc.php @@ -0,0 +1,35 @@ + $_GET["ns"]); +if ($_POST) { + $row = $_POST; +} +?> + +
+

"> + + +\n"; +} +?> +

diff --git a/compile.php b/compile.php index 6615e4ca..02175e69 100644 --- a/compile.php +++ b/compile.php @@ -190,13 +190,15 @@ foreach (glob(dirname(__FILE__) . "/adminer/drivers/" . ($DRIVER ? $DRIVER : "*" } } +$drivers = array(); foreach (array("adminer", "editor") as $project) { $lang_ids = array(); // global variable simplifies usage in a callback function $file = file_get_contents(dirname(__FILE__) . "/$project/index.php"); - if ($DRIVER && $DRIVER != "mysql") { + if ($DRIVER) { + $connection = (object) array("server_info" => 5.1); // MySQL support is version specific $_GET[$DRIVER] = true; // to load the driver include_once dirname(__FILE__) . "/adminer/drivers/$DRIVER.inc.php"; - foreach (array("view", "event", "privileges", "user", "processlist", "variables", "trigger") as $feature) { + foreach (array("view", "event", "privileges", "user", "processlist", "variables", "trigger", "scheme") as $feature) { if (!support($feature)) { $file = str_replace("} elseif (isset(\$_GET[\"$feature\"])) {\n\tinclude \"./$feature.inc.php\";\n", "", $file); } diff --git a/todo.txt b/todo.txt index c145be74..1454a40a 100644 --- a/todo.txt +++ b/todo.txt @@ -35,7 +35,6 @@ Backward keys in Editor PostgreSQL: Users - SELECT * FROM pg_user ORDER BY COUNT(*) -Table schema - SELECT * FROM pg_namespace, CREATE|ALTER|DROP SCHEMA, SET default_tablespace Export - http://www.postgresql.org/docs/8.4/static/functions-info.html Column rights - http://www.postgresql.org/docs/8.4/static/functions-info.html Dollar terminated string in SQL command