1
0
mirror of https://github.com/vrana/adminer.git synced 2025-08-30 09:39:51 +02:00

Compare commits

...

52 Commits

Author SHA1 Message Date
Jakub Vrana
b51d4ab105 Release 3.7.0 2013-05-19 20:37:27 -07:00
Jakub Vrana
fabfb8a0bc Get number of rows on export page asynchronously 2013-05-17 17:40:08 -07:00
Jakub Vrana
5a4d1b3704 Add server placeholder to login form 2013-05-17 14:08:15 -07:00
Jakub Vrana
982974fe27 Use ALTER VIEW and don't use temporary object if changing name 2013-05-13 11:12:28 -07:00
Jakub Vrana
3ed0ce926c Fix table links for existing but invalid views 2013-05-13 10:12:13 -07:00
Jakub Vrana
65fae98558 Don't rely on 't' and 'f' PostgreSQL boolean return values
https://sourceforge.net/projects/adminer/forums/forum/1095138/topic/8119905
2013-05-13 08:40:06 -07:00
Jakub Vrana
af30f59737 Don't use LIMIT 1 if updating unique row (bug #3613109) 2013-05-11 13:05:40 -07:00
Jakub Vrana
2f996ba014 Restrict editing rows without unique identifier to search results 2013-05-11 12:47:04 -07:00
Jakub Vrana
b7e0f1d81c Fix EXPLAIN in MySQL < 5.1, bug since Adminer 3.6.4 (thanks to Coudy) 2013-05-11 08:02:28 -07:00
Jakub Vrana
20915b1764 Save bytes 2013-05-08 12:13:04 -07:00
Jakub Vrana
516416e72b Fix tables list in Editor 2013-05-08 11:58:21 -07:00
Jakub Vrana
c38655418b Simplify process_fields() 2013-05-08 11:43:53 -07:00
Jakub Vrana
046da00eb6 Strip trailing spaces 2013-05-08 11:29:19 -07:00
Jakub Vrana
22f0a5ded8 Display navigation bellow main content on mobile browsers 2013-05-08 11:27:20 -07:00
Jakub Vrana
6a41240c42 Move common function 2013-05-08 10:46:16 -07:00
Jakub Vrana
a09916737e Simplify initializing post variables 2013-05-08 08:54:26 -07:00
Jakub Vrana
e99463b295 Don't drop original view and routine before creating the new one 2013-05-08 07:55:08 -07:00
Jakub Vrana
b7021c9c7f Highlight default submit button 2013-05-06 09:27:35 -07:00
Jakub Vrana
94a0cc8de8 Fix resetting search (bug #3612507) 2013-05-03 18:53:13 -07:00
Jakub Vrana
9c78b3bb34 Add empty lines to source code 2013-05-01 18:28:04 -07:00
Jakub Vrana
0e6003e833 Send export headers sooner 2013-05-01 09:44:07 -07:00
Jakub Vrana
601cdd43c1 Constraint memory used in TAR export 2013-05-01 09:33:23 -07:00
Jakub Vrana
17a8495c2e Display logout button in Nette design. 2013-04-30 12:02:02 -07:00
Jakub Vrana
40c61f6cfc Reduce memory used by TAR export 2013-04-29 15:45:15 -07:00
Jakub Vrana
63c400f95d Allow exporting views dependent on each other (bug #3459151) 2013-04-29 15:42:39 -07:00
Jakub Vrana
34adf46293 Export SQLite views 2013-04-29 15:37:50 -07:00
Jakub Vrana
1ecdde0500 Remove bzip2 compression support
It didn't work for exports bigger than 1 MB.
An alternative would be to remove the limit from output buffer which would need memory for the whole export.
Another alternative would be to create a temporary file in output handler and bzwrite() to this file - that would work but it's complicated, especially if we want to output the file progressively - bzopen($tmp, 'w'), fopen($tmp, 'r').
2013-04-29 15:37:33 -07:00
Jakub Vrana
7f05141b89 Save memory in get_file() 2013-04-28 08:17:50 -07:00
Jakub Vrana
d513de4d71 Allow using lang() in plugins 2013-04-28 08:17:40 -07:00
Jakub Vrana
18d51c6b6e Allow using lang() in plugin with single language Adminer version 2013-04-27 23:36:43 -07:00
Jakub Vrana
5eda7e547f Add anchors to database and table sections to allow linking 2013-04-27 23:17:07 -07:00
Jakub Vrana
f7e671448c Select only required routine columns (possible fix for bug #3515776) 2013-04-27 13:04:54 -07:00
Jakub Vrana
d97ae22fb4 Properly unescape apostrophe in column name 2013-04-26 23:25:35 -07:00
Jakub Vrana
49c1484722 Display bit default value same as existing values 2013-04-26 23:21:09 -07:00
Jakub Vrana
7541ceb1ca Improve export of binary data types (bug #3526494) 2013-04-26 22:57:44 -07:00
Jakub Vrana
2afd915f00 Save bytes 2013-04-26 22:22:38 -07:00
Jakub Vrana
5a0be7e7fe Convert fields with selected columns 2013-04-26 22:20:04 -07:00
Jakub Vrana
de2c3968d4 Display bit type as binary number, also fix bit outside MySQLnd 2013-04-26 22:20:03 -07:00
Jakub Vrana
e24d1fcb02 Optimize table_status() 2013-04-26 22:19:54 -07:00
Jakub Vrana
3cae3e2f7f Fix LIKE backslash escaping 2013-04-26 19:34:15 -07:00
Jakub Vrana
fd5e6ef343 Use standard view detection in schema 2013-04-26 19:34:15 -07:00
Jakub Vrana
8ae8507972 Save bytes 2013-04-26 19:34:03 -07:00
Jakub Vrana
b0b4cb1576 Allow more SQL files to be uploaded at the same time (thanks to Frantisek Svoboda) 2013-04-26 13:26:08 -07:00
Jakub Vrana
ada8917e43 Rename = edit operator to SQL 2013-04-26 12:20:47 -07:00
Jakub Vrana
e287642e26 Rename empty select operator to SQL 2013-04-26 12:20:17 -07:00
Jakub Vrana
4858f332c8 Disable SQL export when applying functions in select 2013-04-26 11:57:21 -07:00
Jakub Vrana
91dbaca3c4 Don't export binary and geometry columns twice in select 2013-04-26 11:52:26 -07:00
Jakub Vrana
741cd5b4b6 Fix handling of POINT data type (bug #3582578) 2013-04-26 11:42:18 -07:00
Étienne Deparis
0f47ae8e0f Update Nette design 2013-04-26 10:54:16 -07:00
Jakub Vrana
01a2722c94 Print run time next to executed queries 2013-04-25 23:41:46 -07:00
Jakub Vrana
3bc5c17d03 Develop 2013-04-25 19:00:37 -07:00
Jakub Vrana
a199998f54 Fix documentation comment 2013-04-25 18:19:27 -07:00
49 changed files with 840 additions and 439 deletions

View File

@@ -28,8 +28,10 @@ if (!$error && $_POST) {
}
$call[] = (isset($out[$key]) ? "@" . idf_escape($field["field"]) : $val);
}
$query = (isset($_GET["callf"]) ? "SELECT" : "CALL") . " " . idf_escape($PROCEDURE) . "(" . implode(", ", $call) . ")";
echo "<p><code class='jush-$jush'>" . h($query) . "</code> <a href='" . h(ME) . "sql=" . urlencode($query) . "'>" . lang('Edit') . "</a>\n";
if (!$connection->multi_query($query)) {
echo "<p class='error'>" . error() . "\n";
} else {
@@ -37,6 +39,7 @@ if (!$error && $_POST) {
if (is_object($connection2)) {
$connection2->select_db(DB);
}
do {
$result = $connection->store_result();
if (is_object($result)) {
@@ -45,6 +48,7 @@ if (!$error && $_POST) {
echo "<p class='message'>" . lang('Routine has been called, %d row(s) affected.', $connection->affected_rows) . "\n";
}
} while ($connection->next_result());
if ($out) {
select($connection->query("SELECT " . implode(", ", $out)));
}

View File

@@ -14,11 +14,14 @@ if ($TABLE != "") {
$orig_fields = fields($TABLE);
$orig_status = table_status($TABLE);
}
if ($_POST && !$_POST["fields"]) {
$_POST["fields"] = array();
$row = $_POST;
$row["fields"] = (array) $row["fields"];
if ($row["auto_increment_col"]) {
$row["fields"][$row["auto_increment_col"]]["auto_increment"] = true;
}
if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"] && !$_POST["down"]) {
if ($_POST && !process_fields($row["fields"]) && !$error) {
if ($_POST["drop"]) {
query_redirect("DROP TABLE " . table($TABLE), substr(ME, 0, -1), lang('Table has been dropped.'));
} else {
@@ -26,17 +29,18 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
$all_fields = array();
$use_all_fields = false;
$foreign = array();
ksort($_POST["fields"]);
ksort($row["fields"]);
$orig_field = reset($orig_fields);
$after = " FIRST";
foreach ($_POST["fields"] as $key => $field) {
foreach ($row["fields"] as $key => $field) {
$foreign_key = $foreign_keys[$field["type"]];
$type_field = ($foreign_key !== null ? $referencable_primary[$foreign_key] : $field); //! can collide with user defined type
if ($field["field"] != "") {
if (!$field["has_default"]) {
$field["default"] = null;
}
if ($key == $_POST["auto_increment_col"]) {
if ($key == $row["auto_increment_col"]) {
$field["auto_increment"] = true;
}
$process_field = process_field($field, $type_field);
@@ -62,37 +66,40 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
}
}
}
$partitioning = "";
if (in_array($_POST["partition_by"], $partition_by)) {
if (in_array($row["partition_by"], $partition_by)) {
$partitions = array();
if ($_POST["partition_by"] == 'RANGE' || $_POST["partition_by"] == 'LIST') {
foreach (array_filter($_POST["partition_names"]) as $key => $val) {
$value = $_POST["partition_values"][$key];
$partitions[] = "\nPARTITION " . idf_escape($val) . " VALUES " . ($_POST["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection
if ($row["partition_by"] == 'RANGE' || $row["partition_by"] == 'LIST') {
foreach (array_filter($row["partition_names"]) as $key => $val) {
$value = $row["partition_values"][$key];
$partitions[] = "\n PARTITION " . idf_escape($val) . " VALUES " . ($row["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection
}
}
$partitioning .= "\nPARTITION BY $_POST[partition_by]($_POST[partition])" . ($partitions // $_POST["partition"] can be expression, not only column
$partitioning .= "\nPARTITION BY $row[partition_by]($row[partition])" . ($partitions // $row["partition"] can be expression, not only column
? " (" . implode(",", $partitions) . "\n)"
: ($_POST["partitions"] ? " PARTITIONS " . (+$_POST["partitions"]) : "")
: ($row["partitions"] ? " PARTITIONS " . (+$row["partitions"]) : "")
);
} elseif (support("partitioning") && ereg("partitioned", $orig_status["Create_options"])) {
$partitioning .= "\nREMOVE PARTITIONING";
}
$message = lang('Table has been altered.');
if ($TABLE == "") {
cookie("adminer_engine", $_POST["Engine"]);
cookie("adminer_engine", $row["Engine"]);
$message = lang('Table has been created.');
}
$name = trim($_POST["name"]);
$name = trim($row["name"]);
queries_redirect(ME . "table=" . urlencode($name), $message, alter_table(
$TABLE,
$name,
($jush == "sqlite" && ($use_all_fields || $foreign) ? $all_fields : $fields),
$foreign,
$_POST["Comment"],
($_POST["Engine"] && $_POST["Engine"] != $orig_status["Engine"] ? $_POST["Engine"] : ""),
($_POST["Collation"] && $_POST["Collation"] != $orig_status["Collation"] ? $_POST["Collation"] : ""),
($_POST["Auto_increment"] != "" ? +$_POST["Auto_increment"] : ""),
$row["Comment"],
($row["Engine"] && $row["Engine"] != $orig_status["Engine"] ? $row["Engine"] : ""),
($row["Collation"] && $row["Collation"] != $orig_status["Collation"] ? $row["Collation"] : ""),
($row["Auto_increment"] != "" ? +$row["Auto_increment"] : ""),
$partitioning
));
}
@@ -100,43 +107,38 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
page_header(($TABLE != "" ? lang('Alter table') : lang('Create table')), $error, array("table" => $TABLE), $TABLE);
$row = array(
"Engine" => $_COOKIE["adminer_engine"],
"fields" => array(array("field" => "", "type" => (isset($types["int"]) ? "int" : (isset($types["integer"]) ? "integer" : "")))),
"partition_names" => array(""),
);
if ($_POST) {
$row = $_POST;
if ($row["auto_increment_col"]) {
$row["fields"][$row["auto_increment_col"]]["auto_increment"] = true;
}
process_fields($row["fields"]);
} elseif ($TABLE != "") {
$row = $orig_status;
$row["name"] = $TABLE;
$row["fields"] = array();
if (!$_GET["auto_increment"]) { // don't prefill by original Auto_increment for the sake of performance and not reusing deleted ids
$row["Auto_increment"] = "";
}
foreach ($orig_fields as $field) {
$field["has_default"] = isset($field["default"]);
$row["fields"][] = $field;
}
if (support("partitioning")) {
$from = "FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = " . q(DB) . " AND TABLE_NAME = " . q($TABLE);
$result = $connection->query("SELECT PARTITION_METHOD, PARTITION_ORDINAL_POSITION, PARTITION_EXPRESSION $from ORDER BY PARTITION_ORDINAL_POSITION DESC LIMIT 1");
list($row["partition_by"], $row["partitions"], $row["partition"]) = $result->fetch_row();
$row["partition_names"] = array();
$row["partition_values"] = array();
foreach (get_rows("SELECT PARTITION_NAME, PARTITION_DESCRIPTION $from AND PARTITION_NAME != '' ORDER BY PARTITION_ORDINAL_POSITION") as $row1) {
$row["partition_names"][] = $row1["PARTITION_NAME"];
$row["partition_values"][] = $row1["PARTITION_DESCRIPTION"];
if (!$_POST) {
$row = array(
"Engine" => $_COOKIE["adminer_engine"],
"fields" => array(array("field" => "", "type" => (isset($types["int"]) ? "int" : (isset($types["integer"]) ? "integer" : "")))),
"partition_names" => array(""),
);
if ($TABLE != "") {
$row = $orig_status;
$row["name"] = $TABLE;
$row["fields"] = array();
if (!$_GET["auto_increment"]) { // don't prefill by original Auto_increment for the sake of performance and not reusing deleted ids
$row["Auto_increment"] = "";
}
foreach ($orig_fields as $field) {
$field["has_default"] = isset($field["default"]);
$row["fields"][] = $field;
}
if (support("partitioning")) {
$from = "FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = " . q(DB) . " AND TABLE_NAME = " . q($TABLE);
$result = $connection->query("SELECT PARTITION_METHOD, PARTITION_ORDINAL_POSITION, PARTITION_EXPRESSION $from ORDER BY PARTITION_ORDINAL_POSITION DESC LIMIT 1");
list($row["partition_by"], $row["partitions"], $row["partition"]) = $result->fetch_row();
$partitions = get_key_vals("SELECT PARTITION_NAME, PARTITION_DESCRIPTION $from AND PARTITION_NAME != '' ORDER BY PARTITION_ORDINAL_POSITION");
$partitions[""] = "";
$row["partition_names"] = array_keys($partitions);
$row["partition_values"] = array_values($partitions);
}
$row["partition_names"][] = "";
}
}
$collations = collations();
$collations = collations();
$engines = engines();
// case of engine may differ
foreach ($engines as $engine) {
@@ -150,7 +152,7 @@ foreach ($engines as $engine) {
<form action="" method="post" id="form">
<p>
<?php echo lang('Table name'); ?>: <input name="name" maxlength="64" value="<?php echo h($row["name"]); ?>" autocapitalize="off">
<?php if ($TABLE == "" && !$_POST) { ?><script type='text/javascript'>document.getElementById('form')['name'].focus();</script><?php } ?>
<?php if ($TABLE == "" && !$_POST) { ?><script type='text/javascript'>focus(document.getElementById('form')['name']);</script><?php } ?>
<?php echo ($engines ? html_select("Engine", array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) : ""); ?>
<?php echo ($collations && !ereg("sqlite|mssql", $jush) ? html_select("Collation", array("" => "(" . lang('collation') . ")") + $collations, $row["Collation"]) : ""); ?>
<input type="submit" value="<?php echo lang('Save'); ?>">

View File

@@ -1,7 +1,9 @@
<?php
$row = $_POST;
if ($_POST && !$error && !isset($_POST["add_x"])) { // add is an image and PHP changes add.x to add_x
restart_session();
$name = trim($_POST["name"]);
$name = trim($row["name"]);
if ($_POST["drop"]) {
$_GET["db"] = ""; // to save in global history
queries_redirect(remove_from_uri("db|database"), lang('Database has been dropped.'), drop_databases(array(DB)));
@@ -9,14 +11,14 @@ if ($_POST && !$error && !isset($_POST["add_x"])) { // add is an image and PHP c
// create or rename database
if (DB != "") {
$_GET["db"] = $name;
queries_redirect(preg_replace('~db=[^&]*&~', '', ME) . "db=" . urlencode($name), lang('Database has been renamed.'), rename_database($name, $_POST["collation"]));
queries_redirect(preg_replace('~db=[^&]*&~', '', ME) . "db=" . urlencode($name), lang('Database has been renamed.'), rename_database($name, $row["collation"]));
} else {
$databases = explode("\n", str_replace("\r", "", $name));
$success = true;
$last = "";
foreach ($databases as $db) {
if (count($databases) == 1 || $db != "") { // ignore empty lines but always try to create single database
if (!create_database($db, $_POST["collation"])) {
if (!create_database($db, $row["collation"])) {
$success = false;
}
$last = $db;
@@ -26,10 +28,10 @@ if ($_POST && !$error && !isset($_POST["add_x"])) { // add is an image and PHP c
}
} else {
// alter database
if (!$_POST["collation"]) {
if (!$row["collation"]) {
redirect(substr(ME, 0, -1));
}
query_redirect("ALTER DATABASE " . idf_escape($name) . (eregi('^[a-z0-9_]+$', $_POST["collation"]) ? " COLLATE $_POST[collation]" : ""), substr(ME, 0, -1), lang('Database has been altered.'));
query_redirect("ALTER DATABASE " . idf_escape($name) . (eregi('^[a-z0-9_]+$', $row["collation"]) ? " COLLATE $row[collation]" : ""), substr(ME, 0, -1), lang('Database has been altered.'));
}
}
@@ -37,12 +39,10 @@ page_header(DB != "" ? lang('Alter database') : lang('Create database'), $error,
$collations = collations();
$name = DB;
$collate = null;
if ($_POST) {
$name = $_POST["name"];
$collate = $_POST["collation"];
$name = $row["name"];
} elseif (DB != "") {
$collate = db_collation(DB, $collations);
$row["collation"] = db_collation(DB, $collations);
} elseif ($jush == "sql") {
// propose database name with limited privileges
foreach (get_vals("SHOW GRANTS") as $grant) {
@@ -60,9 +60,9 @@ if ($_POST) {
echo ($_POST["add_x"] || strpos($name, "\n")
? '<textarea id="name" name="name" rows="10" cols="40">' . h($name) . '</textarea><br>'
: '<input name="name" id="name" value="' . h($name) . '" maxlength="64" autocapitalize="off">'
) . "\n" . ($collations ? html_select("collation", array("" => "(" . lang('collation') . ")") + $collations, $collate) : "");
) . "\n" . ($collations ? html_select("collation", array("" => "(" . lang('collation') . ")") + $collations, $row["collation"]) : "");
?>
<script type='text/javascript'>document.getElementById('name').focus();</script>
<script type='text/javascript'>focus(document.getElementById('name'));</script>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php
if (DB != "") {

View File

@@ -7,6 +7,7 @@ if ($tables_views && !$error && !$_POST["search"]) {
if ($jush == "sql" && count($_POST["tables"]) > 1 && ($_POST["drop"] || $_POST["truncate"] || $_POST["copy"])) {
queries("SET foreign_key_checks = 0"); // allows to truncate or drop several tables at once
}
if ($_POST["truncate"]) {
if ($_POST["tables"]) {
$result = truncate_tables($_POST["tables"]);
@@ -39,6 +40,7 @@ if ($tables_views && !$error && !$_POST["search"]) {
$message .= "<b>" . h($row["Table"]) . "</b>: " . h($row["Msg_text"]) . "<br>";
}
}
queries_redirect(substr(ME, 0, -1), $message, $result);
}
@@ -46,7 +48,7 @@ page_header(($_GET["ns"] == "" ? lang('Database') . ": " . h(DB) : lang('Schema'
if ($adminer->homepage()) {
if ($_GET["ns"] !== "") {
echo "<h3>" . lang('Tables and views') . "</h3>\n";
echo "<h3 id='tables-views'>" . lang('Tables and views') . "</h3>\n";
$tables_list = tables_list();
if (!$tables_list) {
echo "<p class='message'>" . lang('No tables.') . "\n";
@@ -57,6 +59,7 @@ if ($adminer->homepage()) {
search_tables();
}
echo "<table cellspacing='0' class='nowrap checkable' onclick='tableClick(event);' ondblclick='tableClick(event, true);'>\n";
echo '<thead><tr class="wrap"><td><input id="check-all" type="checkbox" onclick="formCheck(this, /^(tables|views)\[/);">';
echo '<th>' . lang('Table');
echo '<td>' . lang('Engine');
@@ -68,6 +71,7 @@ if ($adminer->homepage()) {
echo '<td>' . lang('Rows');
echo (support("comment") ? '<td>' . lang('Comment') : '');
echo "</thead>\n";
foreach ($tables_list as $name => $type) {
$view = ($type !== null && !eregi("table", $type));
echo '<tr' . odd() . '><td>' . checkbox(($view ? "views[]" : "tables[]"), $name, in_array($name, $tables_views, true), "", "formUncheck('check-all');");
@@ -90,12 +94,14 @@ if ($adminer->homepage()) {
}
echo (support("comment") ? "<td id='Comment-" . h($name) . "'>&nbsp;" : "");
}
echo "<tr><td>&nbsp;<th>" . lang('%d in total', count($tables_list));
echo "<td>" . nbsp($jush == "sql" ? $connection->result("SELECT @@storage_engine") : "");
echo "<td>" . nbsp(db_collation(DB, collations()));
foreach (array("Data_length", "Index_length", "Data_free") as $key) {
echo "<td align='right' id='sum-$key'>&nbsp;";
}
echo "</table>\n";
echo "<script type='text/javascript'>tableCheck();</script>\n";
if (!information_schema(DB)) {
@@ -123,7 +129,7 @@ if ($adminer->homepage()) {
}
if (support("routine")) {
echo "<h3>" . lang('Routines') . "</h3>\n";
echo "<h3 id='routines'>" . lang('Routines') . "</h3>\n";
$routines = routines();
if ($routines) {
echo "<table cellspacing='0'>\n";
@@ -142,7 +148,7 @@ if ($adminer->homepage()) {
}
if (support("sequence")) {
echo "<h3>" . lang('Sequences') . "</h3>\n";
echo "<h3 id='sequences'>" . lang('Sequences') . "</h3>\n";
$sequences = get_vals("SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = current_schema()");
if ($sequences) {
echo "<table cellspacing='0'>\n";
@@ -157,7 +163,7 @@ if ($adminer->homepage()) {
}
if (support("type")) {
echo "<h3>" . lang('User types') . "</h3>\n";
echo "<h3 id='user-types'>" . lang('User types') . "</h3>\n";
$user_types = types();
if ($user_types) {
echo "<table cellspacing='0'>\n";
@@ -172,7 +178,7 @@ if ($adminer->homepage()) {
}
if (support("event")) {
echo "<h3>" . lang('Events') . "</h3>\n";
echo "<h3 id='events'>" . lang('Events') . "</h3>\n";
$rows = get_rows("SHOW EVENTS");
if ($rows) {
echo "<table cellspacing='0'>\n";

View File

@@ -366,16 +366,21 @@ if (!defined("DRIVER")) {
/** Get table status
* @param string
* @param bool return only "Name", "Engine" and "Comment" fields
* @return array array($name => array("Name" => , "Engine" => , "Comment" => , "Oid" => , "Rows" => , "Collation" => , "Auto_increment" => , "Data_length" => , "Index_length" => , "Data_free" => )) or only inner array with $name
*/
function table_status($name = "") {
function table_status($name = "", $fast = false) {
global $connection;
$return = array();
foreach (get_rows("SHOW TABLE STATUS" . ($name != "" ? " LIKE " . q(addcslashes($name, "%_")) : "")) as $row) {
foreach (get_rows($fast && $connection->server_info >= 5
? "SELECT TABLE_NAME AS Name, Engine, TABLE_COMMENT AS Comment FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()" . ($name != "" ? " AND TABLE_NAME = " . q($name) : "")
: "SHOW TABLE STATUS" . ($name != "" ? " LIKE " . q(addcslashes($name, "%_\\")) : "")
) as $row) {
if ($row["Engine"] == "InnoDB") {
// ignore internal comment, unnecessary since MySQL 5.1.21
$row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\\1', $row["Comment"]);
}
if (!isset($row["Rows"])) {
if (!isset($row["Engine"])) {
$row["Comment"] = "";
}
if ($name != "") {
@@ -391,7 +396,7 @@ if (!defined("DRIVER")) {
* @return bool
*/
function is_view($table_status) {
return !isset($table_status["Rows"]);
return !isset($table_status["Engine"]);
}
/** Check if table supports foreign keys
@@ -733,7 +738,7 @@ if (!defined("DRIVER")) {
*/
function triggers($table) {
$return = array();
foreach (get_rows("SHOW TRIGGERS LIKE " . q(addcslashes($table, "%_"))) as $row) {
foreach (get_rows("SHOW TRIGGERS LIKE " . q(addcslashes($table, "%_\\"))) as $row) {
$return[$row["Trigger"]] = array($row["Timing"], $row["Event"]);
}
return $return;
@@ -792,7 +797,7 @@ if (!defined("DRIVER")) {
* @return array ("ROUTINE_TYPE" => , "ROUTINE_NAME" => , "DTD_IDENTIFIER" => )
*/
function routines() {
return get_rows("SELECT * FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = " . q(DB));
return get_rows("SELECT ROUTINE_NAME, ROUTINE_TYPE, DTD_IDENTIFIER FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = " . q(DB));
}
/** Get list of available routine languages
@@ -846,7 +851,7 @@ if (!defined("DRIVER")) {
* @return Min_Result
*/
function explain($connection, $query) {
return $connection->query("EXPLAIN " . ($connection->server_info ? "PARTITIONS " : "") . $query);
return $connection->query("EXPLAIN " . ($connection->server_info >= 5.1 ? "PARTITIONS " : "") . $query);
}
/** Get approximate number of rows
@@ -924,7 +929,7 @@ if (!defined("DRIVER")) {
*/
function trigger_sql($table, $style) {
$return = "";
foreach (get_rows("SHOW TRIGGERS LIKE " . q(addcslashes($table, "%_")), null, "-- ") as $row) {
foreach (get_rows("SHOW TRIGGERS LIKE " . q(addcslashes($table, "%_\\")), null, "-- ") as $row) {
$return .= "\n" . ($style == 'CREATE+ALTER' ? "DROP TRIGGER IF EXISTS " . idf_escape($row["Trigger"]) . ";;\n" : "")
. "CREATE TRIGGER " . idf_escape($row["Trigger"]) . " $row[Timing] $row[Event] ON " . table($row["Table"]) . " FOR EACH ROW\n$row[Statement];;\n";
}
@@ -960,6 +965,9 @@ if (!defined("DRIVER")) {
if (ereg("binary", $field["type"])) {
return "HEX(" . idf_escape($field["field"]) . ")";
}
if ($field["type"] == "bit") {
return "BIN(" . idf_escape($field["field"]) . " + 0)"; // + 0 is required outside MySQLnd
}
if (ereg("geometry|point|linestring|polygon", $field["type"])) {
return "AsWKT(" . idf_escape($field["field"]) . ")";
}
@@ -974,6 +982,9 @@ if (!defined("DRIVER")) {
if (ereg("binary", $field["type"])) {
$return = "UNHEX($return)";
}
if ($field["type"] == "bit") {
return "CONV($return, 2, 10) + 0";
}
if (ereg("geometry|point|linestring|polygon", $field["type"])) {
$return = "GeomFromText($return)";
}
@@ -1004,7 +1015,7 @@ if (!defined("DRIVER")) {
$structured_types[$key] = array_keys($val);
}
$unsigned = array("unsigned", "zerofill", "unsigned zerofill"); ///< @var array number variants
$operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", ""); ///< @var array operators used in select
$operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL"); ///< @var array operators used in select
$functions = array("char_length", "date", "from_unixtime", "lower", "round", "sec_to_time", "time_to_sec", "upper"); ///< @var array functions used in select
$grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"); ///< @var array grouping functions used in select
$edit_functions = array( ///< @var array of array("$type|$type2" => "$function/$function2") functions used in editing, [0] - edit and insert, [1] - edit only

View File

@@ -386,7 +386,7 @@ ORDER BY PROCESS
$structured_types[$key] = array_keys($val);
}
$unsigned = array();
$operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "");
$operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL");
$functions = array("length", "lower", "round", "upper");
$grouping = array("avg", "count", "count distinct", "max", "min", "sum");
$edit_functions = array(

View File

@@ -227,7 +227,7 @@ AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema(
function fields($table) {
$return = array();
foreach (get_rows("SELECT a.attname AS field, format_type(a.atttypid, a.atttypmod) AS full_type, d.adsrc AS default, a.attnotnull, col_description(c.oid, a.attnum) AS comment
foreach (get_rows("SELECT a.attname AS field, format_type(a.atttypid, a.atttypmod) AS full_type, d.adsrc AS default, a.attnotnull::int, col_description(c.oid, a.attnum) AS comment
FROM pg_class c
JOIN pg_namespace n ON c.relnamespace = n.oid
JOIN pg_attribute a ON c.oid = a.attrelid
@@ -242,7 +242,7 @@ ORDER BY a.attnum"
ereg('(.*)(\\((.*)\\))?', $row["full_type"], $match);
list(, $row["type"], , $row["length"]) = $match;
$row["full_type"] = $row["type"] . ($row["length"] ? "($row[length])" : "");
$row["null"] = ($row["attnotnull"] == "f");
$row["null"] = !$row["attnotnull"];
$row["auto_increment"] = eregi("^nextval\\(", $row["default"]);
$row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1);
if (preg_match('~^(.*)::.+$~', $row["default"], $match)) {
@@ -261,8 +261,8 @@ ORDER BY a.attnum"
$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, indisprimary, indkey FROM pg_index i, pg_class ci WHERE i.indrelid = $table_oid AND ci.oid = i.indexrelid", $connection2) as $row) {
$return[$row["relname"]]["type"] = ($row["indisprimary"] == "t" ? "PRIMARY" : ($row["indisunique"] == "t" ? "UNIQUE" : "INDEX"));
foreach (get_rows("SELECT relname, indisunique::int, indisprimary::int, indkey FROM pg_index i, pg_class ci WHERE i.indrelid = $table_oid AND ci.oid = i.indexrelid", $connection2) as $row) {
$return[$row["relname"]]["type"] = ($row["indisprimary"] ? "PRIMARY" : ($row["indisunique"] ? "UNIQUE" : "INDEX"));
$return[$row["relname"]]["columns"] = array();
foreach (explode(" ", $row["indkey"]) as $indkey) {
$return[$row["relname"]]["columns"][] = $columns[$indkey];
@@ -607,7 +607,7 @@ AND typelem = 0"
$structured_types[$key] = array_keys($val);
}
$unsigned = array();
$operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"); // no "" to avoid SQL injection
$operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"); // no "SQL" to avoid SQL injection
$functions = array("char_length", "lower", "round", "to_hex", "to_timestamp", "upper");
$grouping = array("avg", "count", "count distinct", "max", "min", "sum");
$edit_functions = array(

View File

@@ -620,7 +620,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
function create_sql($table, $auto_increment) {
global $connection;
$return = $connection->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table));
$return = $connection->result("SELECT sql FROM sqlite_master WHERE type IN ('table', 'view') AND name = " . q($table));
foreach (indexes($table) as $name => $index) {
if ($name == '') {
continue;
@@ -674,7 +674,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
$types = array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0);
$structured_types = array_keys($types);
$unsigned = array();
$operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", ""); // REGEXP can be user defined function
$operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"); // REGEXP can be user defined function
$functions = array("hex", "length", "lower", "round", "unixepoch", "upper");
$grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
$edit_functions = array(

View File

@@ -12,6 +12,7 @@ if ($_POST && !$error) {
(count($tables) == 1 ? key($tables) : DB),
(DB == "" || count($tables) > 1));
$is_sql = ereg('sql', $_POST["format"]);
if ($is_sql) {
echo "-- Adminer $VERSION " . $drivers[DRIVER] . " dump
@@ -31,6 +32,7 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
$databases = explode("\n", rtrim(str_replace("\r", "", $databases), "\n"));
}
}
foreach ((array) $databases as $db) {
$adminer->dumpDatabase($db);
if ($connection->select_db($db)) {
@@ -45,6 +47,7 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
echo use_sql($db) . ";\n\n";
}
$out = "";
if ($_POST["routines"]) {
foreach (array("FUNCTION", "PROCEDURE") as $routine) {
foreach (get_rows("SHOW $routine STATUS WHERE Db = " . q($db), null, "-- ") as $row) {
@@ -53,12 +56,14 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
}
}
}
if ($_POST["events"]) {
foreach (get_rows("SHOW EVENTS", null, "-- ") as $row) {
$out .= ($style != 'DROP+CREATE' ? "DROP EVENT IF EXISTS " . idf_escape($row["Name"]) . ";;\n" : "")
. remove_definer($connection->result("SHOW CREATE EVENT " . idf_escape($row["Name"]), 3)) . ";;\n\n";
}
}
if ($out) {
echo "DELIMITER ;;\n\n$out" . "DELIMITER ;\n\n";
}
@@ -66,40 +71,46 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
if ($_POST["table_style"] || $_POST["data_style"]) {
$views = array();
foreach (table_status() as $table_status) {
$table = (DB == "" || in_array($table_status["Name"], (array) $_POST["tables"]));
$data = (DB == "" || in_array($table_status["Name"], (array) $_POST["data"]));
foreach (table_status('', true) as $name => $table_status) {
$table = (DB == "" || in_array($name, (array) $_POST["tables"]));
$data = (DB == "" || in_array($name, (array) $_POST["data"]));
if ($table || $data) {
if (!is_view($table_status)) {
if ($ext == "tar") {
ob_start();
}
$adminer->dumpTable($table_status["Name"], ($table ? $_POST["table_style"] : ""));
if ($data) {
$adminer->dumpData($table_status["Name"], $_POST["data_style"], "SELECT * FROM " . table($table_status["Name"]));
}
if ($is_sql && $_POST["triggers"] && $table && ($triggers = trigger_sql($table_status["Name"], $_POST["table_style"]))) {
echo "\nDELIMITER ;;\n$triggers\nDELIMITER ;\n";
}
if ($ext == "tar") {
echo tar_file((DB != "" ? "" : "$db/") . "$table_status[Name].csv", ob_get_clean());
} elseif ($is_sql) {
echo "\n";
}
if ($ext == "tar") {
$tmp_file = new TmpFile;
ob_start(array($tmp_file, 'write'), 1e5);
}
$adminer->dumpTable($name, ($table ? $_POST["table_style"] : ""), (is_view($table_status) ? 2 : 0));
if (is_view($table_status)) {
$views[] = $name;
} elseif ($data) {
$fields = fields($name);
$adminer->dumpData($name, $_POST["data_style"], "SELECT *" . convert_fields($fields, $fields) . " FROM " . table($name));
}
if ($is_sql && $_POST["triggers"] && $table && ($triggers = trigger_sql($name, $_POST["table_style"]))) {
echo "\nDELIMITER ;;\n$triggers\nDELIMITER ;\n";
}
if ($ext == "tar") {
ob_end_flush();
tar_file((DB != "" ? "" : "$db/") . "$name.csv", $tmp_file);
} elseif ($is_sql) {
$views[] = $table_status["Name"];
echo "\n";
}
}
}
foreach ($views as $view) {
$adminer->dumpTable($view, $_POST["table_style"], true);
$adminer->dumpTable($view, $_POST["table_style"], 1);
}
if ($ext == "tar") {
echo pack("x512");
}
}
}
}
if ($is_sql) {
echo "-- " . $connection->result("SELECT NOW()") . "\n";
}
@@ -126,16 +137,21 @@ if (!isset($row["events"])) { // backwards compatibility
$row["routines"] = $row["events"] = ($_GET["dump"] == "");
$row["triggers"] = $row["table_style"];
}
echo "<tr><th>" . lang('Output') . "<td>" . html_select("output", $adminer->dumpOutput(), $row["output"], 0) . "\n"; // 0 - radio
echo "<tr><th>" . lang('Format') . "<td>" . html_select("format", $adminer->dumpFormat(), $row["format"], 0) . "\n"; // 0 - radio
echo ($jush == "sqlite" ? "" : "<tr><th>" . lang('Database') . "<td>" . html_select('db_style', $db_style, $row["db_style"])
. (support("routine") ? checkbox("routines", 1, $row["routines"], lang('Routines')) : "")
. (support("event") ? checkbox("events", 1, $row["events"], lang('Events')) : "")
);
echo "<tr><th>" . lang('Tables') . "<td>" . html_select('table_style', $table_style, $row["table_style"])
. checkbox("auto_increment", 1, $row["auto_increment"], lang('Auto Increment'))
. (support("trigger") ? checkbox("triggers", 1, $row["triggers"], lang('Triggers')) : "")
;
echo "<tr><th>" . lang('Data') . "<td>" . html_select('data_style', $data_style, $row["data_style"]);
?>
</table>
@@ -151,21 +167,26 @@ if (DB != "") {
echo "<th style='text-align: left;'><label><input type='checkbox' id='check-tables'$checked onclick='formCheck(this, /^tables\\[/);'>" . lang('Tables') . "</label>";
echo "<th style='text-align: right;'><label>" . lang('Data') . "<input type='checkbox' id='check-data'$checked onclick='formCheck(this, /^data\\[/);'></label>";
echo "</thead>\n";
$views = "";
//! defer number of rows to JavaScript
foreach (table_status() as $table_status) {
$name = $table_status["Name"];
$tables_list = tables_list();
foreach ($tables_list as $name => $type) {
$prefix = ereg_replace("_.*", "", $name);
$checked = ($TABLE == "" || $TABLE == (substr($TABLE, -1) == "%" ? "$prefix%" : $name)); //! % may be part of table name
$print = "<tr><td>" . checkbox("tables[]", $name, $checked, $name, "checkboxClick(event, this); formUncheck('check-tables');");
if (is_view($table_status)) {
if ($type !== null && !eregi("table", $type)) {
$views .= "$print\n";
} else {
echo "$print<td align='right'><label>" . ($table_status["Engine"] == "InnoDB" && $table_status["Rows"] ? "~ " : "") . $table_status["Rows"] . checkbox("data[]", $name, $checked, "", "checkboxClick(event, this); formUncheck('check-data');") . "</label>\n";
echo "$print<td align='right'><label><span id='Rows-" . h($name) . "'></span>" . checkbox("data[]", $name, $checked, "", "checkboxClick(event, this); formUncheck('check-data');") . "</label>\n";
}
$prefixes[$prefix]++;
}
echo $views;
if ($tables_list) {
echo "<script type='text/javascript'>ajaxSetHtml('" . js_escape(ME) . "script=db');</script>\n";
}
} else {
echo "<thead><tr><th style='text-align: left;'><label><input type='checkbox' id='check-databases'" . ($TABLE == "" ? " checked" : "") . " onclick='formCheck(this, /^databases\\[/);'>" . lang('Database') . "</label></thead>\n";
$databases = $adminer->databases();

View File

@@ -8,6 +8,7 @@ foreach ($fields as $name => $field) {
unset($fields[$name]);
}
}
if ($_POST && !$error && !isset($_GET["select"])) {
$location = $_POST["referer"];
if ($_POST["insert"]) { // continue edit or insert
@@ -15,8 +16,18 @@ if ($_POST && !$error && !isset($_GET["select"])) {
} elseif (!ereg('^.+&select=.+$', $location)) {
$location = ME . "select=" . urlencode($TABLE);
}
$indexes = indexes($TABLE);
$unique_array = unique_array($_GET["where"], $indexes);
$query_where = "\nWHERE $where";
if (isset($_POST["delete"])) {
query_redirect("DELETE" . limit1("FROM " . table($TABLE), " WHERE $where"), $location, lang('Item has been deleted.'));
$query = "FROM " . table($TABLE);
query_redirect(
"DELETE" . ($unique_array ? " $query$query_where" : limit1($query, $query_where)),
$location,
lang('Item has been deleted.')
);
} else {
$set = array();
foreach ($fields as $name => $field) {
@@ -25,11 +36,17 @@ if ($_POST && !$error && !isset($_GET["select"])) {
$set[idf_escape($name)] = ($update ? "\n" . idf_escape($name) . " = $val" : $val);
}
}
if ($update) {
if (!$set) {
redirect($location);
}
query_redirect("UPDATE" . limit1(table($TABLE) . " SET" . implode(",", $set), "\nWHERE $where"), $location, lang('Item has been updated.'));
$query = table($TABLE) . " SET" . implode(",", $set);
query_redirect(
"UPDATE" . ($unique_array ? " $query$query_where" : limit1($query, $query_where)),
$location,
lang('Item has been updated.')
);
} else {
$result = insert_into($TABLE, $set);
$last_id = ($result ? last_id() : 0);
@@ -38,7 +55,7 @@ if ($_POST && !$error && !isset($_GET["select"])) {
}
}
$table_name = $adminer->tableName(table_status($TABLE));
$table_name = $adminer->tableName(table_status($TABLE, true));
page_header(
($update ? lang('Edit') : lang('Insert')),
$error,
@@ -81,12 +98,19 @@ if (!$fields) {
echo "<p class='error'>" . lang('You have no privileges to update this table.') . "\n";
} else {
echo "<table cellspacing='0' onkeydown='return editingKeydown(event);'>\n";
foreach ($fields as $name => $field) {
echo "<tr><th>" . $adminer->fieldName($field);
$default = $_GET["set"][bracket_escape($name)];
if ($default === null) {
$default = $field["default"];
if ($field["type"] == "bit" && ereg("^b'([01]*)'\$", $default, $regs)) {
$default = $regs[1];
}
}
$value = ($row !== null
? ($row[$name] != "" && $jush == "sql" && ereg("enum|set", $field["type"]) ? (is_array($row[$name]) ? array_sum($row[$name]) : +$row[$name]) : $row[$name])
: (!$update && $field["auto_increment"] ? "" : (isset($_GET["select"]) ? false : ($default !== null ? $default : $field["default"])))
: (!$update && $field["auto_increment"] ? "" : (isset($_GET["select"]) ? false : $default))
);
if (!$_POST["save"] && is_string($value)) {
$value = $adminer->editVal($value, $field);
@@ -99,6 +123,7 @@ if (!$fields) {
input($field, $value, $function);
echo "\n";
}
echo "</table>\n";
}
?>
@@ -111,7 +136,7 @@ if ($fields) {
}
}
echo ($update ? "<input type='submit' name='delete' value='" . lang('Delete') . "' onclick=\"return confirm('" . lang('Are you sure?') . "');\">\n"
: ($_POST || !$fields ? "" : "<script type='text/javascript'>document.getElementById('form').getElementsByTagName('td')[1].firstChild.focus();</script>\n")
: ($_POST || !$fields ? "" : "<script type='text/javascript'>focus(document.getElementById('form').getElementsByTagName('td')[1].firstChild);</script>\n")
);
if (isset($_GET["select"])) {
hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"]));

View File

@@ -2,31 +2,32 @@
$EVENT = $_GET["event"];
$intervals = array("YEAR", "QUARTER", "MONTH", "DAY", "HOUR", "MINUTE", "WEEK", "SECOND", "YEAR_MONTH", "DAY_HOUR", "DAY_MINUTE", "DAY_SECOND", "HOUR_MINUTE", "HOUR_SECOND", "MINUTE_SECOND");
$statuses = array("ENABLED" => "ENABLE", "DISABLED" => "DISABLE", "SLAVESIDE_DISABLED" => "DISABLE ON SLAVE");
$row = $_POST;
if ($_POST && !$error) {
if ($_POST["drop"]) {
query_redirect("DROP EVENT " . idf_escape($EVENT), substr(ME, 0, -1), lang('Event has been dropped.'));
} elseif (in_array($_POST["INTERVAL_FIELD"], $intervals) && isset($statuses[$_POST["STATUS"]])) {
$schedule = "\nON SCHEDULE " . ($_POST["INTERVAL_VALUE"]
? "EVERY " . q($_POST["INTERVAL_VALUE"]) . " $_POST[INTERVAL_FIELD]"
. ($_POST["STARTS"] ? " STARTS " . q($_POST["STARTS"]) : "")
. ($_POST["ENDS"] ? " ENDS " . q($_POST["ENDS"]) : "") //! ALTER EVENT doesn't drop ENDS - MySQL bug #39173
: "AT " . q($_POST["STARTS"])
) . " ON COMPLETION" . ($_POST["ON_COMPLETION"] ? "" : " NOT") . " PRESERVE"
} elseif (in_array($row["INTERVAL_FIELD"], $intervals) && isset($statuses[$row["STATUS"]])) {
$schedule = "\nON SCHEDULE " . ($row["INTERVAL_VALUE"]
? "EVERY " . q($row["INTERVAL_VALUE"]) . " $row[INTERVAL_FIELD]"
. ($row["STARTS"] ? " STARTS " . q($row["STARTS"]) : "")
. ($row["ENDS"] ? " ENDS " . q($row["ENDS"]) : "") //! ALTER EVENT doesn't drop ENDS - MySQL bug #39173
: "AT " . q($row["STARTS"])
) . " ON COMPLETION" . ($row["ON_COMPLETION"] ? "" : " NOT") . " PRESERVE"
;
queries_redirect(substr(ME, 0, -1), ($EVENT != "" ? lang('Event has been altered.') : lang('Event has been created.')), queries(($EVENT != ""
? "ALTER EVENT " . idf_escape($EVENT) . $schedule
. ($EVENT != $_POST["EVENT_NAME"] ? "\nRENAME TO " . idf_escape($_POST["EVENT_NAME"]) : "")
: "CREATE EVENT " . idf_escape($_POST["EVENT_NAME"]) . $schedule
) . "\n" . $statuses[$_POST["STATUS"]] . " COMMENT " . q($_POST["EVENT_COMMENT"])
. rtrim(" DO\n$_POST[EVENT_DEFINITION]", ";") . ";"
. ($EVENT != $row["EVENT_NAME"] ? "\nRENAME TO " . idf_escape($row["EVENT_NAME"]) : "")
: "CREATE EVENT " . idf_escape($row["EVENT_NAME"]) . $schedule
) . "\n" . $statuses[$row["STATUS"]] . " COMMENT " . q($row["EVENT_COMMENT"])
. rtrim(" DO\n$row[EVENT_DEFINITION]", ";") . ";"
));
}
}
page_header(($EVENT != "" ? lang('Alter event') . ": " . h($EVENT) : lang('Create event')), $error);
$row = $_POST;
if (!$row && $EVENT != "") {
$rows = get_rows("SELECT * FROM information_schema.EVENTS WHERE EVENT_SCHEMA = " . q(DB) . " AND EVENT_NAME = " . q($EVENT));
$row = reset($rows);

View File

@@ -1,50 +1,50 @@
<?php
$TABLE = $_GET["foreign"];
$name = $_GET["name"];
$row = $_POST;
if ($_POST && !$error && !$_POST["add"] && !$_POST["change"] && !$_POST["change-js"]) {
if ($_POST["drop"]) {
query_redirect("ALTER TABLE " . table($TABLE) . "\nDROP " . ($jush == "sql" ? "FOREIGN KEY " : "CONSTRAINT ") . idf_escape($_GET["name"]), ME . "table=" . urlencode($TABLE), lang('Foreign key has been dropped.'));
query_redirect("ALTER TABLE " . table($TABLE) . "\nDROP " . ($jush == "sql" ? "FOREIGN KEY " : "CONSTRAINT ") . idf_escape($name), ME . "table=" . urlencode($TABLE), lang('Foreign key has been dropped.'));
} else {
$source = array_filter($_POST["source"], 'strlen');
$source = array_filter($row["source"], 'strlen');
ksort($source); // enforce input order
$target = array();
foreach ($source as $key => $val) {
$target[$key] = $_POST["target"][$key];
$target[$key] = $row["target"][$key];
}
query_redirect("ALTER TABLE " . table($TABLE)
. ($_GET["name"] != "" ? "\nDROP " . ($jush == "sql" ? "FOREIGN KEY " : "CONSTRAINT ") . idf_escape($_GET["name"]) . "," : "")
. "\nADD FOREIGN KEY (" . implode(", ", array_map('idf_escape', $source)) . ") REFERENCES " . table($_POST["table"]) . " (" . implode(", ", array_map('idf_escape', $target)) . ")" //! reuse $_GET["name"] - check in older MySQL versions
. (ereg("^($on_actions)\$", $_POST["on_delete"]) ? " ON DELETE $_POST[on_delete]" : "")
. (ereg("^($on_actions)\$", $_POST["on_update"]) ? " ON UPDATE $_POST[on_update]" : "")
, ME . "table=" . urlencode($TABLE), ($_GET["name"] != "" ? lang('Foreign key has been altered.') : lang('Foreign key has been created.')));
. ($name != "" ? "\nDROP " . ($jush == "sql" ? "FOREIGN KEY " : "CONSTRAINT ") . idf_escape($name) . "," : "")
. "\nADD FOREIGN KEY (" . implode(", ", array_map('idf_escape', $source)) . ") REFERENCES " . table($row["table"]) . " (" . implode(", ", array_map('idf_escape', $target)) . ")" //! reuse $name - check in older MySQL versions
. (ereg("^($on_actions)\$", $row["on_delete"]) ? " ON DELETE $row[on_delete]" : "")
. (ereg("^($on_actions)\$", $row["on_update"]) ? " ON UPDATE $row[on_update]" : "")
, ME . "table=" . urlencode($TABLE), ($name != "" ? lang('Foreign key has been altered.') : lang('Foreign key has been created.')));
$error = lang('Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.') . "<br>$error"; //! no partitioning
}
}
page_header(lang('Foreign key'), $error, array("table" => $TABLE), $TABLE);
$row = array("table" => $TABLE, "source" => array(""));
if ($_POST) {
$row = $_POST;
ksort($row["source"]);
if ($_POST["add"]) {
$row["source"][] = "";
} elseif ($_POST["change"] || $_POST["change-js"]) {
$row["target"] = array();
}
} elseif ($_GET["name"] != "") {
} elseif ($name != "") {
$foreign_keys = foreign_keys($TABLE);
$row = $foreign_keys[$_GET["name"]];
$row = $foreign_keys[$name];
$row["source"][] = "";
} else {
$row["table"] = $TABLE;
$row["source"] = array("");
}
$source = array_keys(fields($TABLE)); //! no text and blob
$target = ($TABLE === $row["table"] ? $source : array_keys(fields($row["table"])));
$referencable = array();
foreach (table_status() as $name => $table_status) {
if (fk_support($table_status)) {
$referencable[] = $name;
}
}
$referencable = array_keys(array_filter(table_status('', true), 'fk_support'));
?>
<form action="" method="post">
@@ -73,6 +73,6 @@ foreach ($row["source"] as $key => $val) {
<input type="submit" value="<?php echo lang('Save'); ?>">
<noscript><p><input type="submit" name="add" value="<?php echo lang('Add column'); ?>"></noscript>
<?php } ?>
<?php if ($_GET["name"] != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
<?php if ($name != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form>

View File

@@ -71,14 +71,14 @@ class Adminer {
?>
<table cellspacing="0">
<tr><th><?php echo lang('System'); ?><td><?php echo html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);"); ?>
<tr><th><?php echo lang('Server'); ?><td><input name="auth[server]" value="<?php echo h(SERVER); ?>" title="hostname[:port]" autocapitalize="off">
<tr><th><?php echo lang('Server'); ?><td><input name="auth[server]" value="<?php echo h(SERVER); ?>" title="hostname[:port]" placeholder="localhost" autocapitalize="off">
<tr><th><?php echo lang('Username'); ?><td><input name="auth[username]" id="username" value="<?php echo h($_GET["username"]); ?>" autocapitalize="off">
<tr><th><?php echo lang('Password'); ?><td><input type="password" name="auth[password]">
<tr><th><?php echo lang('Database'); ?><td><input name="auth[db]" value="<?php echo h($_GET["db"]); ?>" autocapitalize="off">
</table>
<script type="text/javascript">
var username = document.getElementById('username');
username.focus();
focus(username);
username.form['auth[driver]'].onchange();
</script>
<?php
@@ -264,7 +264,7 @@ username.form['auth[driver]'].onchange();
if (!$val || ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators))) {
echo "<div><select name='where[$i][col]' onchange='$change_next'><option value=''>(" . lang('anywhere') . ")" . optionlist($columns, $val["col"], true) . "</select>";
echo html_select("where[$i][op]", $this->operators, $val["op"], $change_next);
echo "<input type='search' name='where[$i][val]' value='" . h($val["val"]) . "' onchange='" . ($val ? "selectFieldChange(this.form)" : "selectAddRow(this)") . ";' onsearch='selectSearch(this);'></div>\n";
echo "<input type='search' name='where[$i][val]' value='" . h($val["val"]) . "' onchange='" . ($val ? "selectFieldChange(this.form)" : "selectAddRow(this)") . ";' onsearch='selectSearchSearch(this);'></div>\n";
}
}
echo "</div></fieldset>\n";
@@ -400,8 +400,8 @@ username.form['auth[driver]'].onchange();
if (ereg('IN$', $val["op"])) {
$in = process_length($val["val"]);
$cond .= " (" . ($in != "" ? $in : "NULL") . ")";
} elseif (!$val["op"]) {
$cond .= $val["val"]; // SQL injection
} elseif ($val["op"] == "SQL") {
$cond = " $val[val]"; // SQL injection
} elseif ($val["op"] == "LIKE %%") {
$cond = " LIKE " . $this->processInput($fields[$val["col"]], "%$val[val]%");
} elseif (!ereg('NULL$', $val["op"])) {
@@ -414,7 +414,7 @@ username.form['auth[driver]'].onchange();
$cols = array();
foreach ($fields as $name => $field) {
$is_text = ereg('char|text|enum|set', $field["type"]);
if ((is_numeric($val["val"]) || !ereg('int|float|double|decimal|bit', $field["type"]))
if ((is_numeric($val["val"]) || !ereg('(^|[^o])int|float|double|decimal|bit', $field["type"]))
&& (!ereg("[\x80-\xFF]", $val["val"]) || $is_text)
) {
$name = idf_escape($name);
@@ -510,7 +510,7 @@ username.form['auth[driver]'].onchange();
}
}
if ($key && !ereg('set|blob|bytea|raw|file', $field["type"])) {
$return .= "/=";
$return .= "/SQL";
}
}
}
@@ -541,11 +541,11 @@ username.form['auth[driver]'].onchange();
* @return string expression to use in a query
*/
function processInput($field, $value, $function = "") {
if ($function == "=") {
if ($function == "SQL") {
return $value; // SQL injection
}
$name = $field["field"];
$return = ($field["type"] == "bit" && ereg("^([0-9]+|b'[0-1]+')\$", $value) ? $value : q($value));
$return = q($value);
if (ereg('^(now|getdate|uuid)$', $function)) {
$return = "$function()";
} elseif (ereg('^current_(date|timestamp)$', $function)) {
@@ -570,9 +570,6 @@ username.form['auth[driver]'].onchange();
if (function_exists('gzencode')) {
$return['gz'] = 'gzip';
}
if (function_exists('bzcompress')) {
$return['bz2'] = 'bzip2';
}
return $return;
}
@@ -593,22 +590,30 @@ username.form['auth[driver]'].onchange();
/** Export table structure
* @param string
* @param string
* @param bool
* @param int 0 table, 1 view, 2 temporary view table
* @return null prints data
*/
function dumpTable($table, $style, $is_view = false) {
function dumpTable($table, $style, $is_view = 0) {
if ($_POST["format"] != "sql") {
echo "\xef\xbb\xbf"; // UTF-8 byte order mark
if ($style) {
dump_csv(array_keys(fields($table)));
}
} elseif ($style) {
$create = create_sql($table, $_POST["auto_increment"]);
if ($create) {
if ($style == "DROP+CREATE") {
echo "DROP " . ($is_view ? "VIEW" : "TABLE") . " IF EXISTS " . table($table) . ";\n";
if ($is_view == 2) {
$fields = array();
foreach (fields($table) as $name => $field) {
$fields[] = idf_escape($name) . " $field[full_type]";
}
if ($is_view) {
$create = "CREATE TABLE " . table($table) . " (" . implode(", ", $fields) . ")";
} else {
$create = create_sql($table, $_POST["auto_increment"]);
}
if ($create) {
if ($style == "DROP+CREATE" || $is_view == 1) {
echo "DROP " . ($is_view == 2 ? "VIEW" : "TABLE") . " IF EXISTS " . table($table) . ";\n";
}
if ($is_view == 1) {
$create = remove_definer($create);
}
echo "$create;\n\n";
@@ -626,10 +631,10 @@ username.form['auth[driver]'].onchange();
global $connection, $jush;
$max_packet = ($jush == "sqlite" ? 0 : 1048576); // default, minimum is 1024
if ($style) {
if ($_POST["format"] == "sql" && $style == "TRUNCATE+INSERT") {
echo truncate_sql($table) . ";\n";
}
if ($_POST["format"] == "sql") {
if ($style == "TRUNCATE+INSERT") {
echo truncate_sql($table) . ";\n";
}
$fields = fields($table);
}
$result = $connection->query($query, 1); // 1 - MYSQLI_USE_RESULT //! enum and set as numbers
@@ -638,7 +643,8 @@ username.form['auth[driver]'].onchange();
$buffer = "";
$keys = array();
$suffix = "";
while ($row = $result->fetch_row()) {
$fetch_function = ($table != '' ? 'fetch_assoc' : 'fetch_row');
while ($row = $result->$fetch_function()) {
if (!$keys) {
$values = array();
foreach ($row as $val) {
@@ -660,8 +666,9 @@ username.form['auth[driver]'].onchange();
$insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('idf_escape', $keys)) . ") VALUES";
}
foreach ($row as $key => $val) {
$field = $fields[$key];
$row[$key] = ($val !== null
? (ereg('int|float|double|decimal|bit', $fields[$keys[$key]]["type"]) && $val != '' ? $val : q($val)) //! columns looking like functions
? unconvert_field($field, ereg('(^|[^o])int|float|double|decimal', $field["type"]) && $val != '' ? $val : q($val))
: "NULL"
);
}
@@ -702,14 +709,10 @@ username.form['auth[driver]'].onchange();
$output = $_POST["output"];
$ext = (ereg('sql', $_POST["format"]) ? "sql" : ($multi_table ? "tar" : "csv")); // multiple CSV packed to TAR
header("Content-Type: " .
($output == "bz2" ? "application/x-bzip" :
($output == "gz" ? "application/x-gzip" :
($ext == "tar" ? "application/x-tar" :
($ext == "sql" || $output != "file" ? "text/plain" : "text/csv") . "; charset=utf-8"
))));
if ($output == "bz2") {
ob_start('bzcompress', 1e6);
}
)));
if ($output == "gz") {
ob_start('gzencode', 1e6);
}
@@ -777,7 +780,7 @@ username.form['auth[driver]'].onchange();
$this->databasesPrint($missing);
if ($_GET["ns"] !== "" && !$missing && DB != "") {
echo '<p><a href="' . h(ME) . 'create="' . bold($_GET["create"] === "") . ">" . lang('Create new table') . "</a>\n";
$tables = tables_list();
$tables = table_status('', true);
if (!$tables) {
echo "<p class='message'>" . lang('No tables.') . "\n";
} else {
@@ -832,14 +835,14 @@ echo ($databases
}
/** Prints table list in menu
* @param array
* @param array result of table_status('', true)
* @return null
*/
function tablesPrint($tables) {
echo "<p id='tables' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
foreach ($tables as $table => $type) {
foreach ($tables as $table => $status) {
echo '<a href="' . h(ME) . 'select=' . urlencode($table) . '"' . bold($_GET["select"] == $table) . ">" . lang('select') . "</a> ";
echo '<a href="' . h(ME) . 'table=' . urlencode($table) . '"' . bold($_GET["table"] == $table) . " title='" . lang('Show structure') . "'>" . $this->tableName(array("Name" => $table)) . "</a><br>\n"; //! Adminer::tableName may work with full table status
echo '<a href="' . h(ME) . 'table=' . urlencode($table) . '"' . bold($_GET["table"] == $table) . " title='" . lang('Show structure') . "'>" . $this->tableName($status) . "</a><br>\n";
}
}

View File

@@ -33,6 +33,7 @@ if ($auth) {
) {
redirect(auth_url($auth["driver"], $auth["server"], $auth["username"], $auth["db"]));
}
} elseif ($_POST["logout"]) {
if ($token && $_POST["token"] != $token) {
page_header(lang('Logout'), lang('Invalid CSRF token. Send the form again.'));
@@ -45,6 +46,7 @@ if ($auth) {
unset_permanent();
redirect(substr(preg_replace('~(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.'));
}
} elseif ($permanent && !$_SESSION["pwds"]) {
session_regenerate_id();
$private = $adminer->permanentLogin(); // try to decode even if not set
@@ -105,6 +107,7 @@ if (isset($_GET["username"])) {
}
$connection = connect();
}
if (is_string($connection) || !$adminer->login($_GET["username"], get_session("pwds"))) {
auth_error();
exit;
@@ -134,6 +137,7 @@ if ($_POST) {
: lang('Invalid CSRF token. Send the form again.')
);
}
} elseif ($_SERVER["REQUEST_METHOD"] == "POST") {
// posted form with no data means that post_max_size exceeded because Adminer always sends token at least
$error = lang('Too big POST data. Reduce the data or increase the %s configuration directive.', "'post_max_size'");

View File

@@ -28,7 +28,7 @@ include "../adminer/include/functions.inc.php";
global $adminer, $connection, $drivers, $edit_functions, $enum_length, $error, $functions, $grouping, $HTTPS, $inout, $jush, $LANG, $langs, $on_actions, $permanent, $structured_types, $token, $translations, $types, $unsigned, $VERSION; // allows including Adminer inside a function
if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility
$_SERVER["REQUEST_URI"] = $_SERVER["ORIG_PATH_INFO"];
$_SERVER["REQUEST_URI"] = $_SERVER["ORIG_PATH_INFO"];
}
if (!strpos($_SERVER["REQUEST_URI"], '?') && $_SERVER["QUERY_STRING"] != "") { // IIS 7 compatibility
$_SERVER["REQUEST_URI"] .= "?$_SERVER[QUERY_STRING]";

View File

@@ -31,6 +31,7 @@ function connect_error() {
echo "<form action='' method='post'>\n";
echo "<table cellspacing='0' class='checkable' onclick='tableClick(event);' ondblclick='tableClick(event, true);'>\n";
echo "<thead><tr><td>&nbsp;<th>" . lang('Database') . "<td>" . lang('Collation') . "<td>" . lang('Tables') . "</thead>\n";
foreach ($databases as $db) {
$root = h(ME) . "db=" . urlencode($db);
echo "<tr" . odd() . "><td>" . checkbox("db[]", $db, in_array($db, (array) $_POST["db"]));
@@ -39,6 +40,7 @@ function connect_error() {
echo "<td align='right'><a href='$root&amp;schema=' id='tables-" . h($db) . "' title='" . lang('Database schema') . "'>?</a>";
echo "\n";
}
echo "</table>\n";
echo "<script type='text/javascript'>tableCheck();</script>\n";
echo "<p><input type='submit' name='drop' value='" . lang('Drop') . "'" . confirm("formChecked(this, /db/)") . ">\n";
@@ -49,6 +51,7 @@ function connect_error() {
echo "<p>$refresh";
}
}
page_footer("db");
if ($databases) {
echo "<script type='text/javascript'>ajaxSetHtml('" . js_escape(ME) . "script=connect');</script>\n";

View File

@@ -98,5 +98,6 @@ function page_footer($missing = "") {
<div id="menu">
<?php $adminer->navigation($missing); ?>
</div>
<script type="text/javascript">setupSubmitHighlight(document);</script>
<?php
}

View File

@@ -3,7 +3,7 @@
* @param Min_Result
* @param Min_DB connection to examine indexes
* @param string base link for <th> fields
* @param array
* @param array
* @return null
*/
function select($result, $connection2 = null, $href = "", $orgtables = array()) {
@@ -94,7 +94,7 @@ function select($result, $connection2 = null, $href = "", $orgtables = array())
*/
function referencable_primary($self) {
$return = array(); // table_name => field
foreach (table_status() as $table_name => $table) {
foreach (table_status('', true) as $table_name => $table) {
if ($table_name != $self && fk_support($table)) {
foreach (fields($table_name) as $field) {
if ($field["primary"]) {
@@ -129,15 +129,6 @@ function textarea($name, $value, $rows = 10, $cols = 80) {
echo "</textarea>";
}
/** Format time difference
* @param string output of microtime()
* @param string output of microtime()
* @return string HTML code
*/
function format_time($start, $end) {
return " <span class='time'>(" . lang('%.3f s', max(0, array_sum(explode(" ", $end)) - array_sum(explode(" ", $start)))) . ")</span>";
}
/** Print table columns for type edit
* @param string
* @param array
@@ -151,7 +142,7 @@ function edit_type($key, $field, $collations, $foreign_keys = array()) {
<td><select name="<?php echo $key; ?>[type]" class="type" onfocus="lastType = selectValue(this);" onchange="editingTypeChange(this);"><?php echo optionlist((!$field["type"] || isset($types[$field["type"]]) ? array() : array($field["type"])) + $structured_types + ($foreign_keys ? array(lang('Foreign keys') => $foreign_keys) : array()), $field["type"]); ?></select>
<td><input name="<?php echo $key; ?>[length]" value="<?php echo h($field["length"]); ?>" size="3" onfocus="editingLengthFocus(this);"><td class="options"><?php //! type="number" with enabled JavaScript
echo "<select name='$key" . "[collation]'" . (ereg('(char|text|enum|set)$', $field["type"]) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>';
echo ($unsigned ? "<select name='$key" . "[unsigned]'" . (!$field["type"] || ereg('(int|float|double|decimal)$', $field["type"]) ? "" : " class='hidden'") . '><option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : '');
echo ($unsigned ? "<select name='$key" . "[unsigned]'" . (!$field["type"] || ereg('((^|[^o])int|float|double|decimal)$', $field["type"]) ? "" : " class='hidden'") . '><option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : '');
echo (isset($field['on_update']) ? "<select name='$key" . "[on_update]'" . ($field["type"] == "timestamp" ? "" : " class='hidden'") . '>' . optionlist(array("" => "(" . lang('ON UPDATE') . ")", "CURRENT_TIMESTAMP"), $field["on_update"]) . '</select>' : '');
echo ($foreign_keys ? "<select name='$key" . "[on_delete]'" . (ereg("`", $field["type"]) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", $on_actions), $field["on_delete"]) . "</select> " : " "); // space for IE
}
@@ -174,7 +165,7 @@ function process_type($field, $collate = "COLLATE") {
global $unsigned;
return " $field[type]"
. ($field["length"] != "" ? "(" . process_length($field["length"]) . ")" : "")
. (ereg('int|float|double|decimal', $field["type"]) && in_array($field["unsigned"], $unsigned) ? " $field[unsigned]" : "")
. (ereg('(^|[^o])int|float|double|decimal', $field["type"]) && in_array($field["unsigned"], $unsigned) ? " $field[unsigned]" : "")
. (ereg('char|text|enum|set', $field["type"]) && $field["collation"] ? " $collate " . q($field["collation"]) : "")
;
}
@@ -269,7 +260,7 @@ function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = arra
/** Move fields up and down or add field
* @param array
* @return null
* @return bool
*/
function process_fields(&$fields) {
ksort($fields);
@@ -287,8 +278,7 @@ function process_fields(&$fields) {
}
$offset++;
}
}
if ($_POST["down"]) {
} elseif ($_POST["down"]) {
$found = false;
foreach ($fields as $key => $field) {
if (isset($field["field"]) && $found) {
@@ -301,11 +291,13 @@ function process_fields(&$fields) {
}
$offset++;
}
}
$fields = array_values($fields);
if ($_POST["add"]) {
} elseif ($_POST["add"]) {
$fields = array_values($fields);
array_splice($fields, key($_POST["add"]), 0, array(array()));
} elseif (!$_POST["drop_col"]) {
return false;
}
return true;
}
/** Callback used in routine()
@@ -338,9 +330,12 @@ function grant($grant, $privileges, $columns, $on) {
}
/** Drop old object and create a new one
* @param string drop query
* @param string create query
* @param string rollback query
* @param string drop old object query
* @param string create new object query
* @param string drop new object query
* @param string create test object query
* @param string drop test object query
* @param string
* @param string
* @param string
* @param string
@@ -348,32 +343,40 @@ function grant($grant, $privileges, $columns, $on) {
* @param string
* @return null redirect in success
*/
function drop_create($drop, $create, $rollback, $location, $message_drop, $message_alter, $message_create, $name) {
function drop_create($drop, $create, $drop_created, $test, $drop_test, $location, $message_drop, $message_alter, $message_create, $old_name, $new_name) {
if ($_POST["drop"]) {
query_redirect($drop, $location, $message_drop);
} elseif ($old_name == "") {
query_redirect($create, $location, $message_create);
} elseif ($old_name != $new_name) {
$created = queries($create);
queries_redirect($location, $message_alter, $created && queries($drop));
if ($created) {
queries($drop_created);
}
} else {
if ($name != "") {
queries($drop);
}
queries_redirect($location, ($name != "" ? $message_alter : $message_create), queries($create));
if ($name != "") {
queries($rollback);
}
queries_redirect(
$location,
$message_alter,
queries($test) && queries($drop_test) && queries($drop) && queries($create)
);
}
}
/** Generate SQL query for creating trigger
* @param string
* @return array result of trigger()
* @param array result of trigger()
* @return string
*/
function create_trigger($on, $row) {
global $jush;
$timing_event = " $row[Timing] $row[Event]";
return "CREATE TRIGGER "
. idf_escape($row["Trigger"])
. ($jush == "mssql" ? $on . $timing_event : $timing_event . $on)
. rtrim(" $row[Type]\n$row[Statement]", ";")
. ";";
return "CREATE TRIGGER "
. idf_escape($row["Trigger"])
. ($jush == "mssql" ? $on . $timing_event : $timing_event . $on)
. rtrim(" $row[Type]\n$row[Statement]", ";")
. ";"
;
}
/** Generate SQL query for creating routine
@@ -391,13 +394,14 @@ function create_routine($routine, $row) {
$set[] = (ereg("^($inout)\$", $field["inout"]) ? "$field[inout] " : "") . idf_escape($field["field"]) . process_type($field, "CHARACTER SET");
}
}
return "CREATE $routine "
. idf_escape(trim($row["name"]))
. " (" . implode(", ", $set) . ")"
. (isset($_GET["function"]) ? " RETURNS" . process_type($row["returns"], "CHARACTER SET") : "")
. ($row["language"] ? " LANGUAGE $row[language]" : "")
. rtrim("\n$row[definition]", ";")
. ";";
return "CREATE $routine "
. idf_escape(trim($row["name"]))
. " (" . implode(", ", $set) . ")"
. (isset($_GET["function"]) ? " RETURNS" . process_type($row["returns"], "CHARACTER SET") : "")
. ($row["language"] ? " LANGUAGE $row[language]" : "")
. rtrim("\n$row[definition]", ";")
. ";"
;
}
/** Remove current user definer from SQL command
@@ -408,19 +412,22 @@ function remove_definer($query) {
return preg_replace('~^([A-Z =]+) DEFINER=`' . preg_replace('~@(.*)~', '`@`(%|\\1)', logged_user()) . '`~', '\\1', $query); //! proper escaping of user
}
/** Get string to add a file in TAR
/** Add a file to TAR
* @param string
* @param string
* @return string
* @param TmpFile
* @return null prints the output
*/
function tar_file($filename, $contents) {
$return = pack("a100a8a8a8a12a12", $filename, 644, 0, 0, decoct(strlen($contents)), decoct(time()));
function tar_file($filename, $tmp_file) {
$return = pack("a100a8a8a8a12a12", $filename, 644, 0, 0, decoct($tmp_file->size), decoct(time()));
$checksum = 8*32; // space for checksum itself
for ($i=0; $i < strlen($return); $i++) {
$checksum += ord($return[$i]);
}
$return .= sprintf("%06o", $checksum) . "\0 ";
return $return . str_repeat("\0", 512 - strlen($return)) . $contents . str_repeat("\0", 511 - (strlen($contents) + 511) % 512);
echo $return;
echo str_repeat("\0", 512 - strlen($return));
$tmp_file->send();
echo str_repeat("\0", 511 - ($tmp_file->size + 511) % 512);
}
/** Get INI bytes value

View File

@@ -303,7 +303,7 @@ function get_rows($query, $connection2 = null, $error = "<p class='error'>") {
/** Find unique identifier of a row
* @param array
* @param array result of indexes()
* @return array
* @return array or null if there is no unique identifier
*/
function unique_array($row, $indexes) {
foreach ($indexes as $index) {
@@ -318,13 +318,6 @@ function unique_array($row, $indexes) {
return $return;
}
}
$return = array();
foreach ($row as $key => $val) {
if (!preg_match('~^(COUNT\\((\\*|(DISTINCT )?`(?:[^`]|``)+`)\\)|(AVG|GROUP_CONCAT|MAX|MIN|SUM)\\(`(?:[^`]|``)+`\\))$~', $key)) { //! columns looking like functions
$return[$key] = $val;
}
}
return $return;
}
/** Create SQL condition from parsed query string
@@ -370,6 +363,26 @@ function where_link($i, $column, $value, $operator = "=") {
return "&where%5B$i%5D%5Bcol%5D=" . urlencode($column) . "&where%5B$i%5D%5Bop%5D=" . urlencode(($value !== null ? $operator : "IS NULL")) . "&where%5B$i%5D%5Bval%5D=" . urlencode($value);
}
/** Get select clause for convertible fields
* @param array
* @param array
* @param array
* @return string
*/
function convert_fields($columns, $fields, $select = array()) {
$return = "";
foreach ($columns as $key => $val) {
if ($select && !in_array(idf_escape($key), $select)) {
continue;
}
$as = convert_field($fields[$key]);
if ($as) {
$return .= ", $as AS " . idf_escape($key);
}
}
return $return;
}
/** Set cookie valid for 1 month
* @param string
* @param string
@@ -482,12 +495,15 @@ function redirect($location, $message = null) {
*/
function query_redirect($query, $location, $message, $redirect = true, $execute = true, $failed = false) {
global $connection, $error, $adminer;
$time = "";
if ($execute) {
$start = microtime();
$failed = !$connection->query($query);
$time = "; -- " . format_time($start, microtime());
}
$sql = "";
if ($query) {
$sql = $adminer->messageQuery("$query;");
$sql = $adminer->messageQuery($query . $time);
}
if ($failed) {
$error = error() . $sql;
@@ -508,10 +524,13 @@ function queries($query = null) {
static $queries = array();
if ($query === null) {
// return executed queries without parameter
return implode(";\n", $queries);
return implode("\n", $queries);
}
$queries[] = (ereg(';$', $query) ? "DELIMITER ;;\n$query;\nDELIMITER " : $query);
return $connection->query($query);
$start = microtime();
$return = $connection->query($query);
$queries[] = (ereg(';$', $query) ? "DELIMITER ;;\n$query;\nDELIMITER " : $query)
. "; -- " . format_time($start, microtime());
return $return;
}
/** Apply command to all array items
@@ -539,6 +558,15 @@ function queries_redirect($location, $message, $redirect) {
return query_redirect(queries(), $location, $message, $redirect, false, !$redirect);
}
/** Format time difference
* @param string output of microtime()
* @param string output of microtime()
* @return string HTML code
*/
function format_time($start, $end) {
return lang('%.3f s', max(0, array_sum(explode(" ", $end)) - array_sum(explode(" ", $start))));
}
/** Remove parameter from query string
* @param string
* @return string
@@ -563,21 +591,34 @@ function pagination($page, $current) {
*/
function get_file($key, $decompress = false) {
$file = $_FILES[$key];
if (!$file || $file["error"]) {
return $file["error"];
if (!$file) {
return null;
}
$return = file_get_contents($decompress && ereg('\\.gz$', $file["name"]) ? "compress.zlib://$file[tmp_name]"
: ($decompress && ereg('\\.bz2$', $file["name"]) ? "compress.bzip2://$file[tmp_name]"
: $file["tmp_name"]
)); //! may not be reachable because of open_basedir
if ($decompress) {
$start = substr($return, 0, 3);
if (function_exists("iconv") && ereg("^\xFE\xFF|^\xFF\xFE", $start, $regs)) { // not ternary operator to save memory
$return = iconv("utf-16", "utf-8", $return);
} elseif ($start == "\xEF\xBB\xBF") { // UTF-8 BOM
$return = substr($return, 3);
foreach ($file as $key => $val) {
$file[$key] = (array) $val;
}
$return = '';
foreach ($file["error"] as $key => $error) {
if ($error) {
return $error;
}
$name = $file["name"][$key];
$tmp_name = $file["tmp_name"][$key];
$content = file_get_contents($decompress && ereg('\\.gz$', $name)
? "compress.zlib://$tmp_name"
: $tmp_name
); //! may not be reachable because of open_basedir
if ($decompress) {
$start = substr($content, 0, 3);
if (function_exists("iconv") && ereg("^\xFE\xFF|^\xFF\xFE", $start, $regs)) { // not ternary operator to save memory
$content = iconv("utf-16", "utf-8", $content);
} elseif ($start == "\xEF\xBB\xBF") { // UTF-8 BOM
$content = substr($content, 3);
}
}
$return .= $content . "\n\n";
}
//! support SQL files not ending with semicolon
return $return;
}
@@ -803,7 +844,7 @@ function search_tables() {
$_GET["where"][0]["op"] = "LIKE %%";
$_GET["where"][0]["val"] = $_POST["query"];
$found = false;
foreach (table_status() as $table => $table_status) {
foreach (table_status('', true) as $table => $table_status) {
$name = $adminer->tableName($table_status);
if (isset($table_status["Engine"]) && $name != "" && (!$_POST["tables"] || in_array($table, $_POST["tables"]))) {
$result = $connection->query("SELECT" . limit("1 FROM " . table($table), " WHERE " . implode(" AND ", $adminer->selectSearchProcess(fields($table), array())), 1));
@@ -834,6 +875,8 @@ function dump_headers($identifier, $multi_table = false) {
header("Content-Disposition: attachment; filename=" . $adminer->dumpFilename($identifier) . ".$return" . ($output != "file" && !ereg('[^0-9a-z]', $output) ? ".$output" : ""));
}
session_write_close();
ob_flush();
flush();
return $return;
}

View File

@@ -6,7 +6,7 @@ if (extension_loaded('pdo')) {
function __construct() {
global $adminer;
$pos = array_search("", $adminer->operators);
$pos = array_search("SQL", $adminer->operators);
if ($pos !== false) {
unset($adminer->operators[$pos]);
}

View File

@@ -0,0 +1,22 @@
<?php
class TmpFile {
var $handler;
var $size;
function TmpFile() {
$this->handler = tmpfile();
}
function write($contents) {
$this->size += strlen($contents);
fwrite($this->handler, $contents);
}
function send() {
fseek($this->handler, 0);
fpassthru($this->handler);
fclose($this->handler);
}
}

View File

@@ -1,2 +1,2 @@
<?php
$VERSION = "3.6.4";
$VERSION = "3.7.0";

View File

@@ -8,6 +8,7 @@
*/
include "./include/bootstrap.inc.php";
include "./include/tmpfile.inc.php";
$enum_length = "'(?:''|[^'\\\\]|\\\\.)*+'";
$inout = "IN|OUT|INOUT";
@@ -21,6 +22,7 @@ if (isset($_GET["callf"])) {
if (isset($_GET["function"])) {
$_GET["procedure"] = $_GET["function"];
}
if (isset($_GET["download"])) {
include "./download.inc.php";
} elseif (isset($_GET["table"])) {

View File

@@ -1,7 +1,7 @@
<?php
$TABLE = $_GET["indexes"];
$index_types = array("PRIMARY", "UNIQUE", "INDEX");
$table_status = table_status($TABLE);
$table_status = table_status($TABLE, true);
if (eregi("MyISAM|M?aria" . ($connection->server_info >= 5.6 ? "|InnoDB" : ""), $table_status["Engine"])) {
$index_types[] = "FULLTEXT";
}
@@ -10,9 +10,11 @@ if ($jush == "sqlite") { // doesn't support primary key
unset($index_types[0]);
unset($indexes[""]);
}
$row = $_POST;
if ($_POST && !$error && !$_POST["add"]) {
$alter = array();
foreach ($_POST["indexes"] as $index) {
foreach ($row["indexes"] as $index) {
$name = $index["name"];
if (in_array($index["type"], $index_types)) {
$columns = array();
@@ -27,6 +29,7 @@ if ($_POST && !$error && !$_POST["add"]) {
$lengths[] = ($length ? $length : null);
}
}
if ($columns) {
$existing = $indexes[$name];
if ($existing) {
@@ -42,6 +45,7 @@ if ($_POST && !$error && !$_POST["add"]) {
}
}
}
// drop removed indexes
foreach ($indexes as $name => $existing) {
$alter[] = array($existing["type"], $name, "DROP");
@@ -55,26 +59,24 @@ if ($_POST && !$error && !$_POST["add"]) {
page_header(lang('Indexes'), $error, array("table" => $TABLE), $TABLE);
$fields = array_keys(fields($TABLE));
$row = array("indexes" => $indexes);
if ($_POST) {
$row = $_POST;
if ($_POST["add"]) {
foreach ($row["indexes"] as $key => $index) {
if ($index["columns"][count($index["columns"])] != "") {
$row["indexes"][$key]["columns"][] = "";
}
}
$index = end($row["indexes"]);
if ($index["type"] || array_filter($index["columns"], 'strlen') || array_filter($index["lengths"], 'strlen')) {
$row["indexes"][] = array("columns" => array(1 => ""));
}
}
} else {
if ($_POST["add"]) {
foreach ($row["indexes"] as $key => $index) {
$row["indexes"][$key]["name"] = $key;
$row["indexes"][$key]["columns"][] = "";
if ($index["columns"][count($index["columns"])] != "") {
$row["indexes"][$key]["columns"][] = "";
}
}
$row["indexes"][] = array("columns" => array(1 => ""));
$index = end($row["indexes"]);
if ($index["type"] || array_filter($index["columns"], 'strlen') || array_filter($index["lengths"], 'strlen')) {
$row["indexes"][] = array("columns" => array(1 => ""));
}
}
if (!$row) {
foreach ($indexes as $key => $index) {
$indexes[$key]["name"] = $key;
$indexes[$key]["columns"][] = "";
}
$indexes[] = array("columns" => array(1 => ""));
$row["indexes"] = $indexes;
}
?>
@@ -86,12 +88,14 @@ $j = 1;
foreach ($row["indexes"] as $index) {
echo "<tr><td>" . html_select("indexes[$j][type]", array(-1 => "") + $index_types, $index["type"], ($j == count($row["indexes"]) ? "indexesAddRow(this);" : 1)) . "<td>";
ksort($index["columns"]);
$i = 1;
foreach ($index["columns"] as $key => $column) {
echo "<span>" . html_select("indexes[$j][columns][$i]", array(-1 => "") + $fields, $column, ($i == count($index["columns"]) ? "indexesAddColumn" : "indexesChangeColumn") . "(this, '" . js_escape($jush == "sql" ? "" : $_GET["indexes"] . "_") . "');");
echo "<input type='number' name='indexes[$j][lengths][$i]' class='size' value='" . h($index["lengths"][$key]) . "'> </span>"; //! hide for non-MySQL drivers, add ASC|DESC
$i++;
}
echo "<td><input name='indexes[$j][name]' value='" . h($index["name"]) . "' autocapitalize='off'>\n";
$j++;
}

View File

@@ -7,18 +7,22 @@ if (!$result) {
// list logged user, information_schema.USER_PRIVILEGES lists just the current user too
$result = $connection->query("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', 1) AS User, SUBSTRING_INDEX(CURRENT_USER, '@', -1) AS Host");
}
echo "<form action=''><p>\n";
hidden_fields_get();
echo "<input type='hidden' name='db' value='" . h(DB) . "'>\n";
echo ($grant ? "" : "<input type='hidden' name='grant' value=''>\n");
echo "<table cellspacing='0'>\n";
echo "<thead><tr><th>" . lang('Username') . "<th>" . lang('Server') . "<th>&nbsp;</thead>\n";
while ($row = $result->fetch_assoc()) {
echo '<tr' . odd() . '><td>' . h($row["User"]) . "<td>" . h($row["Host"]) . '<td><a href="' . h(ME . 'user=' . urlencode($row["User"]) . '&host=' . urlencode($row["Host"])) . '">' . lang('Edit') . "</a>\n";
}
if (!$grant || DB != "") {
echo "<tr" . odd() . "><td><input name='user' autocapitalize='off'><td><input name='host' value='localhost' autocapitalize='off'><td><input type='submit' value='" . lang('Edit') . "'>\n";
}
echo "</table>\n";
echo "</form>\n";

View File

@@ -1,32 +1,36 @@
<?php
$PROCEDURE = $_GET["procedure"];
$routine = (isset($_GET["function"]) ? "FUNCTION" : "PROCEDURE");
$routine_languages = routine_languages();
$row = ($PROCEDURE == "" ? array("fields" => array()) : routine($PROCEDURE, $routine));
$row["name"] = $PROCEDURE;
$row = $_POST;
$row["fields"] = (array) $row["fields"];
if ($_POST) {
if (!$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"] && !$_POST["down"]) {
drop_create(
"DROP $routine " . idf_escape($PROCEDURE),
create_routine($routine, $_POST),
create_routine($routine, $row),
substr(ME, 0, -1),
lang('Routine has been dropped.'),
lang('Routine has been altered.'),
lang('Routine has been created.'),
$PROCEDURE
);
}
$row = $_POST;
$row["fields"] = (array) $row["fields"];
process_fields($row["fields"]);
if ($_POST && !process_fields($row["fields"]) && !$error) {
$temp_name = "$row[name]_adminer_" . uniqid();
drop_create(
"DROP $routine " . idf_escape($PROCEDURE),
create_routine($routine, $row),
"DROP $routine " . idf_escape($row["name"]),
create_routine($routine, array("name" => $temp_name) + $row),
"DROP $routine " . idf_escape($temp_name),
substr(ME, 0, -1),
lang('Routine has been dropped.'),
lang('Routine has been altered.'),
lang('Routine has been created.'),
$PROCEDURE,
$row["name"]
);
}
page_header(($PROCEDURE != "" ? (isset($_GET["function"]) ? lang('Alter function') : lang('Alter procedure')) . ": " . h($PROCEDURE) : (isset($_GET["function"]) ? lang('Create function') : lang('Create procedure'))), $error);
if (!$_POST && $PROCEDURE != "") {
$row = routine($PROCEDURE, $routine);
$row["name"] = $PROCEDURE;
}
$collations = get_vals("SHOW CHARACTER SET");
sort($collations);
$routine_languages = routine_languages();
?>
<form action="" method="post" id="form">

View File

@@ -18,16 +18,18 @@ page_header(lang('Process list'), $error);
// HTML valid because there is always at least one process
$i = -1;
foreach (process_list() as $i => $row) {
if (!$i) {
echo "<thead><tr lang='en'>" . (support("kill") ? "<th>&nbsp;" : "");
foreach ($row as $key => $val) {
echo "<th>" . ($jush == "sql"
echo "<th>" . ($jush == "sql"
? "<a href='http://dev.mysql.com/doc/refman/" . substr($connection->server_info, 0, 3) . "/en/show-processlist.html#processlist_" . strtolower($key) . "' target='_blank' rel='noreferrer' class='help'>$key</a>"
: $key
);
}
echo "</thead>\n";
}
echo "<tr" . odd() . ">" . (support("kill") ? "<td>" . checkbox("kill[]", $row["Id"], 0) : "");
foreach ($row as $key => $val) {
echo "<td>" . (

View File

@@ -16,23 +16,23 @@ $base_left = -1;
$schema = array(); // table => array("fields" => array(name => field), "pos" => array(top, left), "references" => array(table => array(left => array(source, target))))
$referenced = array(); // target_table => array(table => array(left => target_column))
$lefts = array(); // float => bool
foreach (table_status() as $table_status) {
if (!isset($table_status["Engine"])) { // view
foreach (table_status('', true) as $table => $table_status) {
if (is_view($table_status)) {
continue;
}
$pos = 0;
$schema[$table_status["Name"]]["fields"] = array();
foreach (fields($table_status["Name"]) as $name => $field) {
$schema[$table]["fields"] = array();
foreach (fields($table) as $name => $field) {
$pos += 1.25;
$field["pos"] = $pos;
$schema[$table_status["Name"]]["fields"][$name] = $field;
$schema[$table]["fields"][$name] = $field;
}
$schema[$table_status["Name"]]["pos"] = ($table_pos[$table_status["Name"]] ? $table_pos[$table_status["Name"]] : array($top, 0));
foreach ($adminer->foreignKeys($table_status["Name"]) as $val) {
$schema[$table]["pos"] = ($table_pos[$table] ? $table_pos[$table] : array($top, 0));
foreach ($adminer->foreignKeys($table) as $val) {
if (!$val["db"]) {
$left = $base_left;
if ($table_pos[$table_status["Name"]][1] || $table_pos[$val["table"]][1]) {
$left = min(floatval($table_pos[$table_status["Name"]][1]), floatval($table_pos[$val["table"]][1])) - 1;
if ($table_pos[$table][1] || $table_pos[$val["table"]][1]) {
$left = min(floatval($table_pos[$table][1]), floatval($table_pos[$val["table"]][1])) - 1;
} else {
$base_left -= .1;
}
@@ -40,12 +40,12 @@ foreach (table_status() as $table_status) {
// find free $left
$left -= .0001;
}
$schema[$table_status["Name"]]["references"][$val["table"]][(string) $left] = array($val["source"], $val["target"]);
$referenced[$val["table"]][$table_status["Name"]][(string) $left] = $val["target"];
$schema[$table]["references"][$val["table"]][(string) $left] = array($val["source"], $val["target"]);
$referenced[$val["table"]][$table][(string) $left] = $val["target"];
$lefts[(string) $left] = true;
}
}
$top = max($top, $schema[$table_status["Name"]]["pos"][0] + 2.5 + $pos);
$top = max($top, $schema[$table]["pos"][0] + 2.5 + $pos);
}
?>
@@ -62,10 +62,12 @@ document.onmouseup = function (ev) {
foreach ($schema as $name => $table) {
echo "<div class='table' style='top: " . $table["pos"][0] . "em; left: " . $table["pos"][1] . "em;' onmousedown='schemaMousedown(this, event);'>";
echo '<a href="' . h(ME) . 'table=' . urlencode($name) . '"><b>' . h($name) . "</b></a>";
foreach ($table["fields"] as $field) {
$val = '<span' . type_class($field["type"]) . ' title="' . h($field["full_type"] . ($field["null"] ? " NULL" : '')) . '">' . h($field["field"]) . '</span>';
echo "<br>" . ($field["primary"] ? "<i>$val</i>" : $val);
}
foreach ((array) $table["references"] as $target_name => $refs) {
foreach ($refs as $left => $ref) {
$left1 = $left - $table_pos[$name][1];
@@ -75,6 +77,7 @@ foreach ($schema as $name => $table) {
}
}
}
foreach ((array) $referenced[$name] as $target_name => $refs) {
foreach ($refs as $left => $columns) {
$left1 = $left - $table_pos[$name][1];
@@ -84,8 +87,10 @@ foreach ($schema as $name => $table) {
}
}
}
echo "\n</div>\n";
}
foreach ($schema as $name => $table) {
foreach ((array) $table["references"] as $target_name => $refs) {
foreach ($refs as $left => $ref) {

View File

@@ -1,10 +1,12 @@
<?php
$row = $_POST;
if ($_POST && !$error) {
$link = preg_replace('~ns=[^&]*&~', '', ME) . "ns=";
if ($_POST["drop"]) {
query_redirect("DROP SCHEMA " . idf_escape($_GET["ns"]), $link, lang('Schema has been dropped.'));
} else {
$name = trim($_POST["name"]);
$name = trim($row["name"]);
$link .= urlencode($name);
if ($_GET["ns"] == "") {
query_redirect("CREATE SCHEMA " . idf_escape($name), $link, lang('Schema has been created.'));
@@ -18,15 +20,14 @@ if ($_POST && !$error) {
page_header($_GET["ns"] != "" ? lang('Alter schema') : lang('Create schema'), $error);
$row = $_POST;
if (!$row) {
$row = array("name" => $_GET["ns"]);
$row["name"] = $_GET["ns"];
}
?>
<form action="" method="post">
<p><input name="name" id="name" value="<?php echo h($row["name"]); ?>" autocapitalize="off">
<script type='text/javascript'>document.getElementById('name').focus();</script>
<script type='text/javascript'>focus(document.getElementById('name'));</script>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php
if ($_GET["ns"] != "") {

View File

@@ -3,8 +3,8 @@ header("Content-Type: text/javascript; charset=utf-8");
if ($_GET["script"] == "db") {
$sums = array("Data_length" => 0, "Index_length" => 0, "Data_free" => 0);
foreach (table_status() as $table_status) {
$id = js_escape($table_status["Name"]);
foreach (table_status() as $name => $table_status) {
$id = js_escape($name);
json_row("Comment-$id", nbsp($table_status["Comment"]));
if (!is_view($table_status)) {
foreach (array("Engine", "Collation") as $key) {

View File

@@ -17,7 +17,7 @@ $text_length = null;
foreach ($fields as $key => $field) {
$name = $adminer->fieldName($field);
if (isset($field["privileges"]["select"]) && $name != "") {
$columns[$key] = html_entity_decode(strip_tags($name));
$columns[$key] = html_entity_decode(strip_tags($name), ENT_QUOTES);
if (is_shortable($field)) {
$text_length = $adminer->selectLengthProcess();
}
@@ -30,32 +30,26 @@ $is_group = count($group) < count($select);
$where = $adminer->selectSearchProcess($fields, $indexes);
$order = $adminer->selectOrderProcess($fields, $indexes);
$limit = $adminer->selectLimitProcess();
$from = ($select ? implode(", ", $select) : "*" . ($oid ? ", $oid" : ""));
if ($jush == "sql") {
foreach ($columns as $key => $val) {
if ($select && !$select[$key]) {
continue;
}
$as = convert_field($fields[$key]);
if ($as) {
$from .= ", $as AS " . idf_escape($key);
}
}
}
$from .= "\nFROM " . table($TABLE);
$from = ($select ? implode(", ", $select) : "*" . ($oid ? ", $oid" : ""))
. convert_fields($columns, $fields, $select)
. "\nFROM " . table($TABLE);
$group_by = ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : "");
if ($_GET["val"] && is_ajax()) {
header("Content-Type: text/plain; charset=utf-8");
foreach ($_GET["val"] as $unique_idf => $row) {
$as = convert_field($fields[key($row)]);
echo $connection->result("SELECT" . limit(($as ? $as : idf_escape(key($row))) . " FROM " . table($TABLE), " WHERE " . where_check($unique_idf, $fields) . ($where ? " AND " . implode(" AND ", $where) : "") . ($order ? " ORDER BY " . implode(", ", $order) : ""), 1));
echo $connection->result("SELECT" . limit($as ? $as : idf_escape(key($row)) . " FROM " . table($TABLE), " WHERE " . where_check($unique_idf, $fields) . ($where ? " AND " . implode(" AND ", $where) : "") . ($order ? " ORDER BY " . implode(", ", $order) : ""), 1));
}
exit;
}
if ($_POST && !$error) {
$where_check = "(" . implode(") OR (", array_map('where_check', (array) $_POST["check"])) . ")";
$where_check = $where;
if (is_array($_POST["check"])) {
$where_check[] = "((" . implode(") OR (", array_map('where_check', $_POST["check"])) . "))";
}
$where_check = ($where_check ? "\nWHERE " . implode(" AND ", $where_check) : "");
$primary = $unselected = null;
foreach ($indexes as $index) {
if ($index["type"] == "PRIMARY") {
@@ -69,16 +63,13 @@ if ($_POST && !$error) {
unset($unselected[$key]);
}
}
if ($_POST["export"]) {
cookie("adminer_import", "output=" . urlencode($_POST["output"]) . "&format=" . urlencode($_POST["format"]));
dump_headers($TABLE);
$adminer->dumpTable($TABLE, "");
if (!is_array($_POST["check"]) || $unselected === array()) {
$where2 = $where;
if (is_array($_POST["check"])) {
$where2[] = "($where_check)";
}
$query = "SELECT $from" . ($where2 ? "\nWHERE " . implode(" AND ", $where2) : "") . $group_by;
$query = "SELECT $from$where_check$group_by";
} else {
$union = array();
foreach ($_POST["check"] as $val) {
@@ -90,6 +81,7 @@ if ($_POST && !$error) {
$adminer->dumpData($TABLE, "table", $query);
exit;
}
if (!$adminer->selectEmailProcess($where, $foreign_keys)) {
if ($_POST["save"] || $_POST["delete"]) { // edit
$result = true;
@@ -120,12 +112,12 @@ if ($_POST && !$error) {
$query = "INTO $query";
}
if ($_POST["all"] || ($unselected === array() && $_POST["check"]) || $is_group) {
$result = queries("$command $query" . ($_POST["all"] ? ($where ? "\nWHERE " . implode(" AND ", $where) : "") : "\nWHERE $where_check"));
$result = queries("$command $query$where_check");
$affected = $connection->affected_rows;
} else {
foreach ((array) $_POST["check"] as $val) {
// where is not unique so OR can't be used
$result = queries($command . limit1($query, "\nWHERE " . where_check($val, $fields)));
$result = queries($command . limit1($query, "\nWHERE " . ($where ? implode(" AND ", $where) . " AND " : "") . where_check($val, $fields)));
if (!$result) {
break;
}
@@ -142,6 +134,7 @@ if ($_POST && !$error) {
}
queries_redirect(remove_from_uri($_POST["all"] && $_POST["delete"] ? "page" : ""), $message, $result);
//! display edit page in case of an error
} elseif (!$_POST["import"]) { // modify
if (!$_POST["val"]) {
$error = lang('Ctrl+click on a value to modify it.');
@@ -164,6 +157,7 @@ if ($_POST && !$error) {
}
queries_redirect(remove_from_uri(), lang('%d item(s) have been affected.', $affected), $result);
}
} elseif (is_string($file = get_file("csv_file", true))) {
//! character set
cookie("adminer_import", "output=" . urlencode($adminer_import["output"]) . "&format=" . urlencode($_POST["separator"]));
@@ -195,6 +189,7 @@ if ($_POST && !$error) {
}
queries_redirect(remove_from_uri("page"), lang('%d row(s) have been imported.', $affected), $result);
queries("ROLLBACK"); // after queries_redirect() to not overwrite error
} else {
$error = upload_error($file);
}
@@ -316,6 +311,7 @@ if (!$columns) {
next($select);
}
}
$lengths = array();
if ($_GET["modify"]) {
foreach ($rows as $row) {
@@ -324,15 +320,26 @@ if (!$columns) {
}
}
}
echo ($backward_keys ? "<th>" . lang('Relations') : "") . "</thead>\n";
if (is_ajax()) {
if ($limit % 2 == 1 && $page % 2 == 1) {
odd();
}
ob_end_clean();
}
foreach ($adminer->rowDescriptions($rows, $foreign_keys) as $n => $row) {
$unique_array = unique_array($rows[$n], $indexes);
if (!$unique_array) {
$unique_array = array();
foreach ($rows[$n] as $key => $val) {
if (!preg_match('~^(COUNT\\((\\*|(DISTINCT )?`(?:[^`]|``)+`)\\)|(AVG|GROUP_CONCAT|MAX|MIN|SUM)\\(`(?:[^`]|``)+`\\))$~', $key)) { //! columns looking like functions
$unique_array[$key] = $val;
}
}
}
$unique_idf = "";
foreach ($unique_array as $key => $val) {
if (strlen($val) > 64) {
@@ -342,12 +349,14 @@ if (!$columns) {
$unique_idf .= "&" . ($val !== null ? urlencode("where[" . bracket_escape($key) . "]") . "=" . urlencode($val) : "null%5B%5D=" . urlencode($key));
}
echo "<tr" . odd() . ">" . (!$group && $select ? "" : "<td>" . checkbox("check[]", substr($unique_idf, 1), in_array(substr($unique_idf, 1), (array) $_POST["check"]), "", "this.form['all'].checked = false; formUncheck('all-page');") . ($is_group || information_schema(DB) ? "" : " <a href='" . h(ME . "edit=" . urlencode($TABLE) . $unique_idf) . "'>" . lang('edit') . "</a>"));
foreach ($row as $key => $val) {
if (isset($names[$key])) {
$field = $fields[$key];
if ($val != "" && (!isset($email_fields[$key]) || $email_fields[$key] != "")) {
$email_fields[$key] = (is_mail($val) ? $names[$key] : ""); //! filled e-mails can be contained on other pages
}
$link = "";
$val = $adminer->editVal($val, $field);
if ($val !== null) {
@@ -376,6 +385,7 @@ if (!$columns) {
}
}
}
if ($key == "COUNT(*)") { //! columns looking like functions
$link = ME . "select=" . urlencode($TABLE);
$i = 0;
@@ -388,7 +398,9 @@ if (!$columns) {
$link .= where_link($i++, $k, $v);
}
}
}
if (!$link && ($link = $adminer->selectLink($row[$key], $field)) === null) {
if (is_mail($row[$key])) {
$link = "mailto:$row[$key]";
@@ -400,6 +412,7 @@ if (!$columns) {
);
}
}
$id = h("val[$unique_idf][" . bracket_escape($key) . "]");
$value = $_POST["val"][$unique_idf][bracket_escape($key)];
$h_value = h($value !== null ? $value : $row[$key]);
@@ -412,12 +425,14 @@ if (!$columns) {
);
}
}
if ($backward_keys) {
echo "<td>";
}
$adminer->backwardKeysPrint($backward_keys, $rows[$n]);
echo "</tr>\n"; // close to allow white-space: pre
}
if (is_ajax()) {
exit;
}
@@ -436,6 +451,7 @@ if (!$columns) {
$exact_count = false;
}
}
if (+$limit && ($found_rows === false || $found_rows > $limit || $page)) {
echo "<p class='pages'>";
// display first, previous 4, next 4 and last page
@@ -457,6 +473,7 @@ if (!$columns) {
}
echo (($found_rows === false ? count($rows) + 1 : $found_rows - $page * $limit) > $limit ? ' <a href="' . h(remove_from_uri("page") . "&page=" . ($page + 1)) . '" onclick="return !selectLoadMore(this, ' . (+$limit) . ', \'' . lang('Loading') . '\');">' . lang('Load more data') . '</a>' : '');
}
echo "<p>\n";
echo ($found_rows !== false ? "(" . ($exact_count ? "" : "~ ") . lang('%d row(s)', $found_rows) . ") " : "");
echo checkbox("all", 1, 0, lang('whole result')) . "\n";
@@ -471,7 +488,14 @@ if (!$columns) {
</div></fieldset>
<?php
}
$format = $adminer->dumpFormat();
foreach ((array) $_GET["columns"] as $column) {
if ($column["fun"]) {
unset($format['sql']);
break;
}
}
if ($format) {
print_fieldset("export", lang('Export'));
$output = $adminer->dumpOutput();
@@ -481,6 +505,7 @@ if (!$columns) {
echo "</div></fieldset>\n";
}
}
if ($adminer->selectImportPrint()) {
print_fieldset("import", lang('Import'), !$rows);
echo "<input type='file' name='csv_file'> ";

View File

@@ -1,9 +1,10 @@
<?php
$SEQUENCE = $_GET["sequence"];
$row = $_POST;
if ($_POST && !$error) {
$link = substr(ME, 0, -1);
$name = trim($_POST["name"]);
$name = trim($row["name"]);
if ($_POST["drop"]) {
query_redirect("DROP SEQUENCE " . idf_escape($SEQUENCE), $link, lang('Sequence has been dropped.'));
} elseif ($SEQUENCE == "") {
@@ -17,9 +18,8 @@ if ($_POST && !$error) {
page_header($SEQUENCE != "" ? lang('Alter sequence') . ": " . h($SEQUENCE) : lang('Create sequence'), $error);
$row = $_POST;
if (!$row) {
$row = array("name" => $SEQUENCE);
$row["name"] = $SEQUENCE;
}
?>

View File

@@ -20,18 +20,20 @@ if (!$error && $_POST) {
$fp = false;
$query = $_POST["query"];
if ($_POST["webfile"]) {
$fp = @fopen((file_exists("adminer.sql") ? "adminer.sql"
: (file_exists("adminer.sql.gz") ? "compress.zlib://adminer.sql.gz"
: "compress.bzip2://adminer.sql.bz2"
)), "rb");
$fp = @fopen((file_exists("adminer.sql")
? "adminer.sql"
: "compress.zlib://adminer.sql.gz"
), "rb");
$query = ($fp ? fread($fp, 1e6) : false);
} elseif ($_FILES && $_FILES["sql_file"]["error"] != UPLOAD_ERR_NO_FILE) {
} elseif ($_FILES && $_FILES["sql_file"]["error"][0] != 4) { // 4 - UPLOAD_ERR_NO_FILE
$query = get_file("sql_file", true);
}
if (is_string($query)) { // get_file() returns error as number, fread() as false
if (function_exists('memory_get_usage')) {
@ini_set("memory_limit", max(ini_bytes("memory_limit"), 2 * strlen($query) + memory_get_usage() + 8e6)); // @ - may be disabled, 2 - substr and trim, 8e6 - other variables
}
if ($query != "" && strlen($query) < 1e6) { // don't add big queries
$q = $query . (ereg(";[ \t\r\n]*\$", $query) ? "" : ";"); //! doesn't work with DELIMITER |
if (!$history || reset(end($history)) != $q) { // no repeated queries
@@ -41,6 +43,7 @@ if (!$error && $_POST) {
stop_session();
}
}
$space = "(?:\\s|/\\*.*\\*/|(?:#|-- )[^\n]*\n|--\n)";
$delimiter = ";";
$offset = 0;
@@ -57,6 +60,7 @@ if (!$error && $_POST) {
parse_str($_COOKIE["adminer_export"], $adminer_export);
$dump_format = $adminer->dumpFormat();
unset($dump_format["sql"]);
while ($query != "") {
if (!$offset && preg_match("~^$space*DELIMITER\\s+(\\S+)~i", $query, $match)) {
$delimiter = $match[1];
@@ -71,6 +75,7 @@ if (!$error && $_POST) {
break;
}
$offset = $pos + strlen($found);
if ($found && rtrim($found) != $delimiter) { // find matching quote or comment end
while (preg_match('(' . ($found == '/*' ? '\\*/' : ($found == '[' ? ']' : (ereg('^-- |^#', $found) ? "\n" : preg_quote($found) . "|\\\\."))) . '|$)s', $query, $match, PREG_OFFSET_CAPTURE, $offset)) { //! respect sql_mode NO_BACKSLASH_ESCAPES
$s = $match[0][0];
@@ -83,6 +88,7 @@ if (!$error && $_POST) {
}
}
}
} else { // end of a query
$empty = false;
$q = substr($query, 0, $pos);
@@ -98,10 +104,14 @@ if (!$error && $_POST) {
if ($connection->multi_query($q) && is_object($connection2) && preg_match("~^$space*USE\\b~isU", $q)) {
$connection2->query($q);
}
do {
$result = $connection->store_result();
$end = microtime();
$time = format_time($start, $end) . (strlen($q) < 1000 ? " <a href='" . h(ME) . "sql=" . urlencode(trim($q)) . "'>" . lang('Edit') . "</a>" : ""); // 1000 - maximum length of encoded URL in IE is 2083 characters
$time = " <span class='time'>(" . format_time($start, $end) . ")</span>"
. (strlen($q) < 1000 ? " <a href='" . h(ME) . "sql=" . urlencode(trim($q)) . "'>" . lang('Edit') . "</a>" : "") // 1000 - maximum length of encoded URL in IE is 2083 characters
;
if ($connection->error) {
echo ($_POST["only_errors"] ? $print : "");
echo "<p class='error'>" . lang('Error in query') . ($connection->errno ? " ($connection->errno)" : "") . ": " . error() . "\n";
@@ -109,6 +119,7 @@ if (!$error && $_POST) {
if ($_POST["error_stops"]) {
break 2;
}
} elseif (is_object($result)) {
$orgtables = select($result, $connection2);
if (!$_POST["only_errors"]) {
@@ -132,6 +143,7 @@ if (!$error && $_POST) {
}
echo "</form>\n";
}
} else {
if (preg_match("~^$space*(CREATE|DROP|ALTER)$space+(DATABASE|SCHEMA)\\b~isU", $q)) {
restart_session();
@@ -142,23 +154,29 @@ if (!$error && $_POST) {
echo "<p class='message' title='" . h($connection->info) . "'>" . lang('Query executed OK, %d row(s) affected.', $connection->affected_rows) . "$time\n";
}
}
$start = $end;
} while ($connection->next_result());
$line += substr_count($q.$found, "\n");
$query = substr($query, $offset);
$offset = 0;
}
}
}
}
if ($empty) {
echo "<p class='message'>" . lang('No commands to execute.') . "\n";
} elseif ($_POST["only_errors"]) {
echo "<p class='message'>" . lang('%d query(s) executed OK.', $commands - count($errors)) . format_time($total_start, microtime()) . "\n";
echo "<p class='message'>" . lang('%d query(s) executed OK.', $commands - count($errors));
echo " <span class='time'>(" . format_time($total_start, microtime()) . ")</span>\n";
} elseif ($errors && $commands > 1) {
echo "<p class='error'>" . lang('Error in query') . ": " . implode("", $errors) . "\n";
}
//! MS SQL - SET SHOWPLAN_ALL OFF
} else {
echo "<p class='error'>" . upload_error($query) . "\n";
}
@@ -176,9 +194,12 @@ if ($_POST) {
$q = $history[$_GET["history"]][0];
}
textarea("query", $q, 20);
echo ($_POST ? "" : "<script type='text/javascript'>document.getElementsByTagName('textarea')[0].focus();</script>\n");
echo ($_POST ? "" : "<script type='text/javascript'>focus(document.getElementsByTagName('textarea')[0]);</script>\n");
echo "<p>" . (ini_bool("file_uploads")
? lang('File upload') . ': <input type="file" name="sql_file"' . ($_FILES && $_FILES["sql_file"]["error"] != 4 ? '' : ' onchange="this.form[\'only_errors\'].checked = true;"') . '> (&lt; ' . ini_get("upload_max_filesize") . 'B)' // ignore post_max_size because it is for all form fields together and bytes computing would be necessary
? lang('File upload') . ': <input type="file" name="sql_file[]" multiple'
. ($_FILES && $_FILES["sql_file"]["error"][0] != 4 ? '' : ' onchange="this.form[\'only_errors\'].checked = true;"') // 4 - UPLOAD_ERR_NO_FILE
. '> (&lt; ' . ini_get("upload_max_filesize") . 'B)' // ignore post_max_size because it is for all form fields together and bytes computing would be necessary
: lang('File uploads are disabled.')
);
@@ -190,13 +211,7 @@ echo checkbox("error_stops", 1, $_POST["error_stops"], lang('Stop on error')) .
echo checkbox("only_errors", 1, $_POST["only_errors"], lang('Show only errors')) . "\n";
print_fieldset("webfile", lang('From server'), $_POST["webfile"], "document.getElementById('form')['only_errors'].checked = true; ");
$compress = array();
foreach (array("gz" => "zlib", "bz2" => "bz2") as $key => $val) {
if (extension_loaded($val)) {
$compress[] = ".$key";
}
}
echo lang('Webserver file %s', "<code>adminer.sql" . ($compress ? "[" . implode("|", $compress) . "]" : "") . "</code>");
echo lang('Webserver file %s', "<code>adminer.sql" . (extension_loaded("zlib") ? "[.gz]" : "") . "</code>");
echo ' <input type="submit" name="webfile" value="' . lang('Run file') . '">';
echo "</div></fieldset>\n";

View File

@@ -21,6 +21,7 @@ code { background: #eee; }
tbody tr:hover td, tbody tr:hover th { background: #eee; }
pre { margin: 1em 0 0; }
input[type=image] { vertical-align: middle; }
input.default { background: #ddf; }
.version { color: #777; font-size: 67%; }
.js .hidden, .nojs .jsonly { display: none; }
.js .column { position: absolute; background: #ddf; padding: .3em 1ex .3em 0; margin-top: -.3em; }
@@ -70,6 +71,16 @@ input[type=image] { vertical-align: middle; }
.rtl #breadcrumb { left: auto; right: 21em; margin: 0 -18px 0 0; }
.rtl #lang, .rtl #menu { left: auto; right: 0; }
@media all and (max-device-width: 880px) {
.pages { left: auto; }
#menu { position: static; width: auto; }
#content { margin-left: 10px; }
#lang { position: static; border-top: 1px solid #999; }
#breadcrumb { left: auto; }
.rtl #content { margin-right: 10px; }
.rtl #breadcrumb { right: auto; }
}
@media print {
#lang, #menu { display: none; }
#content { margin-left: 1em; }

View File

@@ -291,7 +291,7 @@ function editingAddRow(button, focus) {
var match = /(\d+)(\.\d+)?/.exec(button.name);
var x = match[0] + (match[2] ? added.substr(match[2].length) : added) + '1';
var row = parentTag(button, 'tr');
var row2 = row.cloneNode(true);
var row2 = cloneNode(row);
var tags = row.getElementsByTagName('select');
var tags2 = row2.getElementsByTagName('select');
for (var i=0; i < tags.length; i++) {
@@ -363,7 +363,7 @@ function editingTypeChange(type) {
el.className = (/(char|text|enum|set)$/.test(text) ? '' : 'hidden');
}
if (el.name == name + '[unsigned]') {
el.className = (/(int|float|double|decimal)$/.test(text) ? '' : 'hidden');
el.className = (/((^|[^o])int|float|double|decimal)$/.test(text) ? '' : 'hidden');
}
if (el.name == name + '[on_update]') {
el.className = (text == 'timestamp' ? '' : 'hidden');
@@ -434,7 +434,7 @@ function partitionByChange(el) {
* @param HTMLInputElement
*/
function partitionNameChange(el) {
var row = parentTag(el, 'tr').cloneNode(true);
var row = cloneNode(parentTag(el, 'tr'));
row.firstChild.firstChild.value = '';
parentTag(el, 'table').appendChild(row);
el.onchange = function () {};
@@ -447,7 +447,7 @@ function partitionNameChange(el) {
*/
function foreignAddRow(field) {
field.onchange = function () { };
var row = parentTag(field, 'tr').cloneNode(true);
var row = cloneNode(parentTag(field, 'tr'));
var selects = row.getElementsByTagName('select');
for (var i=0; i < selects.length; i++) {
selects[i].name = selects[i].name.replace(/\]/, '1$&');
@@ -463,7 +463,7 @@ function foreignAddRow(field) {
*/
function indexesAddRow(field) {
field.onchange = function () { };
var row = parentTag(field, 'tr').cloneNode(true);
var row = cloneNode(parentTag(field, 'tr'));
var selects = row.getElementsByTagName('select');
for (var i=0; i < selects.length; i++) {
selects[i].name = selects[i].name.replace(/indexes\[\d+/, '$&1');
@@ -506,7 +506,7 @@ function indexesAddColumn(field, prefix) {
select.selectedIndex = 3;
select.onchange();
}
var column = field.parentNode.cloneNode(true);
var column = cloneNode(field.parentNode);
select = column.getElementsByTagName('select')[0];
select.name = select.name.replace(/\]\[\d+/, '$&1');
select.selectedIndex = 0;

View File

@@ -240,7 +240,7 @@ function selectAddRow(field) {
selectFieldChange(field.form);
};
field.onchange();
var row = field.parentNode.cloneNode(true);
var row = cloneNode(field.parentNode);
var selects = row.getElementsByTagName('select');
for (var i=0; i < selects.length; i++) {
selects[i].name = selects[i].name.replace(/[a-z]\[\d+/, '$&1');
@@ -258,7 +258,7 @@ function selectAddRow(field) {
/** Clear column name after resetting search
* @param HTMLInputElement
*/
function selectSearch(el) {
function selectSearchSearch(el) {
if (!el.value) {
el.parentNode.firstChild.selectedIndex = 0;
}
@@ -474,6 +474,7 @@ function selectClick(td, event, text, warning) {
}
td.innerHTML = '';
td.appendChild(input);
setupSubmitHighlight(td);
input.focus();
if (text == 2) { // long text
return ajax(location.href + '&' + encodeURIComponent(td.id) + '=', function (request) {
@@ -536,3 +537,88 @@ function eventStop(event) {
event.cancelBubble = true;
}
}
/** Setup highlighting of default submit button on form field focus
* @param HTMLElement
*/
function setupSubmitHighlight(parent) {
for (var key in { input: 1, select: 1, textarea: 1 }) {
var inputs = parent.getElementsByTagName(key);
for (var i = 0; i < inputs.length; i++) {
if (!/submit|image|file/.test(inputs[i].type)) {
addEvent(inputs[i], 'focus', inputFocus);
addEvent(inputs[i], 'blur', inputBlur);
}
}
}
}
/** Highlight default submit button
* @this HTMLInputElement
*/
function inputFocus() {
var submit = findDefaultSubmit(this.form);
if (submit) {
submit.className += ' default';
}
}
/** Unhighlight default submit button
* @this HTMLInputElement
*/
function inputBlur() {
var submit = findDefaultSubmit(this.form);
if (submit) {
submit.className = submit.className.replace(/ default( |$)/, '$1');
}
}
/** Find submit button used by Enter
* @param HTMLFormElement
* @return HTMLInputElement
*/
function findDefaultSubmit(form) {
var inputs = form.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
if (input.type == 'submit') {
return input;
}
}
}
/** Add event listener
* @param HTMLElement
* @param string without 'on'
* @param function
*/
function addEvent(el, action, handler) {
if (el.addEventListener) {
el.addEventListener(action, handler, false);
} else {
el.attachEvent('on' + action, handler);
}
}
/** Defer focusing element
* @param HTMLElement
*/
function focus(el) {
setTimeout(function () { // this has to be an anonymous function because Firefox passes some arguments to setTimeout callback
el.focus();
}, 0);
}
/** Clone node and setup submit highlighting
* @param HTMLElement
* @return HTMLElement
*/
function cloneNode(el) {
var el2 = el.cloneNode(true);
setupSubmitHighlight(el2);
return el2;
}

View File

@@ -4,9 +4,10 @@ $fields = fields($TABLE);
if (!$fields) {
$error = error();
}
$table_status = ($fields ? table_status($TABLE) : array());
$table_status = table_status($TABLE, true);
page_header(($fields && is_view($table_status) ? lang('View') : lang('Table')) . ": " . h($TABLE), $error);
$adminer->selectLinks($table_status);
$comment = $table_status["Comment"];
if ($comment != "") {
@@ -26,7 +27,7 @@ if ($fields) {
echo "</table>\n";
if (!is_view($table_status)) {
echo "<h3>" . lang('Indexes') . "</h3>\n";
echo "<h3 id='indexes'>" . lang('Indexes') . "</h3>\n";
$indexes = indexes($TABLE);
if ($indexes) {
echo "<table cellspacing='0'>\n";
@@ -43,7 +44,7 @@ if ($fields) {
echo '<p><a href="' . h(ME) . 'indexes=' . urlencode($TABLE) . '">' . lang('Alter indexes') . "</a>\n";
if (fk_support($table_status)) {
echo "<h3>" . lang('Foreign keys') . "</h3>\n";
echo "<h3 id='foreign-keys'>" . lang('Foreign keys') . "</h3>\n";
$foreign_keys = foreign_keys($TABLE);
if ($foreign_keys) {
echo "<table cellspacing='0'>\n";
@@ -68,7 +69,7 @@ if ($fields) {
}
if (support("trigger")) {
echo "<h3>" . lang('Triggers') . "</h3>\n";
echo "<h3 id='triggers'>" . lang('Triggers') . "</h3>\n";
$triggers = triggers($TABLE);
if ($triggers) {
echo "<table cellspacing='0'>\n";
@@ -79,5 +80,6 @@ if ($fields) {
}
echo '<p><a href="' . h(ME) . 'trigger=' . urlencode($TABLE) . '">' . lang('Add trigger') . "</a>\n";
}
}
}

View File

@@ -1,27 +1,36 @@
<?php
$TABLE = $_GET["trigger"];
$name = $_GET["name"];
$trigger_options = trigger_options();
$trigger_event = array("INSERT", "UPDATE", "DELETE");
$row = (array) trigger($_GET["name"]) + array("Trigger" => $TABLE . "_bi");
$row = (array) trigger($name) + array("Trigger" => $TABLE . "_bi");
if ($_POST) {
if (!$error && in_array($_POST["Timing"], $trigger_options["Timing"]) && in_array($_POST["Event"], $trigger_event) && in_array($_POST["Type"], $trigger_options["Type"])) {
// don't use drop_create() because there may not be more triggers for the same action
$on = " ON " . table($TABLE);
drop_create(
"DROP TRIGGER " . idf_escape($_GET["name"]) . ($jush == "pgsql" ? $on : ""),
create_trigger($on, $_POST),
create_trigger($on, $row + array("Type" => reset($trigger_options["Type"]))),
ME . "table=" . urlencode($TABLE),
lang('Trigger has been dropped.'),
lang('Trigger has been altered.'),
lang('Trigger has been created.'),
$_GET["name"]
);
$drop = "DROP TRIGGER " . idf_escape($name) . ($jush == "pgsql" ? $on : "");
$location = ME . "table=" . urlencode($TABLE);
if ($_POST["drop"]) {
query_redirect($drop, $location, lang('Trigger has been dropped.'));
} else {
if ($name != "") {
queries($drop);
}
queries_redirect(
$location,
($name != "" ? lang('Trigger has been altered.') : lang('Trigger has been created.')),
queries(create_trigger($on, $_POST))
);
if ($name != "") {
queries(create_trigger($on, $row + array("Type" => reset($trigger_options["Type"]))));
}
}
}
$row = $_POST;
}
page_header(($_GET["name"] != "" ? lang('Alter trigger') . ": " . h($_GET["name"]) : lang('Create trigger')), $error, array("table" => $TABLE));
page_header(($name != "" ? lang('Alter trigger') . ": " . h($name) : lang('Create trigger')), $error, array("table" => $TABLE));
?>
<form action="" method="post" id="form">
@@ -34,6 +43,6 @@ page_header(($_GET["name"] != "" ? lang('Alter trigger') . ": " . h($_GET["name"
<p><?php textarea("Statement", $row["Statement"]); ?>
<p>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php if ($_GET["name"] != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
<?php if ($name != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form>

View File

@@ -1,20 +1,20 @@
<?php
$TYPE = $_GET["type"];
$row = $_POST;
if ($_POST && !$error) {
$link = substr(ME, 0, -1);
if ($_POST["drop"]) {
query_redirect("DROP TYPE " . idf_escape($TYPE), $link, lang('Type has been dropped.'));
} else {
query_redirect("CREATE TYPE " . idf_escape(trim($_POST["name"])) . " $_POST[as]", $link, lang('Type has been created.'));
query_redirect("CREATE TYPE " . idf_escape(trim($row["name"])) . " $row[as]", $link, lang('Type has been created.'));
}
}
page_header($TYPE != "" ? lang('Alter type') . ": " . h($TYPE) : lang('Create type'), $error);
$row = $_POST;
if (!$row) {
$row = array("as" => "AS ");
$row["as"] = "AS ";
}
?>

View File

@@ -26,6 +26,7 @@ if ($_POST) {
}
$grants = array();
$old_pass = "";
if (isset($_GET["host"]) && ($result = $connection->query("SHOW GRANTS FOR " . q($USER) . "@" . q($_GET["host"])))) { //! use information_schema for MySQL 5 - column names in column privileges are not escaped
while ($row = $result->fetch_row()) {
if (preg_match('~GRANT (.*) ON (.*) TO ~', $row[0], $match) && preg_match_all('~ *([^(,]*[^ ,(])( *\\([^)]+\\))?~', $match[1], $matches, PREG_SET_ORDER)) { //! escape the part between ON and TO
@@ -56,6 +57,7 @@ if ($_POST && !$error) {
$pass = $connection->result("SELECT PASSWORD(" . q($pass) . ")");
$error = !$pass;
}
$created = false;
if (!$error) {
if ($old_user != $new_user) {
@@ -65,6 +67,7 @@ if ($_POST && !$error) {
queries("SET PASSWORD FOR $new_user = " . q($pass));
}
}
if (!$error) {
$revoke = array();
foreach ($new_grants as $object => $grant) {
@@ -90,6 +93,7 @@ if ($_POST && !$error) {
}
}
}
if (!$error && isset($_GET["host"])) {
if ($old_user != $new_user) {
queries("DROP USER $old_user");
@@ -101,7 +105,9 @@ if ($_POST && !$error) {
}
}
}
queries_redirect(ME . "privileges=", (isset($_GET["host"]) ? lang('User has been altered.') : lang('User has been created.')), !$error);
if ($created) {
// delete new user in case of an error
$connection->query("DROP USER $new_user");
@@ -120,7 +126,7 @@ if ($_POST) {
if ($old_pass != "") {
$row["hashed"] = true;
}
$grants[(DB == "" || $grants ? "" : idf_escape(addcslashes(DB, "%_"))) . ".*"] = array();
$grants[(DB == "" || $grants ? "" : idf_escape(addcslashes(DB, "%_\\"))) . ".*"] = array();
}
?>
@@ -143,6 +149,7 @@ foreach ($grants as $object => $grant) {
$i++;
}
echo "</thead>\n";
foreach (array(
"" => "",
"Server Admin" => lang('Server'),
@@ -168,6 +175,7 @@ foreach (array(
}
}
}
echo "</table>\n";
?>
<p>

View File

@@ -1,26 +1,39 @@
<?php
$TABLE = $_GET["view"];
$row = ($TABLE == "" ? array() : view($TABLE));
$row["name"] = $TABLE;
$row = $_POST;
if ($_POST) {
if (!$error) {
$name = trim($_POST["name"]);
if ($_POST && !$error) {
$name = trim($row["name"]);
$as = " AS\n$row[select]";
$location = ME . "table=" . urlencode($name);
$message = lang('View has been altered.');
if (!$_POST["drop"] && $TABLE == $name && $jush != "sqlite") {
query_redirect(($jush == "mssql" ? "ALTER" : "CREATE OR REPLACE") . " VIEW " . table($name) . $as, $location, $message);
} else {
$temp_name = $name . "_adminer_" . uniqid();
drop_create(
"DROP VIEW " . table($TABLE),
"CREATE VIEW " . table($name) . " AS\n$_POST[select]",
"CREATE VIEW " . table($TABLE) . " AS\n$row[select]",
($_POST["drop"] ? substr(ME, 0, -1) : ME . "table=" . urlencode($name)),
"CREATE VIEW " . table($name) . $as,
"DROP VIEW " . table($name),
"CREATE VIEW " . table($temp_name) . $as,
"DROP VIEW " . table($temp_name),
($_POST["drop"] ? substr(ME, 0, -1) : $location),
lang('View has been dropped.'),
lang('View has been altered.'),
$message,
lang('View has been created.'),
$TABLE
$TABLE,
$name
);
}
$row = $_POST;
}
page_header(($TABLE != "" ? lang('Alter view') : lang('Create view')), $error, array("table" => $TABLE), $TABLE);
if (!$_POST && $TABLE != "") {
$row = view($TABLE);
$row["name"] = $TABLE;
}
?>
<form action="" method="post">

View File

@@ -1,3 +1,28 @@
Adminer 3.7.0 (released 2013-05-19):
Allow more SQL files to be uploaded at the same time
Print run time next to executed queries
Don't drop original view and routine before creating the new one
Highlight default submit button
Add server placeholder to login form
Disable SQL export when applying functions in select
Allow using lang() in plugins (customization)
Remove bzip2 compression support
Constraint memory used in TAR export
Allow exporting views dependent on each other (bug #3459151)
Fix resetting search (bug #3612507)
Don't use LIMIT 1 if updating unique row (bug #3613109)
Restrict editing rows without unique identifier to search results
Display navigation bellow main content on mobile browsers
Get number of rows on export page asynchronously
MySQL: Optimize create table page and Editor navigation
MySQL: Display bit type as binary number
MySQL: Improve export of binary data types
MySQL: Fix handling of POINT data type (bug #3582578)
MySQL: Don't export binary and geometry columns twice in select
MySQL: Fix EXPLAIN in MySQL < 5.1, bug since Adminer 3.6.4
SQLite: Export views
PostgreSQL: Fix swapped NULL and NOT NULL columns in weird setups
Adminer 3.6.4 (released 2013-04-26):
Display pagination on a fixed position
Increase default select limit to 50

View File

@@ -42,6 +42,19 @@ function put_file($match) {
}
$return = file_get_contents(dirname(__FILE__) . "/$project/$match[2]");
if (basename($match[2]) != "lang.inc.php" || !$_SESSION["lang"]) {
if (basename($match[2]) == "lang.inc.php") {
$return = str_replace('function lang($idf, $number = null) {', 'function lang($idf, $number = null) {
if (is_string($idf)) { // compiled version uses numbers, string comes from a plugin
// English translation is closest to the original identifiers //! pluralized translations are not found
$pos = array_search($idf, get_translations("en")); //! this should be cached
if ($pos !== false) {
$idf = $pos;
}
}', $return, $count);
if (!$count) {
echo "lang() not found\n";
}
}
$tokens = token_get_all($return); // to find out the last token
return "?>\n$return" . (in_array($tokens[count($tokens) - 1][0], array(T_CLOSE_TAG, T_INLINE_HTML), true) ? "<?php" : "");
} elseif (preg_match('~\\s*(\\$pos = (.+\n).+;)~sU', $return, $match2)) {
@@ -50,16 +63,19 @@ function put_file($match) {
return '$_SESSION[lang]';
}
function lang(\$translation, \$number) {
\$pos = $match2[2]\t\t: " . (preg_match("~\\\$LANG == '$_SESSION[lang]'.* \\? (.+)\n~U", $match2[1], $match3) ? $match3[1] : "1") . '
);
$translation = str_replace("%d", "%s", $translation[$pos]);
function lang(\$translation, \$number = null) {
if (is_array(\$translation)) {
\$pos = $match2[2]\t\t\t: " . (preg_match("~\\\$LANG == '$_SESSION[lang]'.* \\? (.+)\n~U", $match2[1], $match3) ? $match3[1] : "1") . '
);
$translation = $translation[$pos];
}
$translation = str_replace("%d", "%s", $translation);
$number = number_format($number, 0, ".", lang(\',\'));
return sprintf($translation, $number);
}
';
} else {
echo "lang() not found\n";
echo "lang() \$pos not found\n";
}
}
@@ -123,13 +139,19 @@ if ($_SESSION["translations_version"] != ' . $translations_version . ') {
$translations = array();
$_SESSION["translations_version"] = ' . $translations_version . ';
}
if (!$translations) {
switch ($LANG) {' . $return . '
function get_translations($lang) {
switch ($lang) {' . $return . '
}
$translations = array();
foreach (explode("\n", lzw_decompress($compressed)) as $val) {
$translations[] = (strpos($val, "\t") ? explode("\t", $val) : $val);
}
return $translations;
}
if (!$translations) {
$translations = get_translations($LANG);
}
';
}

View File

@@ -217,10 +217,29 @@ table code {
#content:after {
clear: both;
content: ".";
content: "";
display: table;
}
#content > h2:before {
display: block;
height: 0;
overflow: hidden;
content: "";
color: #FF9;
font-size: 13px;
background: #333;
line-height: 40px;
margin: 0;
padding: 0 0 0 20px;
position: fixed;
top: 0;
left: 300px;
width: 100%;
height: 40px;
}
#content > #breadcrumb + h2:before {
display: none;
}
#content > p {
@@ -231,11 +250,11 @@ table code {
background: #333;
color: #FFF;
height: 40px;
left: 0;
line-height: 40px;
padding: 0 0 0 40px;
position: fixed;
top: 0;
left: 0;
width: 260px;
}
@@ -281,12 +300,12 @@ table code {
#breadcrumb {
background: #333;
color: #FFF;
left: 300px;
line-height: 40px;
margin: 0;
padding: 0 0 0 20px;
position: fixed;
top: 0;
left: 300px;
width: 100%;
height: 40px;
}
@@ -329,6 +348,12 @@ table code {
height: 100%;
}
#content > p.tabs + *:after {
display: table;
clear: both;
content: "";
}
/* icons */
@@ -367,44 +392,27 @@ select[name="db"] option {
}
#menu p a[href*="&select="] {
clear: left;
display: block;
float: left;
display: inline-block;
margin-right: 8px;
overflow: hidden;
padding-left: 0;
text-decoration: none;
width: 16px;
line-height: 16px;
height: 16px;
}
#menu p a[href*="&select="]:before {
content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHkm9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1zztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wGhGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUHYJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWluUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhNTWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7nHADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGFrwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=");
padding-right: 5px;
}
#menu p a[href*="&select="]:hover {
margin-left: -3px;
margin-top: -2px;
overflow: visible;
padding: 1px 2px;
position: absolute;
width: auto;
display: inline-block;
margin-top: 2px;
}
#menu p a[href*="&table="], #menu p a[href*="&view="] {
clear: right;
display: block;
min-height: 20px;
margin-left: 24px;
padding-bottom: 1px;
display: inline-block;
text-decoration: none;
}
#menu p br {
display: none;
}
a[href*="&create="] {
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ6SURBVDjLpZNZSNRRGMV//2XGsjFrMg2z0so2K21xIFpepYUiAsGIICLffI8eWiBBeg3qQV+KwBYKLB8qpHUmrahcKLc0QsxldNSxdPz/79LD1ChBUXTh8sG93POdc75zDa01/7NsgGvPR09rzQmpVZZSCqlAKIWUCqk0QqoZWyKFRir1uvxIbsAGUFqXHQqkpP1L57M3Pm5MMJBKpQHUdF9BKIGQAlcJXOlOVykSdye3leO6MmkGQNyHw+uO/1X3bzGBK+S0B1IqAKqDg3986HeCZPffwvJtoNT7lOZLvUdtAPEDAKBkRzo3QwMUb89InN1uGGD3spdE214xe8MRUnM2MfppNW0Pqy7YAK5UKK2xLbhdP4hlmdxpGMQwwQT8ziNiI534c7cT6WrFazikzF2Eb8HS1IQEDdiWwcHAQmpehTkQSAcgNvSMiYFW5uUUMdV3HW+ywefGNqITJsbUUL75k4FWYJtQ+yaMZcXrk1ANk/33mbdiD7EvlRieETy+FJLkMFcjRRSW3emIAwiF1hqPBfu2LGSWbbA1uZ41SfWkrtxPrPcypsfFiWYzFGzGKTjFV28WEJeIUHETLdOgrmkI1VdHpCdEet5enP4qLK9mKrqMgedv6cyrAP+qxOTiUxAi7oEJi8frELoFoTLpa7nI/HQvscgSRt+0kV1SSW7qYtp7xrBMphm4Mi5h/VIfTcEq1u0oJaknSEdNiMYHET7UvcMpPEN31Ed7zxgASmk1I0g6dK66s8CRak5mVxjnfS05+TsZCw/T9baTx1nnGb47DrQksjE6HrsHYPz6nYt3+Sc3L8+wA2tz0J6pF5OD4WP7Kpq7f5fO79DfSxjdtCtDAAAAAElFTkSuQmCC") no-repeat scroll 2px center;
padding-left: 22px;
@@ -537,7 +545,7 @@ input[name="delete"]:hover, input[name="drop"]:hover {
color: red;
}
input[name="logout"] {
#logout {
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJHSURBVDjLlZPNi81hFMc/z7137p1mTCFvNZfGSzLIWNjZKRvFRoqNhRCSYm8xS3+AxRRZ2JAFJWJHSQqTQkbEzYwIM+6Yid/znJfH4prLXShOnb6r8/nWOd8Tcs78bz0/f+KMu50y05nK/wy+uHDylbutqS5extvGcxaWqtoGDA8PZ3dnrs2srQc2Zko41UXLmLdyDW5OfvsUkUgbYGbU63UAQggdmvMzFmzZCgTi7CQmkZwdEaX0JwDgTnGbTCaE0G4zw80omhPI92lcEtkNkdgJCCHwJX7mZvNaB0A14SaYJlwTrpHsTkoFlV1nt2c3x5YYo1/vM9A/gKpxdfwyu/v3teCayKq4JEwT5EB2R6WgYmrs2bYbcUNNUVfEhIfFYy69uci+1fuRX84mkawFSxd/4nVWUopUVIykwlQxRTJBTIDA4Pp1jBZPuNW4wUAPmCqWIn29X1k4f5Ku8g9mpKCkakRLVEs1auVuauVuyqHMo8ejNCe+sWPVTkQKXCMmkeZUmUZjETF1tc6ooly+fgUVw9So1/tRN6YnZji46QghBFKKuAouERNhMlbAHZFE6e7pB+He8MMw+GGI4xtOMf1+lsl3TQ4NHf19BSlaO1DB9BfMHdX0O0iqSgiBbJkjm491hClJbA1LxCURgpPzXwAHhg63necAIi3XngXLcRU0fof8ETMljIyM5LGxMcbHxzvy/6fuXdWgt6+PWncv1e4euqo1ZmabvHs5+jn8yzufO7hiiZmuNpNBM13rbvVSpbrXJE7/BMkHtU9jFIC/AAAAAElFTkSuQmCC") no-repeat scroll left center;
border: none;
cursor: pointer;

View File

@@ -9,6 +9,7 @@ if ($adminer->homepage()) {
}
echo "<table cellspacing='0' class='nowrap checkable' onclick='tableClick(event);'>\n";
echo '<thead><tr class="wrap"><td><input id="check-all" type="checkbox" onclick="formCheck(this, /^tables\[/);"><th>' . lang('Table') . '<td>' . lang('Rows') . "</thead>\n";
foreach (table_status() as $table => $row) {
$name = $adminer->tableName($row);
if (isset($row["Engine"]) && $name != "") {
@@ -18,6 +19,7 @@ if ($adminer->homepage()) {
echo "<td align='right'><a href='" . h(ME . "edit=") . urlencode($table) . "'>" . ($row["Engine"] == "InnoDB" && $val ? "~ $val" : $val) . "</a>";
}
}
echo "</table>\n";
echo "<script type='text/javascript'>tableCheck();</script>\n";
echo "</form>\n";

View File

@@ -49,7 +49,7 @@ class Adminer {
<tr><th><?php echo lang('Password'); ?><td><input type="password" name="auth[password]">
</table>
<script type="text/javascript">
document.getElementById('username').focus();
focus(document.getElementById('username'));
</script>
<?php
echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
@@ -92,7 +92,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
$return[$row["TABLE_NAME"]]["keys"][$row["CONSTRAINT_NAME"]][$row["COLUMN_NAME"]] = $row["REFERENCED_COLUMN_NAME"];
}
foreach ($return as $key => $val) {
$name = $this->tableName(table_status($key));
$name = $this->tableName(table_status($key, true));
if ($name != "") {
$search = preg_quote($tableName);
$separator = "(:|\\s*-)?\\s+";
@@ -234,7 +234,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
if (($val["col"] == "" || $columns[$val["col"]]) && "$val[col]$val[val]" != "") {
echo "<div><select name='where[$i][col]'><option value=''>(" . lang('anywhere') . ")" . optionlist($columns, $val["col"], true) . "</select>";
echo html_select("where[$i][op]", array(-1 => "") + $this->operators, $val["op"]);
echo "<input type='search' name='where[$i][val]' value='" . h($val["val"]) . "' onsearch='selectSearch(this);'></div>\n";
echo "<input type='search' name='where[$i][val]' value='" . h($val["val"]) . "' onsearch='selectSearchSearch(this);'></div>\n";
$i++;
}
}
@@ -562,7 +562,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
<?php
$this->databasesPrint($missing);
if ($missing != "db" && $missing != "ns") {
$table_status = table_status();
$table_status = table_status('', true);
if (!$table_status) {
echo "<p class='message'>" . lang('No tables.') . "\n";
} else {

View File

@@ -13,6 +13,7 @@ $drivers[DRIVER] = lang('Login');
if (isset($_GET["select"]) && ($_POST["edit"] || $_POST["clone"]) && !$_POST["save"]) {
$_GET["edit"] = $_GET["select"];
}
if (isset($_GET["download"])) {
include "../adminer/download.inc.php";
} elseif (isset($_GET["edit"])) {

View File

@@ -9,7 +9,7 @@
class AdminerMasterSlave {
private $masters = array();
/**
/**
* @param array ($slave => $master)
*/
function AdminerMasterSlave($masters) {

View File

@@ -4,7 +4,6 @@ Variables editation
Blob download and image display in edit form (important for Editor with hidden fields in select and SQL command)
Add title to Logout, edit (in select) and select (in menu) for style "hever"
Export by GET parameters
Only first part of big BZ2 export is readable, files are missing in TAR
Draggable columns in alter table (thanks to Michal Manak)
<option class> for system databases and schemas - information_schema and driver-specific (thanks to Vaclav Novotny)
Define foreign keys name - http://forum.zdrojak.root.cz/index.php?topic=185.msg1255#msg1255