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

Compare commits

...

92 Commits

Author SHA1 Message Date
Jakub Vrana
ba1bb263b3 Release 3.7.1 2013-06-29 08:26:37 -07:00
Jakub Vrana
82a63f335b SQLite: Load information about descending indexes 2013-06-25 15:28:57 -07:00
Jakub Vrana
50d2054e36 PostgreSQL: Properly mark ascending index columns 2013-06-25 15:01:38 -07:00
Jakub Vrana
13f34d1ea9 Highlight table being altered in navigation 2013-06-25 10:12:10 -07:00
Jakub Vrana
2cf2021995 Open schema to new tab on Ctrl+click 2013-06-25 09:58:08 -07:00
Jakub Vrana
5f370927f1 Descending indexes 2013-06-25 09:42:47 -07:00
Jakub Vrana
c8248bb19c Allow changing PostgreSQL indexes with same name 2013-06-24 17:54:04 -07:00
Jakub Vrana
3a8191b7ac SQLite: Preselect index type after adding a column 2013-06-24 10:04:59 -07:00
Jakub Vrana
7dd454f0b4 Allow changing SQLite indexes with same name 2013-06-24 10:04:07 -07:00
Jakub Vrana
e51640eb98 Display error on invalid alter table and view pages 2013-06-24 09:08:26 -07:00
Jakub Vrana
2e32bf1f97 Suggest using adminer.sql 2013-06-24 06:12:13 -07:00
Jakub Vrana
27c7a218bd Save bytes 2013-06-24 05:53:48 -07:00
Jakub Vrana
2e4a7121a9 Fix title and links on invalid table pages 2013-06-24 05:53:23 -07:00
Jakub Vrana
81e134f872 Send 404 for invalid database and schema 2013-06-24 05:43:13 -07:00
Jakub Vrana
e680d22023 Avoid fatal in PostgreSQL without implemented database()
https://sourceforge.net/p/adminer/discussion/1095138/thread/5e29e380/
2013-06-13 07:46:12 +02:00
Jakub Vrana
aae2289095 Simplify translation 2013-06-11 14:56:54 +02:00
Jakub Vrana
4660ff852c Suggest that Import is available in SQL command 2013-06-11 11:03:17 +02:00
Jakub Vrana
f29a7cb140 Notify user about expired master password for permanent login 2013-06-11 11:02:17 +02:00
Jakub Vrana
64297aea60 Add design from https://gist.github.com/pappu687/5589922 2013-06-05 18:45:33 -07:00
Jakub Vrana
41cde565d5 Fix tests 2013-06-05 18:44:06 -07:00
Jakub Vrana
e80eb058e9 Support &null[]=F(c) 2013-06-04 19:42:46 -07:00
Jakub Vrana
7dd90f56f1 MySQL: Speed up updating rows without numeric or UTF-8 primary key 2013-06-04 19:40:17 -07:00
Jakub Vrana
8e0ead4678 Verify UTF-8 encoding of CSV import 2013-06-03 14:57:26 -07:00
Jakub Vrana
c05e332ca3 Sort languages 2013-06-03 10:00:16 -07:00
Jakub Vrana
717f4535a9 Fix Korean date format and hint 2013-06-03 09:46:55 -07:00
Jakub Vrana
d100a1ed9a Fix Korean translation identifiers 2013-06-03 09:24:30 -07:00
dalli
21756c492a Add Korean translation 2013-06-03 09:23:58 -07:00
Jakub Vrana
26ad18bab2 Avoid duplicate values of HTML id attributes (bug #3614245)
Unsupports <label> in IE6.
2013-06-03 08:56:18 -07:00
Jakub Vrana
e04be3a996 Handle timestamp PostgreSQL types (bug #3614086) 2013-05-29 17:24:27 -07:00
Jakub Vrana
0869ff02c6 Stricter check 2013-05-28 11:23:48 -07:00
Jakub Vrana
1dc9044ff4 Order table list by name (bug #3613974) 2013-05-28 11:14:15 -07:00
Jakub Vrana
5eb3eaa06e Add Bzip2 export plugin 2013-05-28 10:28:47 -07:00
Jakub Vrana
55c494b767 Don't use LIMIT 1 if inline updating unique row 2013-05-24 13:38:54 -07:00
Jakub Vrana
005c963e2d Fix detecting oid column in PDO_PGSQL 2013-05-23 21:05:45 -07:00
Jakub Vrana
2c381345b4 Use variable instead of literal value 2013-05-23 18:31:48 -07:00
Jakub Vrana
15e698d302 Order PostgreSQL table list by name 2013-05-23 09:22:12 -07:00
Jakub Vrana
7be9d5c7ca Simplify box-shadow 2013-05-20 10:58:06 -07:00
Jakub Vrana
2dfe2640db Don't highlight rows in uncheckable tables 2013-05-20 10:14:04 -07:00
Jakub Vrana
68aba96c72 Increase click target for checkboxes (thanks to Roman) 2013-05-20 10:13:54 -07:00
Jakub Vrana
bf94b88503 Use shadow for highlighting default button (thanks to srigi) 2013-05-20 09:13:06 -07:00
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
62 changed files with 1734 additions and 600 deletions

View File

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

View File

@@ -9,16 +9,22 @@ foreach ($referencable_primary as $table_name => $field) {
} }
$orig_fields = array(); $orig_fields = array();
$orig_status = array(); $table_status = array();
if ($TABLE != "") { if ($TABLE != "") {
$orig_fields = fields($TABLE); $orig_fields = fields($TABLE);
$orig_status = table_status($TABLE); $table_status = table_status($TABLE);
} if (!$table_status) {
if ($_POST && !$_POST["fields"]) { $error = lang('No tables.');
$_POST["fields"] = array(); }
} }
if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"] && !$_POST["down"]) { $row = $_POST;
$row["fields"] = (array) $row["fields"];
if ($row["auto_increment_col"]) {
$row["fields"][$row["auto_increment_col"]]["auto_increment"] = true;
}
if ($_POST && !process_fields($row["fields"]) && !$error) {
if ($_POST["drop"]) { if ($_POST["drop"]) {
query_redirect("DROP TABLE " . table($TABLE), substr(ME, 0, -1), lang('Table has been dropped.')); query_redirect("DROP TABLE " . table($TABLE), substr(ME, 0, -1), lang('Table has been dropped.'));
} else { } else {
@@ -26,17 +32,18 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
$all_fields = array(); $all_fields = array();
$use_all_fields = false; $use_all_fields = false;
$foreign = array(); $foreign = array();
ksort($_POST["fields"]); ksort($row["fields"]);
$orig_field = reset($orig_fields); $orig_field = reset($orig_fields);
$after = " FIRST"; $after = " FIRST";
foreach ($_POST["fields"] as $key => $field) {
foreach ($row["fields"] as $key => $field) {
$foreign_key = $foreign_keys[$field["type"]]; $foreign_key = $foreign_keys[$field["type"]];
$type_field = ($foreign_key !== null ? $referencable_primary[$foreign_key] : $field); //! can collide with user defined type $type_field = ($foreign_key !== null ? $referencable_primary[$foreign_key] : $field); //! can collide with user defined type
if ($field["field"] != "") { if ($field["field"] != "") {
if (!$field["has_default"]) { if (!$field["has_default"]) {
$field["default"] = null; $field["default"] = null;
} }
if ($key == $_POST["auto_increment_col"]) { if ($key == $row["auto_increment_col"]) {
$field["auto_increment"] = true; $field["auto_increment"] = true;
} }
$process_field = process_field($field, $type_field); $process_field = process_field($field, $type_field);
@@ -62,37 +69,40 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
} }
} }
} }
$partitioning = ""; $partitioning = "";
if (in_array($_POST["partition_by"], $partition_by)) { if (in_array($row["partition_by"], $partition_by)) {
$partitions = array(); $partitions = array();
if ($_POST["partition_by"] == 'RANGE' || $_POST["partition_by"] == 'LIST') { if ($row["partition_by"] == 'RANGE' || $row["partition_by"] == 'LIST') {
foreach (array_filter($_POST["partition_names"]) as $key => $val) { foreach (array_filter($row["partition_names"]) as $key => $val) {
$value = $_POST["partition_values"][$key]; $value = $row["partition_values"][$key];
$partitions[] = "\nPARTITION " . idf_escape($val) . " VALUES " . ($_POST["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection $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)" ? " (" . implode(",", $partitions) . "\n)"
: ($_POST["partitions"] ? " PARTITIONS " . (+$_POST["partitions"]) : "") : ($row["partitions"] ? " PARTITIONS " . (+$row["partitions"]) : "")
); );
} elseif (support("partitioning") && ereg("partitioned", $orig_status["Create_options"])) { } elseif (support("partitioning") && ereg("partitioned", $table_status["Create_options"])) {
$partitioning .= "\nREMOVE PARTITIONING"; $partitioning .= "\nREMOVE PARTITIONING";
} }
$message = lang('Table has been altered.'); $message = lang('Table has been altered.');
if ($TABLE == "") { if ($TABLE == "") {
cookie("adminer_engine", $_POST["Engine"]); cookie("adminer_engine", $row["Engine"]);
$message = lang('Table has been created.'); $message = lang('Table has been created.');
} }
$name = trim($_POST["name"]); $name = trim($row["name"]);
queries_redirect(ME . "table=" . urlencode($name), $message, alter_table( queries_redirect(ME . "table=" . urlencode($name), $message, alter_table(
$TABLE, $TABLE,
$name, $name,
($jush == "sqlite" && ($use_all_fields || $foreign) ? $all_fields : $fields), ($jush == "sqlite" && ($use_all_fields || $foreign) ? $all_fields : $fields),
$foreign, $foreign,
$_POST["Comment"], $row["Comment"],
($_POST["Engine"] && $_POST["Engine"] != $orig_status["Engine"] ? $_POST["Engine"] : ""), ($row["Engine"] && $row["Engine"] != $table_status["Engine"] ? $row["Engine"] : ""),
($_POST["Collation"] && $_POST["Collation"] != $orig_status["Collation"] ? $_POST["Collation"] : ""), ($row["Collation"] && $row["Collation"] != $table_status["Collation"] ? $row["Collation"] : ""),
($_POST["Auto_increment"] != "" ? +$_POST["Auto_increment"] : ""), ($row["Auto_increment"] != "" ? +$row["Auto_increment"] : ""),
$partitioning $partitioning
)); ));
} }
@@ -100,43 +110,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); page_header(($TABLE != "" ? lang('Alter table') : lang('Create table')), $error, array("table" => $TABLE), $TABLE);
$row = array( if (!$_POST) {
"Engine" => $_COOKIE["adminer_engine"], $row = array(
"fields" => array(array("field" => "", "type" => (isset($types["int"]) ? "int" : (isset($types["integer"]) ? "integer" : "")))), "Engine" => $_COOKIE["adminer_engine"],
"partition_names" => array(""), "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"]) { if ($TABLE != "") {
$row["fields"][$row["auto_increment_col"]]["auto_increment"] = true; $row = $table_status;
} $row["name"] = $TABLE;
process_fields($row["fields"]); $row["fields"] = array();
} elseif ($TABLE != "") { if (!$_GET["auto_increment"]) { // don't prefill by original Auto_increment for the sake of performance and not reusing deleted ids
$row = $orig_status; $row["Auto_increment"] = "";
$row["name"] = $TABLE; }
$row["fields"] = array(); foreach ($orig_fields as $field) {
if (!$_GET["auto_increment"]) { // don't prefill by original Auto_increment for the sake of performance and not reusing deleted ids $field["has_default"] = isset($field["default"]);
$row["Auto_increment"] = ""; $row["fields"][] = $field;
} }
foreach ($orig_fields as $field) {
$field["has_default"] = isset($field["default"]); if (support("partitioning")) {
$row["fields"][] = $field; $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");
if (support("partitioning")) { list($row["partition_by"], $row["partitions"], $row["partition"]) = $result->fetch_row();
$from = "FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = " . q(DB) . " AND TABLE_NAME = " . q($TABLE); $partitions = get_key_vals("SELECT PARTITION_NAME, PARTITION_DESCRIPTION $from AND PARTITION_NAME != '' ORDER BY PARTITION_ORDINAL_POSITION");
$result = $connection->query("SELECT PARTITION_METHOD, PARTITION_ORDINAL_POSITION, PARTITION_EXPRESSION $from ORDER BY PARTITION_ORDINAL_POSITION DESC LIMIT 1"); $partitions[""] = "";
list($row["partition_by"], $row["partitions"], $row["partition"]) = $result->fetch_row(); $row["partition_names"] = array_keys($partitions);
$row["partition_names"] = array(); $row["partition_values"] = array_values($partitions);
$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"];
} }
$row["partition_names"][] = "";
} }
} }
$collations = collations();
$collations = collations();
$engines = engines(); $engines = engines();
// case of engine may differ // case of engine may differ
foreach ($engines as $engine) { foreach ($engines as $engine) {
@@ -150,7 +155,7 @@ foreach ($engines as $engine) {
<form action="" method="post" id="form"> <form action="" method="post" id="form">
<p> <p>
<?php echo lang('Table name'); ?>: <input name="name" maxlength="64" value="<?php echo h($row["name"]); ?>" autocapitalize="off"> <?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 ($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"]) : ""); ?> <?php echo ($collations && !ereg("sqlite|mssql", $jush) ? html_select("Collation", array("" => "(" . lang('collation') . ")") + $collations, $row["Collation"]) : ""); ?>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
@@ -170,9 +175,13 @@ edit_fields($row["fields"], $collations, "TABLE", $foreign_keys, $comments);
</table> </table>
<p> <p>
<?php echo lang('Auto Increment'); ?>: <input type="number" name="Auto_increment" size="6" value="<?php echo h($row["Auto_increment"]); ?>"> <?php echo lang('Auto Increment'); ?>: <input type="number" name="Auto_increment" size="6" value="<?php echo h($row["Auto_increment"]); ?>">
<label class="jsonly"><input type="checkbox" id="defaults" name="defaults" value="1" checked onclick="columnShow(this.checked, 5);"><?php echo lang('Default values'); ?></label> <?php echo checkbox("defaults", 1, true, lang('Default values'), "columnShow(this.checked, 5)", "jsonly"); ?>
<?php if (!$_POST["defaults"]) { ?><script type="text/javascript">editingHideDefaults()</script><?php } ?> <?php if (!$_POST["defaults"]) { ?><script type="text/javascript">editingHideDefaults()</script><?php } ?>
<?php echo (support("comment") ? checkbox("comments", 1, $comments, lang('Comment'), "columnShow(this.checked, 6); toggle('Comment'); if (this.checked) this.form['Comment'].focus();", true) . ' <input name="Comment" id="Comment" value="' . h($row["Comment"]) . '" maxlength="' . ($connection->server_info >= 5.5 ? 2048 : 60) . '"' . ($comments ? '' : ' class="hidden"') . '>' : ''); ?> <?php echo (support("comment")
? "<label><input type='checkbox' name='comments' value='1' class='jsonly' onclick=\"columnShow(this.checked, 6); toggle('Comment'); if (this.checked) this.form['Comment'].focus();\"" . ($comments ? " checked" : "") . ">" . lang('Comment') . "</label>"
. ' <input name="Comment" id="Comment" value="' . h($row["Comment"]) . '" maxlength="' . ($connection->server_info >= 5.5 ? 2048 : 60) . '"' . ($comments ? '' : ' class="hidden"') . '>'
: '')
; ?>
<p> <p>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php if ($_GET["create"] != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?> <?php if ($_GET["create"] != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>

View File

@@ -1,7 +1,9 @@
<?php <?php
$row = $_POST;
if ($_POST && !$error && !isset($_POST["add_x"])) { // add is an image and PHP changes add.x to add_x if ($_POST && !$error && !isset($_POST["add_x"])) { // add is an image and PHP changes add.x to add_x
restart_session(); restart_session();
$name = trim($_POST["name"]); $name = trim($row["name"]);
if ($_POST["drop"]) { if ($_POST["drop"]) {
$_GET["db"] = ""; // to save in global history $_GET["db"] = ""; // to save in global history
queries_redirect(remove_from_uri("db|database"), lang('Database has been dropped.'), drop_databases(array(DB))); 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 // create or rename database
if (DB != "") { if (DB != "") {
$_GET["db"] = $name; $_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 { } else {
$databases = explode("\n", str_replace("\r", "", $name)); $databases = explode("\n", str_replace("\r", "", $name));
$success = true; $success = true;
$last = ""; $last = "";
foreach ($databases as $db) { foreach ($databases as $db) {
if (count($databases) == 1 || $db != "") { // ignore empty lines but always try to create single database 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; $success = false;
} }
$last = $db; $last = $db;
@@ -26,10 +28,10 @@ if ($_POST && !$error && !isset($_POST["add_x"])) { // add is an image and PHP c
} }
} else { } else {
// alter database // alter database
if (!$_POST["collation"]) { if (!$row["collation"]) {
redirect(substr(ME, 0, -1)); 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(); $collations = collations();
$name = DB; $name = DB;
$collate = null;
if ($_POST) { if ($_POST) {
$name = $_POST["name"]; $name = $row["name"];
$collate = $_POST["collation"];
} elseif (DB != "") { } elseif (DB != "") {
$collate = db_collation(DB, $collations); $row["collation"] = db_collation(DB, $collations);
} elseif ($jush == "sql") { } elseif ($jush == "sql") {
// propose database name with limited privileges // propose database name with limited privileges
foreach (get_vals("SHOW GRANTS") as $grant) { foreach (get_vals("SHOW GRANTS") as $grant) {
@@ -60,9 +60,9 @@ if ($_POST) {
echo ($_POST["add_x"] || strpos($name, "\n") echo ($_POST["add_x"] || strpos($name, "\n")
? '<textarea id="name" name="name" rows="10" cols="40">' . h($name) . '</textarea><br>' ? '<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">' : '<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'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php <?php
if (DB != "") { 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"])) { 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 queries("SET foreign_key_checks = 0"); // allows to truncate or drop several tables at once
} }
if ($_POST["truncate"]) { if ($_POST["truncate"]) {
if ($_POST["tables"]) { if ($_POST["tables"]) {
$result = truncate_tables($_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>"; $message .= "<b>" . h($row["Table"]) . "</b>: " . h($row["Msg_text"]) . "<br>";
} }
} }
queries_redirect(substr(ME, 0, -1), $message, $result); 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 ($adminer->homepage()) {
if ($_GET["ns"] !== "") { 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(); $tables_list = tables_list();
if (!$tables_list) { if (!$tables_list) {
echo "<p class='message'>" . lang('No tables.') . "\n"; echo "<p class='message'>" . lang('No tables.') . "\n";
@@ -57,6 +59,7 @@ if ($adminer->homepage()) {
search_tables(); search_tables();
} }
echo "<table cellspacing='0' class='nowrap checkable' onclick='tableClick(event);' ondblclick='tableClick(event, true);'>\n"; 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 '<thead><tr class="wrap"><td><input id="check-all" type="checkbox" onclick="formCheck(this, /^(tables|views)\[/);">';
echo '<th>' . lang('Table'); echo '<th>' . lang('Table');
echo '<td>' . lang('Engine'); echo '<td>' . lang('Engine');
@@ -68,6 +71,7 @@ if ($adminer->homepage()) {
echo '<td>' . lang('Rows'); echo '<td>' . lang('Rows');
echo (support("comment") ? '<td>' . lang('Comment') : ''); echo (support("comment") ? '<td>' . lang('Comment') : '');
echo "</thead>\n"; echo "</thead>\n";
foreach ($tables_list as $name => $type) { foreach ($tables_list as $name => $type) {
$view = ($type !== null && !eregi("table", $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');"); 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 (support("comment") ? "<td id='Comment-" . h($name) . "'>&nbsp;" : "");
} }
echo "<tr><td>&nbsp;<th>" . lang('%d in total', count($tables_list)); 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($jush == "sql" ? $connection->result("SELECT @@storage_engine") : "");
echo "<td>" . nbsp(db_collation(DB, collations())); echo "<td>" . nbsp(db_collation(DB, collations()));
foreach (array("Data_length", "Index_length", "Data_free") as $key) { foreach (array("Data_length", "Index_length", "Data_free") as $key) {
echo "<td align='right' id='sum-$key'>&nbsp;"; echo "<td align='right' id='sum-$key'>&nbsp;";
} }
echo "</table>\n"; echo "</table>\n";
echo "<script type='text/javascript'>tableCheck();</script>\n"; echo "<script type='text/javascript'>tableCheck();</script>\n";
if (!information_schema(DB)) { if (!information_schema(DB)) {
@@ -123,7 +129,7 @@ if ($adminer->homepage()) {
} }
if (support("routine")) { if (support("routine")) {
echo "<h3>" . lang('Routines') . "</h3>\n"; echo "<h3 id='routines'>" . lang('Routines') . "</h3>\n";
$routines = routines(); $routines = routines();
if ($routines) { if ($routines) {
echo "<table cellspacing='0'>\n"; echo "<table cellspacing='0'>\n";
@@ -142,7 +148,7 @@ if ($adminer->homepage()) {
} }
if (support("sequence")) { 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()"); $sequences = get_vals("SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = current_schema()");
if ($sequences) { if ($sequences) {
echo "<table cellspacing='0'>\n"; echo "<table cellspacing='0'>\n";
@@ -157,7 +163,7 @@ if ($adminer->homepage()) {
} }
if (support("type")) { if (support("type")) {
echo "<h3>" . lang('User types') . "</h3>\n"; echo "<h3 id='user-types'>" . lang('User types') . "</h3>\n";
$user_types = types(); $user_types = types();
if ($user_types) { if ($user_types) {
echo "<table cellspacing='0'>\n"; echo "<table cellspacing='0'>\n";
@@ -172,7 +178,7 @@ if ($adminer->homepage()) {
} }
if (support("event")) { if (support("event")) {
echo "<h3>" . lang('Events') . "</h3>\n"; echo "<h3 id='events'>" . lang('Events') . "</h3>\n";
$rows = get_rows("SHOW EVENTS"); $rows = get_rows("SHOW EVENTS");
if ($rows) { if ($rows) {
echo "<table cellspacing='0'>\n"; echo "<table cellspacing='0'>\n";

View File

@@ -293,7 +293,7 @@ if (isset($_GET["mssql"])) {
function table_status($name = "") { function table_status($name = "") {
$return = array(); $return = array();
foreach (get_rows("SELECT name AS Name, type_desc AS Engine FROM sys.all_objects WHERE schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND type IN ('S', 'U', 'V')" . ($name != "" ? " AND name = " . q($name) : "")) as $row) { foreach (get_rows("SELECT name AS Name, type_desc AS Engine FROM sys.all_objects WHERE schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND type IN ('S', 'U', 'V') " . ($name != "" ? "AND name = " . q($name) : "ORDER BY name")) as $row) {
if ($name != "") { if ($name != "") {
return $row; return $row;
} }
@@ -340,15 +340,17 @@ WHERE o.schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND o.type IN ('S', 'U',
function indexes($table, $connection2 = null) { function indexes($table, $connection2 = null) {
$return = array(); $return = array();
// sp_statistics doesn't return information about primary key // sp_statistics doesn't return information about primary key
foreach (get_rows("SELECT i.name, key_ordinal, is_unique, is_primary_key, c.name AS column_name foreach (get_rows("SELECT i.name, key_ordinal, is_unique, is_primary_key, c.name AS column_name, is_descending_key
FROM sys.indexes i FROM sys.indexes i
INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
WHERE OBJECT_NAME(i.object_id) = " . q($table) WHERE OBJECT_NAME(i.object_id) = " . q($table)
, $connection2) as $row) { , $connection2) as $row) {
$return[$row["name"]]["type"] = ($row["is_primary_key"] ? "PRIMARY" : ($row["is_unique"] ? "UNIQUE" : "INDEX")); $name = $row["name"];
$return[$row["name"]]["lengths"] = array(); $return[$name]["type"] = ($row["is_primary_key"] ? "PRIMARY" : ($row["is_unique"] ? "UNIQUE" : "INDEX"));
$return[$row["name"]]["columns"][$row["key_ordinal"]] = $row["column_name"]; $return[$name]["lengths"] = array();
$return[$name]["columns"][$row["key_ordinal"]] = $row["column_name"];
$return[$name]["descs"][$row["key_ordinal"]] = ($row["is_descending_key"] ? '1' : null);
} }
return $return; return $return;
} }
@@ -375,10 +377,6 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
return nl_br(h(preg_replace('~^(\\[[^]]*])+~m', '', $connection->error))); return nl_br(h(preg_replace('~^(\\[[^]]*])+~m', '', $connection->error)));
} }
function exact_value($val) {
return q($val);
}
function create_database($db, $collation) { function create_database($db, $collation) {
return queries("CREATE DATABASE " . idf_escape($db) . (eregi('^[a-z0-9_]+$', $collation) ? " COLLATE $collation" : "")); return queries("CREATE DATABASE " . idf_escape($db) . (eregi('^[a-z0-9_]+$', $collation) ? " COLLATE $collation" : ""));
} }

View File

@@ -366,16 +366,21 @@ if (!defined("DRIVER")) {
/** Get table status /** Get table status
* @param string * @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 * @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(); $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) : "ORDER BY Name")
: "SHOW TABLE STATUS" . ($name != "" ? " LIKE " . q(addcslashes($name, "%_\\")) : "")
) as $row) {
if ($row["Engine"] == "InnoDB") { if ($row["Engine"] == "InnoDB") {
// ignore internal comment, unnecessary since MySQL 5.1.21 // ignore internal comment, unnecessary since MySQL 5.1.21
$row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\\1', $row["Comment"]); $row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\\1', $row["Comment"]);
} }
if (!isset($row["Rows"])) { if (!isset($row["Engine"])) {
$row["Comment"] = ""; $row["Comment"] = "";
} }
if ($name != "") { if ($name != "") {
@@ -391,7 +396,7 @@ if (!defined("DRIVER")) {
* @return bool * @return bool
*/ */
function is_view($table_status) { function is_view($table_status) {
return !isset($table_status["Rows"]); return $table_status["Engine"] === null;
} }
/** Check if table supports foreign keys /** Check if table supports foreign keys
@@ -440,6 +445,7 @@ if (!defined("DRIVER")) {
$return[$row["Key_name"]]["type"] = ($row["Key_name"] == "PRIMARY" ? "PRIMARY" : ($row["Index_type"] == "FULLTEXT" ? "FULLTEXT" : ($row["Non_unique"] ? "INDEX" : "UNIQUE"))); $return[$row["Key_name"]]["type"] = ($row["Key_name"] == "PRIMARY" ? "PRIMARY" : ($row["Index_type"] == "FULLTEXT" ? "FULLTEXT" : ($row["Non_unique"] ? "INDEX" : "UNIQUE")));
$return[$row["Key_name"]]["columns"][] = $row["Column_name"]; $return[$row["Key_name"]]["columns"][] = $row["Column_name"];
$return[$row["Key_name"]]["lengths"][] = $row["Sub_part"]; $return[$row["Key_name"]]["lengths"][] = $row["Sub_part"];
$return[$row["Key_name"]]["descs"][] = null;
} }
return $return; return $return;
} }
@@ -527,14 +533,6 @@ if (!defined("DRIVER")) {
} }
} }
/** Return expression for binary comparison
* @param string
* @return string
*/
function exact_value($val) {
return q($val) . " COLLATE utf8_bin";
}
/** Create database /** Create database
* @param string * @param string
* @param string * @param string
@@ -733,7 +731,7 @@ if (!defined("DRIVER")) {
*/ */
function triggers($table) { function triggers($table) {
$return = array(); $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[$row["Trigger"]] = array($row["Timing"], $row["Event"]);
} }
return $return; return $return;
@@ -792,7 +790,7 @@ if (!defined("DRIVER")) {
* @return array ("ROUTINE_TYPE" => , "ROUTINE_NAME" => , "DTD_IDENTIFIER" => ) * @return array ("ROUTINE_TYPE" => , "ROUTINE_NAME" => , "DTD_IDENTIFIER" => )
*/ */
function routines() { 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 /** Get list of available routine languages
@@ -846,7 +844,7 @@ if (!defined("DRIVER")) {
* @return Min_Result * @return Min_Result
*/ */
function explain($connection, $query) { 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 /** Get approximate number of rows
@@ -924,7 +922,7 @@ if (!defined("DRIVER")) {
*/ */
function trigger_sql($table, $style) { function trigger_sql($table, $style) {
$return = ""; $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" : "") $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"; . "CREATE TRIGGER " . idf_escape($row["Trigger"]) . " $row[Timing] $row[Event] ON " . table($row["Table"]) . " FOR EACH ROW\n$row[Statement];;\n";
} }
@@ -960,6 +958,9 @@ if (!defined("DRIVER")) {
if (ereg("binary", $field["type"])) { if (ereg("binary", $field["type"])) {
return "HEX(" . idf_escape($field["field"]) . ")"; 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"])) { if (ereg("geometry|point|linestring|polygon", $field["type"])) {
return "AsWKT(" . idf_escape($field["field"]) . ")"; return "AsWKT(" . idf_escape($field["field"]) . ")";
} }
@@ -974,6 +975,9 @@ if (!defined("DRIVER")) {
if (ereg("binary", $field["type"])) { if (ereg("binary", $field["type"])) {
$return = "UNHEX($return)"; $return = "UNHEX($return)";
} }
if ($field["type"] == "bit") {
$return = "CONV($return, 2, 10) + 0";
}
if (ereg("geometry|point|linestring|polygon", $field["type"])) { if (ereg("geometry|point|linestring|polygon", $field["type"])) {
$return = "GeomFromText($return)"; $return = "GeomFromText($return)";
} }
@@ -1004,7 +1008,7 @@ if (!defined("DRIVER")) {
$structured_types[$key] = array_keys($val); $structured_types[$key] = array_keys($val);
} }
$unsigned = array("unsigned", "zerofill", "unsigned zerofill"); ///< @var array number variants $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 $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 $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 $edit_functions = array( ///< @var array of array("$type|$type2" => "$function/$function2") functions used in editing, [0] - edit and insert, [1] - edit only

View File

@@ -181,7 +181,8 @@ if (isset($_GET["oracle"])) {
function tables_list() { function tables_list() {
return get_key_vals("SELECT table_name, 'table' FROM all_tables WHERE tablespace_name = " . q(DB) . " return get_key_vals("SELECT table_name, 'table' FROM all_tables WHERE tablespace_name = " . q(DB) . "
UNION SELECT view_name, 'view' FROM user_views" UNION SELECT view_name, 'view' FROM user_views
ORDER BY 1"
); //! views don't have schema ); //! views don't have schema
} }
@@ -193,7 +194,8 @@ UNION SELECT view_name, 'view' FROM user_views"
$return = array(); $return = array();
$search = q($name); $search = q($name);
foreach (get_rows('SELECT table_name "Name", \'table\' "Engine", avg_row_len * num_rows "Data_length", num_rows "Rows" FROM all_tables WHERE tablespace_name = ' . q(DB) . ($name != "" ? " AND table_name = $search" : "") . " foreach (get_rows('SELECT table_name "Name", \'table\' "Engine", avg_row_len * num_rows "Data_length", num_rows "Rows" FROM all_tables WHERE tablespace_name = ' . q(DB) . ($name != "" ? " AND table_name = $search" : "") . "
UNION SELECT view_name, 'view', 0, 0 FROM user_views" . ($name != "" ? " WHERE view_name = $search" : "") UNION SELECT view_name, 'view', 0, 0 FROM user_views" . ($name != "" ? " WHERE view_name = $search" : "") . "
ORDER BY 1"
) as $row) { ) as $row) {
if ($name != "") { if ($name != "") {
return $row; return $row;
@@ -243,9 +245,11 @@ FROM user_ind_columns uic
LEFT JOIN user_constraints uc ON uic.index_name = uc.constraint_name AND uic.table_name = uc.table_name LEFT JOIN user_constraints uc ON uic.index_name = uc.constraint_name AND uic.table_name = uc.table_name
WHERE uic.table_name = " . q($table) . " WHERE uic.table_name = " . q($table) . "
ORDER BY uc.constraint_type, uic.column_position", $connection2) as $row) { ORDER BY uc.constraint_type, uic.column_position", $connection2) as $row) {
$return[$row["INDEX_NAME"]]["type"] = ($row["CONSTRAINT_TYPE"] == "P" ? "PRIMARY" : ($row["CONSTRAINT_TYPE"] == "U" ? "UNIQUE" : "INDEX")); $index_name = $row["INDEX_NAME"];
$return[$row["INDEX_NAME"]]["columns"][] = $row["COLUMN_NAME"]; $return[$index_name]["type"] = ($row["CONSTRAINT_TYPE"] == "P" ? "PRIMARY" : ($row["CONSTRAINT_TYPE"] == "U" ? "UNIQUE" : "INDEX"));
$return[$row["INDEX_NAME"]]["lengths"][] = ($row["CHAR_LENGTH"] && $row["CHAR_LENGTH"] != $row["COLUMN_LENGTH"] ? $row["CHAR_LENGTH"] : null); $return[$index_name]["columns"][] = $row["COLUMN_NAME"];
$return[$index_name]["lengths"][] = ($row["CHAR_LENGTH"] && $row["CHAR_LENGTH"] != $row["COLUMN_LENGTH"] ? $row["CHAR_LENGTH"] : null);
$return[$index_name]["descs"][] = ($row["DESCEND"] ? '1' : null);
} }
return $return; return $return;
} }
@@ -268,10 +272,6 @@ ORDER BY uc.constraint_type, uic.column_position", $connection2) as $row) {
return h($connection->error); //! highlight sqltext from offset return h($connection->error); //! highlight sqltext from offset
} }
function exact_value($val) {
return q($val);
}
function explain($connection, $query) { function explain($connection, $query) {
$connection->query("EXPLAIN PLAN FOR $query"); $connection->query("EXPLAIN PLAN FOR $query");
return $connection->query("SELECT * FROM plan_table"); return $connection->query("SELECT * FROM plan_table");
@@ -386,7 +386,7 @@ ORDER BY PROCESS
$structured_types[$key] = array_keys($val); $structured_types[$key] = array_keys($val);
} }
$unsigned = array(); $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"); $functions = array("length", "lower", "round", "upper");
$grouping = array("avg", "count", "count distinct", "max", "min", "sum"); $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
$edit_functions = array( $edit_functions = array(

View File

@@ -206,11 +206,11 @@ if (isset($_GET["pgsql"])) {
function table_status($name = "") { function table_status($name = "") {
$return = array(); $return = array();
foreach (get_rows("SELECT relname AS \"Name\", CASE relkind WHEN 'r' THEN 'table' ELSE 'view' END AS \"Engine\", pg_relation_size(oid) AS \"Data_length\", pg_total_relation_size(oid) - pg_relation_size(oid) AS \"Index_length\", obj_description(oid, 'pg_class') AS \"Comment\", relhasoids AS \"Oid\", reltuples as \"Rows\" foreach (get_rows("SELECT relname AS \"Name\", CASE relkind WHEN 'r' THEN 'table' ELSE 'view' END AS \"Engine\", pg_relation_size(oid) AS \"Data_length\", pg_total_relation_size(oid) - pg_relation_size(oid) AS \"Index_length\", obj_description(oid, 'pg_class') AS \"Comment\", relhasoids::int AS \"Oid\", reltuples as \"Rows\"
FROM pg_class FROM pg_class
WHERE relkind IN ('r','v') WHERE relkind IN ('r','v')
AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema())" AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema())
. ($name != "" ? " AND relname = " . q($name) : "") " . ($name != "" ? "AND relname = " . q($name) : "ORDER BY relname")
) as $row) { //! Index_length, Auto_increment ) as $row) { //! Index_length, Auto_increment
$return[$row["Name"]] = $row; $return[$row["Name"]] = $row;
} }
@@ -227,7 +227,11 @@ AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema(
function fields($table) { function fields($table) {
$return = array(); $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 $aliases = array(
'timestamp without time zone' => 'timestamp',
'timestamp with time zone' => 'timestamptz',
);
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 FROM pg_class c
JOIN pg_namespace n ON c.relnamespace = n.oid JOIN pg_namespace n ON c.relnamespace = n.oid
JOIN pg_attribute a ON c.oid = a.attrelid JOIN pg_attribute a ON c.oid = a.attrelid
@@ -239,10 +243,13 @@ AND a.attnum > 0
ORDER BY a.attnum" ORDER BY a.attnum"
) as $row) { ) as $row) {
//! collation, primary //! collation, primary
ereg('(.*)(\\((.*)\\))?', $row["full_type"], $match); $type = $row["full_type"];
list(, $row["type"], , $row["length"]) = $match; if (ereg('(.+)\\((.*)\\)$', $row["full_type"], $match)) {
list(, $type, $row["length"]) = $match;
}
$row["type"] = ($aliases[$type] ? $aliases[$type] : $type);
$row["full_type"] = $row["type"] . ($row["length"] ? "($row[length])" : ""); $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["auto_increment"] = eregi("^nextval\\(", $row["default"]);
$row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1); $row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1);
if (preg_match('~^(.*)::.+$~', $row["default"], $match)) { if (preg_match('~^(.*)::.+$~', $row["default"], $match)) {
@@ -261,13 +268,18 @@ ORDER BY a.attnum"
$return = array(); $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)); $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); $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) { foreach (get_rows("SELECT relname, indisunique::int, indisprimary::int, indkey, indoption 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")); $relname = $row["relname"];
$return[$row["relname"]]["columns"] = array(); $return[$relname]["type"] = ($row["indisprimary"] ? "PRIMARY" : ($row["indisunique"] ? "UNIQUE" : "INDEX"));
$return[$relname]["columns"] = array();
foreach (explode(" ", $row["indkey"]) as $indkey) { foreach (explode(" ", $row["indkey"]) as $indkey) {
$return[$row["relname"]]["columns"][] = $columns[$indkey]; $return[$relname]["columns"][] = $columns[$indkey];
} }
$return[$row["relname"]]["lengths"] = array(); $return[$relname]["descs"] = array();
foreach (explode(" ", $row["indoption"]) as $indoption) {
$return[$relname]["descs"][] = ($indoption & 1 ? '1' : null); // 1 - INDOPTION_DESC
}
$return[$relname]["lengths"] = array();
} }
return $return; return $return;
} }
@@ -319,10 +331,6 @@ ORDER BY conkey, conname") as $row) {
return nl_br($return); return nl_br($return);
} }
function exact_value($val) {
return q($val);
}
function create_database($db, $collation) { function create_database($db, $collation) {
return queries("CREATE DATABASE " . idf_escape($db) . ($collation ? " ENCODING " . idf_escape($collation) : "")); return queries("CREATE DATABASE " . idf_escape($db) . ($collation ? " ENCODING " . idf_escape($collation) : ""));
} }
@@ -399,21 +407,32 @@ ORDER BY conkey, conname") as $row) {
function alter_indexes($table, $alter) { function alter_indexes($table, $alter) {
$create = array(); $create = array();
$drop = array(); $drop = array();
$queries = array();
foreach ($alter as $val) { foreach ($alter as $val) {
if ($val[0] != "INDEX") { if ($val[0] != "INDEX") {
//! descending UNIQUE indexes results in syntax error
$create[] = ($val[2] == "DROP" $create[] = ($val[2] == "DROP"
? "\nDROP CONSTRAINT " . idf_escape($val[1]) ? "\nDROP CONSTRAINT " . idf_escape($val[1])
: "\nADD $val[0] " . ($val[0] == "PRIMARY" ? "KEY " : "") . $val[2] : "\nADD" . ($val[1] != "" ? " CONSTRAINT " . idf_escape($val[1]) : "") . " $val[0] " . ($val[0] == "PRIMARY" ? "KEY " : "") . $val[2]
); );
} elseif ($val[2] == "DROP") { } elseif ($val[2] == "DROP") {
$drop[] = idf_escape($val[1]); $drop[] = idf_escape($val[1]);
} elseif (!queries("CREATE INDEX " . idf_escape($val[1] != "" ? $val[1] : uniqid($table . "_")) . " ON " . table($table) . " $val[2]")) { } else {
$queries[] = "CREATE INDEX " . idf_escape($val[1] != "" ? $val[1] : uniqid($table . "_")) . " ON " . table($table) . " $val[2]";
}
}
if ($create) {
array_unshift($queries, "ALTER TABLE " . table($table) . implode(",", $create));
}
if ($drop) {
array_unshift($queries, "DROP INDEX " . implode(", ", $drop));
}
foreach ($queries as $query) {
if (!queries($query)) {
return false; return false;
} }
} }
return ((!$create || queries("ALTER TABLE " . table($table) . implode(",", $create))) return true;
&& (!$drop || queries("DROP INDEX " . implode(", ", $drop)))
);
} }
function truncate_tables($tables) { function truncate_tables($tables) {
@@ -607,7 +626,7 @@ AND typelem = 0"
$structured_types[$key] = array_keys($val); $structured_types[$key] = array_keys($val);
} }
$unsigned = array(); $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"); $functions = array("char_length", "lower", "round", "to_hex", "to_timestamp", "upper");
$grouping = array("avg", "count", "count distinct", "max", "min", "sum"); $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
$edit_functions = array( $edit_functions = array(

View File

@@ -253,8 +253,8 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
function table_status($name = "") { function table_status($name = "") {
global $connection; global $connection;
$return = array(); $return = array();
foreach (get_rows("SELECT name AS Name, type AS Engine FROM sqlite_master WHERE type IN ('table', 'view')" . ($name != "" ? " AND name = " . q($name) : "")) as $row) { foreach (get_rows("SELECT name AS Name, type AS Engine FROM sqlite_master WHERE type IN ('table', 'view') " . ($name != "" ? "AND name = " . q($name) : "ORDER BY name")) as $row) {
$row["Oid"] = "t"; $row["Oid"] = 1;
$row["Auto_increment"] = ""; $row["Auto_increment"] = "";
$row["Rows"] = $connection->result("SELECT COUNT(*) FROM " . idf_escape($row["Name"])); $row["Rows"] = $connection->result("SELECT COUNT(*) FROM " . idf_escape($row["Name"]));
$return[$row["Name"]] = $row; $return[$row["Name"]] = $row;
@@ -304,12 +304,21 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
if ($primary) { if ($primary) {
$return[""] = array("type" => "PRIMARY", "columns" => $primary, "lengths" => array()); $return[""] = array("type" => "PRIMARY", "columns" => $primary, "lengths" => array());
} }
$sqls = get_key_vals("SELECT name, sql FROM sqlite_master WHERE type = 'index' AND tbl_name = " . q($table));
foreach (get_rows("PRAGMA index_list(" . table($table) . ")") as $row) { foreach (get_rows("PRAGMA index_list(" . table($table) . ")") as $row) {
if (!ereg("^sqlite_", $row["name"])) { $name = $row["name"];
$return[$row["name"]]["type"] = ($row["unique"] ? "UNIQUE" : "INDEX"); if (!ereg("^sqlite_", $name)) {
$return[$row["name"]]["lengths"] = array(); $return[$name]["type"] = ($row["unique"] ? "UNIQUE" : "INDEX");
foreach (get_rows("PRAGMA index_info(" . idf_escape($row["name"]) . ")") as $row1) { $return[$name]["lengths"] = array();
$return[$row["name"]]["columns"][] = $row1["name"]; foreach (get_rows("PRAGMA index_info(" . idf_escape($name) . ")") as $row1) {
$return[$name]["columns"][] = $row1["name"];
}
$return[$name]["descs"] = array();
if (eregi('^CREATE( UNIQUE)? INDEX ' . quotemeta(idf_escape($name) . ' ON ' . idf_escape($table)) . ' \((.*)\)$', $sqls[$name], $regs)) {
preg_match_all('/("[^"]*+")+( DESC)?/', $regs[2], $matches);
foreach ($matches[2] as $val) {
$return[$name]["descs"][] = ($val ? '1' : null);
}
} }
} }
} }
@@ -348,10 +357,6 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return h($connection->error); return h($connection->error);
} }
function exact_value($val) {
return q($val);
}
function check_sqlite_name($name) { function check_sqlite_name($name) {
// avoid creating PHP files on unsecured servers // avoid creating PHP files on unsecured servers
global $connection; global $connection;
@@ -514,7 +519,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
} }
function alter_indexes($table, $alter) { function alter_indexes($table, $alter) {
foreach ($alter as $val) { foreach (array_reverse($alter) as $val) {
if (!queries($val[2] == "DROP" if (!queries($val[2] == "DROP"
? "DROP INDEX " . idf_escape($val[1]) ? "DROP INDEX " . idf_escape($val[1])
: index_sql($table, $val[0], $val[1], $val[2]) : index_sql($table, $val[0], $val[1], $val[2])
@@ -620,7 +625,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
function create_sql($table, $auto_increment) { function create_sql($table, $auto_increment) {
global $connection; 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) { foreach (indexes($table) as $name => $index) {
if ($name == '') { if ($name == '') {
continue; continue;
@@ -674,7 +679,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
$types = array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0); $types = array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0);
$structured_types = array_keys($types); $structured_types = array_keys($types);
$unsigned = array(); $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"); $functions = array("hex", "length", "lower", "round", "unixepoch", "upper");
$grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"); $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
$edit_functions = array( $edit_functions = array(

View File

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

View File

@@ -8,6 +8,7 @@ foreach ($fields as $name => $field) {
unset($fields[$name]); unset($fields[$name]);
} }
} }
if ($_POST && !$error && !isset($_GET["select"])) { if ($_POST && !$error && !isset($_GET["select"])) {
$location = $_POST["referer"]; $location = $_POST["referer"];
if ($_POST["insert"]) { // continue edit or insert if ($_POST["insert"]) { // continue edit or insert
@@ -15,8 +16,18 @@ if ($_POST && !$error && !isset($_GET["select"])) {
} elseif (!ereg('^.+&select=.+$', $location)) { } elseif (!ereg('^.+&select=.+$', $location)) {
$location = ME . "select=" . urlencode($TABLE); $location = ME . "select=" . urlencode($TABLE);
} }
$indexes = indexes($TABLE);
$unique_array = unique_array($_GET["where"], $indexes);
$query_where = "\nWHERE $where";
if (isset($_POST["delete"])) { 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 { } else {
$set = array(); $set = array();
foreach ($fields as $name => $field) { 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); $set[idf_escape($name)] = ($update ? "\n" . idf_escape($name) . " = $val" : $val);
} }
} }
if ($update) { if ($update) {
if (!$set) { if (!$set) {
redirect($location); 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 { } else {
$result = insert_into($TABLE, $set); $result = insert_into($TABLE, $set);
$last_id = ($result ? last_id() : 0); $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_status1($TABLE, true));
page_header( page_header(
($update ? lang('Edit') : lang('Insert')), ($update ? lang('Edit') : lang('Insert')),
$error, $error,
@@ -81,12 +98,19 @@ if (!$fields) {
echo "<p class='error'>" . lang('You have no privileges to update this table.') . "\n"; echo "<p class='error'>" . lang('You have no privileges to update this table.') . "\n";
} else { } else {
echo "<table cellspacing='0' onkeydown='return editingKeydown(event);'>\n"; echo "<table cellspacing='0' onkeydown='return editingKeydown(event);'>\n";
foreach ($fields as $name => $field) { foreach ($fields as $name => $field) {
echo "<tr><th>" . $adminer->fieldName($field); echo "<tr><th>" . $adminer->fieldName($field);
$default = $_GET["set"][bracket_escape($name)]; $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 $value = ($row !== null
? ($row[$name] != "" && $jush == "sql" && ereg("enum|set", $field["type"]) ? (is_array($row[$name]) ? array_sum($row[$name]) : +$row[$name]) : $row[$name]) ? ($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)) { if (!$_POST["save"] && is_string($value)) {
$value = $adminer->editVal($value, $field); $value = $adminer->editVal($value, $field);
@@ -99,6 +123,7 @@ if (!$fields) {
input($field, $value, $function); input($field, $value, $function);
echo "\n"; echo "\n";
} }
echo "</table>\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" 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"])) { if (isset($_GET["select"])) {
hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"])); hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"]));

View File

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

View File

@@ -1,50 +1,50 @@
<?php <?php
$TABLE = $_GET["foreign"]; $TABLE = $_GET["foreign"];
$name = $_GET["name"];
$row = $_POST;
if ($_POST && !$error && !$_POST["add"] && !$_POST["change"] && !$_POST["change-js"]) { if ($_POST && !$error && !$_POST["add"] && !$_POST["change"] && !$_POST["change-js"]) {
if ($_POST["drop"]) { 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 { } else {
$source = array_filter($_POST["source"], 'strlen'); $source = array_filter($row["source"], 'strlen');
ksort($source); // enforce input order ksort($source); // enforce input order
$target = array(); $target = array();
foreach ($source as $key => $val) { foreach ($source as $key => $val) {
$target[$key] = $_POST["target"][$key]; $target[$key] = $row["target"][$key];
} }
query_redirect("ALTER TABLE " . table($TABLE) query_redirect("ALTER TABLE " . table($TABLE)
. ($_GET["name"] != "" ? "\nDROP " . ($jush == "sql" ? "FOREIGN KEY " : "CONSTRAINT ") . idf_escape($_GET["name"]) . "," : "") . ($name != "" ? "\nDROP " . ($jush == "sql" ? "FOREIGN KEY " : "CONSTRAINT ") . idf_escape($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 . "\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)\$", $_POST["on_delete"]) ? " ON DELETE $_POST[on_delete]" : "") . (ereg("^($on_actions)\$", $row["on_delete"]) ? " ON DELETE $row[on_delete]" : "")
. (ereg("^($on_actions)\$", $_POST["on_update"]) ? " ON UPDATE $_POST[on_update]" : "") . (ereg("^($on_actions)\$", $row["on_update"]) ? " ON UPDATE $row[on_update]" : "")
, ME . "table=" . urlencode($TABLE), ($_GET["name"] != "" ? lang('Foreign key has been altered.') : lang('Foreign key has been created.'))); , 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 $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); page_header(lang('Foreign key'), $error, array("table" => $TABLE), $TABLE);
$row = array("table" => $TABLE, "source" => array(""));
if ($_POST) { if ($_POST) {
$row = $_POST;
ksort($row["source"]); ksort($row["source"]);
if ($_POST["add"]) { if ($_POST["add"]) {
$row["source"][] = ""; $row["source"][] = "";
} elseif ($_POST["change"] || $_POST["change-js"]) { } elseif ($_POST["change"] || $_POST["change-js"]) {
$row["target"] = array(); $row["target"] = array();
} }
} elseif ($_GET["name"] != "") { } elseif ($name != "") {
$foreign_keys = foreign_keys($TABLE); $foreign_keys = foreign_keys($TABLE);
$row = $foreign_keys[$_GET["name"]]; $row = $foreign_keys[$name];
$row["source"][] = ""; $row["source"][] = "";
} else {
$row["table"] = $TABLE;
$row["source"] = array("");
} }
$source = array_keys(fields($TABLE)); //! no text and blob $source = array_keys(fields($TABLE)); //! no text and blob
$target = ($TABLE === $row["table"] ? $source : array_keys(fields($row["table"]))); $target = ($TABLE === $row["table"] ? $source : array_keys(fields($row["table"])));
$referencable = array(); $referencable = array_keys(array_filter(table_status('', true), 'fk_support'));
foreach (table_status() as $name => $table_status) {
if (fk_support($table_status)) {
$referencable[] = $name;
}
}
?> ?>
<form action="" method="post"> <form action="" method="post">
@@ -73,6 +73,6 @@ foreach ($row["source"] as $key => $val) {
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<noscript><p><input type="submit" name="add" value="<?php echo lang('Add column'); ?>"></noscript> <noscript><p><input type="submit" name="add" value="<?php echo lang('Add column'); ?>"></noscript>
<?php } ?> <?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; ?>"> <input type="hidden" name="token" value="<?php echo $token; ?>">
</form> </form>

View File

@@ -20,10 +20,11 @@ class Adminer {
} }
/** Get key used for permanent login /** Get key used for permanent login
* @return string cryptic string which gets combined with password * @param bool
* @return string cryptic string which gets combined with password or false in case of an error
*/ */
function permanentLogin() { function permanentLogin($create = false) {
return password_file(); return password_file($create);
} }
/** Identifier of selected database /** Identifier of selected database
@@ -71,14 +72,14 @@ class Adminer {
?> ?>
<table cellspacing="0"> <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('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('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('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"> <tr><th><?php echo lang('Database'); ?><td><input name="auth[db]" value="<?php echo h($_GET["db"]); ?>" autocapitalize="off">
</table> </table>
<script type="text/javascript"> <script type="text/javascript">
var username = document.getElementById('username'); var username = document.getElementById('username');
username.focus(); focus(username);
username.form['auth[driver]'].onchange(); username.form['auth[driver]'].onchange();
</script> </script>
<?php <?php
@@ -264,7 +265,7 @@ username.form['auth[driver]'].onchange();
if (!$val || ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators))) { 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 "<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 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"; echo "</div></fieldset>\n";
@@ -287,7 +288,7 @@ username.form['auth[driver]'].onchange();
} }
} }
echo "<div><select name='order[$i]' onchange='selectAddRow(this);'><option>" . optionlist($columns, null, true) . "</select>"; echo "<div><select name='order[$i]' onchange='selectAddRow(this);'><option>" . optionlist($columns, null, true) . "</select>";
echo "<label><input type='checkbox' name='desc[$i]' value='1'>" . lang('descending') . "</label></div>\n"; // not checkbox() to allow selectAddRow() echo checkbox("desc[$i]", 1, false, lang('descending')) . "</div>\n";
echo "</div></fieldset>\n"; echo "</div></fieldset>\n";
} }
@@ -400,8 +401,8 @@ username.form['auth[driver]'].onchange();
if (ereg('IN$', $val["op"])) { if (ereg('IN$', $val["op"])) {
$in = process_length($val["val"]); $in = process_length($val["val"]);
$cond .= " (" . ($in != "" ? $in : "NULL") . ")"; $cond .= " (" . ($in != "" ? $in : "NULL") . ")";
} elseif (!$val["op"]) { } elseif ($val["op"] == "SQL") {
$cond .= $val["val"]; // SQL injection $cond = " $val[val]"; // SQL injection
} elseif ($val["op"] == "LIKE %%") { } elseif ($val["op"] == "LIKE %%") {
$cond = " LIKE " . $this->processInput($fields[$val["col"]], "%$val[val]%"); $cond = " LIKE " . $this->processInput($fields[$val["col"]], "%$val[val]%");
} elseif (!ereg('NULL$', $val["op"])) { } elseif (!ereg('NULL$', $val["op"])) {
@@ -414,7 +415,7 @@ username.form['auth[driver]'].onchange();
$cols = array(); $cols = array();
foreach ($fields as $name => $field) { foreach ($fields as $name => $field) {
$is_text = ereg('char|text|enum|set', $field["type"]); $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) && (!ereg("[\x80-\xFF]", $val["val"]) || $is_text)
) { ) {
$name = idf_escape($name); $name = idf_escape($name);
@@ -510,7 +511,7 @@ username.form['auth[driver]'].onchange();
} }
} }
if ($key && !ereg('set|blob|bytea|raw|file', $field["type"])) { if ($key && !ereg('set|blob|bytea|raw|file', $field["type"])) {
$return .= "/="; $return .= "/SQL";
} }
} }
} }
@@ -541,11 +542,11 @@ username.form['auth[driver]'].onchange();
* @return string expression to use in a query * @return string expression to use in a query
*/ */
function processInput($field, $value, $function = "") { function processInput($field, $value, $function = "") {
if ($function == "=") { if ($function == "SQL") {
return $value; // SQL injection return $value; // SQL injection
} }
$name = $field["field"]; $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)) { if (ereg('^(now|getdate|uuid)$', $function)) {
$return = "$function()"; $return = "$function()";
} elseif (ereg('^current_(date|timestamp)$', $function)) { } elseif (ereg('^current_(date|timestamp)$', $function)) {
@@ -570,9 +571,6 @@ username.form['auth[driver]'].onchange();
if (function_exists('gzencode')) { if (function_exists('gzencode')) {
$return['gz'] = 'gzip'; $return['gz'] = 'gzip';
} }
if (function_exists('bzcompress')) {
$return['bz2'] = 'bzip2';
}
return $return; return $return;
} }
@@ -593,22 +591,30 @@ username.form['auth[driver]'].onchange();
/** Export table structure /** Export table structure
* @param string * @param string
* @param string * @param string
* @param bool * @param int 0 table, 1 view, 2 temporary view table
* @return null prints data * @return null prints data
*/ */
function dumpTable($table, $style, $is_view = false) { function dumpTable($table, $style, $is_view = 0) {
if ($_POST["format"] != "sql") { if ($_POST["format"] != "sql") {
echo "\xef\xbb\xbf"; // UTF-8 byte order mark echo "\xef\xbb\xbf"; // UTF-8 byte order mark
if ($style) { if ($style) {
dump_csv(array_keys(fields($table))); dump_csv(array_keys(fields($table)));
} }
} elseif ($style) { } elseif ($style) {
$create = create_sql($table, $_POST["auto_increment"]); if ($is_view == 2) {
if ($create) { $fields = array();
if ($style == "DROP+CREATE") { foreach (fields($table) as $name => $field) {
echo "DROP " . ($is_view ? "VIEW" : "TABLE") . " IF EXISTS " . table($table) . ";\n"; $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); $create = remove_definer($create);
} }
echo "$create;\n\n"; echo "$create;\n\n";
@@ -626,10 +632,10 @@ username.form['auth[driver]'].onchange();
global $connection, $jush; global $connection, $jush;
$max_packet = ($jush == "sqlite" ? 0 : 1048576); // default, minimum is 1024 $max_packet = ($jush == "sqlite" ? 0 : 1048576); // default, minimum is 1024
if ($style) { if ($style) {
if ($_POST["format"] == "sql" && $style == "TRUNCATE+INSERT") {
echo truncate_sql($table) . ";\n";
}
if ($_POST["format"] == "sql") { if ($_POST["format"] == "sql") {
if ($style == "TRUNCATE+INSERT") {
echo truncate_sql($table) . ";\n";
}
$fields = fields($table); $fields = fields($table);
} }
$result = $connection->query($query, 1); // 1 - MYSQLI_USE_RESULT //! enum and set as numbers $result = $connection->query($query, 1); // 1 - MYSQLI_USE_RESULT //! enum and set as numbers
@@ -638,7 +644,8 @@ username.form['auth[driver]'].onchange();
$buffer = ""; $buffer = "";
$keys = array(); $keys = array();
$suffix = ""; $suffix = "";
while ($row = $result->fetch_row()) { $fetch_function = ($table != '' ? 'fetch_assoc' : 'fetch_row');
while ($row = $result->$fetch_function()) {
if (!$keys) { if (!$keys) {
$values = array(); $values = array();
foreach ($row as $val) { foreach ($row as $val) {
@@ -660,8 +667,9 @@ username.form['auth[driver]'].onchange();
$insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('idf_escape', $keys)) . ") VALUES"; $insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('idf_escape', $keys)) . ") VALUES";
} }
foreach ($row as $key => $val) { foreach ($row as $key => $val) {
$field = $fields[$key];
$row[$key] = ($val !== null $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" : "NULL"
); );
} }
@@ -702,14 +710,10 @@ username.form['auth[driver]'].onchange();
$output = $_POST["output"]; $output = $_POST["output"];
$ext = (ereg('sql', $_POST["format"]) ? "sql" : ($multi_table ? "tar" : "csv")); // multiple CSV packed to TAR $ext = (ereg('sql', $_POST["format"]) ? "sql" : ($multi_table ? "tar" : "csv")); // multiple CSV packed to TAR
header("Content-Type: " . header("Content-Type: " .
($output == "bz2" ? "application/x-bzip" :
($output == "gz" ? "application/x-gzip" : ($output == "gz" ? "application/x-gzip" :
($ext == "tar" ? "application/x-tar" : ($ext == "tar" ? "application/x-tar" :
($ext == "sql" || $output != "file" ? "text/plain" : "text/csv") . "; charset=utf-8" ($ext == "sql" || $output != "file" ? "text/plain" : "text/csv") . "; charset=utf-8"
)))); )));
if ($output == "bz2") {
ob_start('bzcompress', 1e6);
}
if ($output == "gz") { if ($output == "gz") {
ob_start('gzencode', 1e6); ob_start('gzencode', 1e6);
} }
@@ -763,7 +767,7 @@ username.form['auth[driver]'].onchange();
<p class="logout"> <p class="logout">
<?php <?php
if (DB == "" || !$missing) { if (DB == "" || !$missing) {
echo "<a href='" . h(ME) . "sql='" . bold(isset($_GET["sql"])) . ">" . lang('SQL command') . "</a>\n"; echo "<a href='" . h(ME) . "sql='" . bold(isset($_GET["sql"])) . " title='" . lang('Import') . "'>" . lang('SQL command') . "</a>\n";
if (support("dump")) { if (support("dump")) {
echo "<a href='" . h(ME) . "dump=" . urlencode(isset($_GET["table"]) ? $_GET["table"] : $_GET["select"]) . "' id='dump'" . bold(isset($_GET["dump"])) . ">" . lang('Dump') . "</a>\n"; echo "<a href='" . h(ME) . "dump=" . urlencode(isset($_GET["table"]) ? $_GET["table"] : $_GET["select"]) . "' id='dump'" . bold(isset($_GET["dump"])) . ">" . lang('Dump') . "</a>\n";
} }
@@ -777,7 +781,7 @@ username.form['auth[driver]'].onchange();
$this->databasesPrint($missing); $this->databasesPrint($missing);
if ($_GET["ns"] !== "" && !$missing && DB != "") { if ($_GET["ns"] !== "" && !$missing && DB != "") {
echo '<p><a href="' . h(ME) . 'create="' . bold($_GET["create"] === "") . ">" . lang('Create new table') . "</a>\n"; 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) { if (!$tables) {
echo "<p class='message'>" . lang('No tables.') . "\n"; echo "<p class='message'>" . lang('No tables.') . "\n";
} else { } else {
@@ -808,17 +812,16 @@ username.form['auth[driver]'].onchange();
<form action=""> <form action="">
<p id="dbs"> <p id="dbs">
<?php <?php
hidden_fields_get(); hidden_fields_get();
echo ($databases $db_events = " onmousedown='dbMouseDown(event, this);' onchange='dbChange(this);'";
? '<select name="db" onmousedown="dbMouseDown(event, this);" onchange="dbChange(this);">' . optionlist(array("" => "(" . lang('database') . ")") + $databases, DB) . '</select>' echo ($databases
: '<input name="db" value="' . h(DB) . '" autocapitalize="off">' ? "<select name='db'$db_events>" . optionlist(array("" => "(" . lang('database') . ")") + $databases, DB) . "</select>"
); : '<input name="db" value="' . h(DB) . '" autocapitalize="off">'
?> );
<input type="submit" value="<?php echo lang('Use'); ?>"<?php echo ($databases ? " class='hidden'" : ""); ?>> echo "<input type='submit' value='" . lang('Use') . "'" . ($databases ? " class='hidden'" : "") . ">\n";
<?php
if ($missing != "db" && DB != "" && $connection->select_db(DB)) { if ($missing != "db" && DB != "" && $connection->select_db(DB)) {
if (support("scheme")) { if (support("scheme")) {
echo "<br>" . html_select("ns", array("" => "(" . lang('schema') . ")") + schemas(), $_GET["ns"], "this.form.submit();"); echo "<br><select name='ns'$db_events>" . optionlist(array("" => "(" . lang('schema') . ")") + schemas(), $_GET["ns"]) . "</select>";
if ($_GET["ns"] != "") { if ($_GET["ns"] != "") {
set_schema($_GET["ns"]); set_schema($_GET["ns"]);
} }
@@ -832,14 +835,14 @@ echo ($databases
} }
/** Prints table list in menu /** Prints table list in menu
* @param array * @param array result of table_status('', true)
* @return null * @return null
*/ */
function tablesPrint($tables) { function tablesPrint($tables) {
echo "<p id='tables' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n"; 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) . 'select=' . urlencode($table) . '"' . bold($_GET["select"] == $table || $_GET["edit"] == $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(in_array($table, array($_GET["table"], $_GET["create"], $_GET["indexes"], $_GET["foreign"], $_GET["trigger"]))) . " title='" . lang('Show structure') . "'>" . $this->tableName($status) . "</a><br>\n";
} }
} }

View File

@@ -21,7 +21,7 @@ if ($auth) {
$_SESSION["db"][$auth["driver"]][$auth["server"]][$auth["username"]][$auth["db"]] = true; $_SESSION["db"][$auth["driver"]][$auth["server"]][$auth["username"]][$auth["db"]] = true;
if ($auth["permanent"]) { if ($auth["permanent"]) {
$key = base64_encode($auth["driver"]) . "-" . base64_encode($auth["server"]) . "-" . base64_encode($auth["username"]) . "-" . base64_encode($auth["db"]); $key = base64_encode($auth["driver"]) . "-" . base64_encode($auth["server"]) . "-" . base64_encode($auth["username"]) . "-" . base64_encode($auth["db"]);
$private = $adminer->permanentLogin(); $private = $adminer->permanentLogin(true);
$permanent[$key] = "$key:" . base64_encode($private ? encrypt_string($auth["password"], $private) : ""); $permanent[$key] = "$key:" . base64_encode($private ? encrypt_string($auth["password"], $private) : "");
cookie("adminer_permanent", implode(" ", $permanent)); cookie("adminer_permanent", implode(" ", $permanent));
} }
@@ -33,6 +33,7 @@ if ($auth) {
) { ) {
redirect(auth_url($auth["driver"], $auth["server"], $auth["username"], $auth["db"])); redirect(auth_url($auth["driver"], $auth["server"], $auth["username"], $auth["db"]));
} }
} elseif ($_POST["logout"]) { } elseif ($_POST["logout"]) {
if ($token && $_POST["token"] != $token) { if ($token && $_POST["token"] != $token) {
page_header(lang('Logout'), lang('Invalid CSRF token. Send the form again.')); page_header(lang('Logout'), lang('Invalid CSRF token. Send the form again.'));
@@ -45,9 +46,10 @@ if ($auth) {
unset_permanent(); unset_permanent();
redirect(substr(preg_replace('~(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.')); redirect(substr(preg_replace('~(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.'));
} }
} elseif ($permanent && !$_SESSION["pwds"]) { } elseif ($permanent && !$_SESSION["pwds"]) {
session_regenerate_id(); session_regenerate_id();
$private = $adminer->permanentLogin(); // try to decode even if not set $private = $adminer->permanentLogin();
foreach ($permanent as $key => $val) { foreach ($permanent as $key => $val) {
list(, $cipher) = explode(":", $val); list(, $cipher) = explode(":", $val);
list($driver, $server, $username, $db) = array_map('base64_decode', explode("-", $key)); list($driver, $server, $username, $db) = array_map('base64_decode', explode("-", $key));
@@ -80,6 +82,9 @@ function auth_error($exception = null) {
$password = &get_session("pwds"); $password = &get_session("pwds");
if ($password !== null) { if ($password !== null) {
$error = h($exception ? $exception->getMessage() : (is_string($connection) ? $connection : lang('Invalid credentials.'))); $error = h($exception ? $exception->getMessage() : (is_string($connection) ? $connection : lang('Invalid credentials.')));
if ($password === false) {
$error .= '<br>' . lang('Master password expired. <a href="http://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.', '<code>permanentLogin()</code>');
}
$password = null; $password = null;
} }
unset_permanent(); unset_permanent();
@@ -105,6 +110,7 @@ if (isset($_GET["username"])) {
} }
$connection = connect(); $connection = connect();
} }
if (is_string($connection) || !$adminer->login($_GET["username"], get_session("pwds"))) { if (is_string($connection) || !$adminer->login($_GET["username"], get_session("pwds"))) {
auth_error(); auth_error();
exit; exit;
@@ -134,7 +140,11 @@ if ($_POST) {
: lang('Invalid CSRF token. Send the form again.') : lang('Invalid CSRF token. Send the form again.')
); );
} }
} elseif ($_SERVER["REQUEST_METHOD"] == "POST") { } elseif ($_SERVER["REQUEST_METHOD"] == "POST") {
// posted form with no data means that post_max_size exceeded because Adminer always sends token at least // 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'"); $error = lang('Too big POST data. Reduce the data or increase the %s configuration directive.', "'post_max_size'");
if (isset($_GET["sql"])) {
$error .= ' ' . lang('You can upload a big SQL file via FTP and import it from server.');
}
} }

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 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 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 if (!strpos($_SERVER["REQUEST_URI"], '?') && $_SERVER["QUERY_STRING"] != "") { // IIS 7 compatibility
$_SERVER["REQUEST_URI"] .= "?$_SERVER[QUERY_STRING]"; $_SERVER["REQUEST_URI"] .= "?$_SERVER[QUERY_STRING]";

View File

@@ -3,6 +3,7 @@ function connect_error() {
global $adminer, $connection, $token, $error, $drivers; global $adminer, $connection, $token, $error, $drivers;
$databases = array(); $databases = array();
if (DB != "") { if (DB != "") {
header("HTTP/1.1 404 Not Found");
page_header(lang('Database') . ": " . h(DB), lang('Invalid database.'), true); page_header(lang('Database') . ": " . h(DB), lang('Invalid database.'), true);
} else { } else {
if ($_POST["db"] && !$error) { if ($_POST["db"] && !$error) {
@@ -31,6 +32,7 @@ function connect_error() {
echo "<form action='' method='post'>\n"; echo "<form action='' method='post'>\n";
echo "<table cellspacing='0' class='checkable' onclick='tableClick(event);' ondblclick='tableClick(event, true);'>\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"; echo "<thead><tr><td>&nbsp;<th>" . lang('Database') . "<td>" . lang('Collation') . "<td>" . lang('Tables') . "</thead>\n";
foreach ($databases as $db) { foreach ($databases as $db) {
$root = h(ME) . "db=" . urlencode($db); $root = h(ME) . "db=" . urlencode($db);
echo "<tr" . odd() . "><td>" . checkbox("db[]", $db, in_array($db, (array) $_POST["db"])); echo "<tr" . odd() . "><td>" . checkbox("db[]", $db, in_array($db, (array) $_POST["db"]));
@@ -39,6 +41,7 @@ function connect_error() {
echo "<td align='right'><a href='$root&amp;schema=' id='tables-" . h($db) . "' title='" . lang('Database schema') . "'>?</a>"; echo "<td align='right'><a href='$root&amp;schema=' id='tables-" . h($db) . "' title='" . lang('Database schema') . "'>?</a>";
echo "\n"; echo "\n";
} }
echo "</table>\n"; echo "</table>\n";
echo "<script type='text/javascript'>tableCheck();</script>\n"; echo "<script type='text/javascript'>tableCheck();</script>\n";
echo "<p><input type='submit' name='drop' value='" . lang('Drop') . "'" . confirm("formChecked(this, /db/)") . ">\n"; echo "<p><input type='submit' name='drop' value='" . lang('Drop') . "'" . confirm("formChecked(this, /db/)") . ">\n";
@@ -49,6 +52,7 @@ function connect_error() {
echo "<p>$refresh"; echo "<p>$refresh";
} }
} }
page_footer("db"); page_footer("db");
if ($databases) { if ($databases) {
echo "<script type='text/javascript'>ajaxSetHtml('" . js_escape(ME) . "script=connect');</script>\n"; echo "<script type='text/javascript'>ajaxSetHtml('" . js_escape(ME) . "script=connect');</script>\n";
@@ -72,6 +76,7 @@ if (support("scheme") && DB != "" && $_GET["ns"] !== "") {
redirect(preg_replace('~ns=[^&]*&~', '', ME) . "ns=" . get_schema()); redirect(preg_replace('~ns=[^&]*&~', '', ME) . "ns=" . get_schema());
} }
if (!set_schema($_GET["ns"])) { if (!set_schema($_GET["ns"])) {
header("HTTP/1.1 404 Not Found");
page_header(lang('Schema') . ": " . h($_GET["ns"]), lang('Invalid schema.'), true); page_header(lang('Schema') . ": " . h($_GET["ns"]), lang('Invalid schema.'), true);
page_footer("ns"); page_footer("ns");
exit; exit;

View File

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

View File

@@ -3,7 +3,7 @@
* @param Min_Result * @param Min_Result
* @param Min_DB connection to examine indexes * @param Min_DB connection to examine indexes
* @param string base link for <th> fields * @param string base link for <th> fields
* @param array * @param array
* @return null * @return null
*/ */
function select($result, $connection2 = null, $href = "", $orgtables = array()) { function select($result, $connection2 = null, $href = "", $orgtables = array()) {
@@ -94,7 +94,7 @@ function select($result, $connection2 = null, $href = "", $orgtables = array())
*/ */
function referencable_primary($self) { function referencable_primary($self) {
$return = array(); // table_name => field $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)) { if ($table_name != $self && fk_support($table)) {
foreach (fields($table_name) as $field) { foreach (fields($table_name) as $field) {
if ($field["primary"]) { if ($field["primary"]) {
@@ -129,15 +129,6 @@ function textarea($name, $value, $rows = 10, $cols = 80) {
echo "</textarea>"; 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 /** Print table columns for type edit
* @param string * @param string
* @param array * @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><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 <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 "<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 (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 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; global $unsigned;
return " $field[type]" return " $field[type]"
. ($field["length"] != "" ? "(" . process_length($field["length"]) . ")" : "") . ($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"]) : "") . (ereg('char|text|enum|set', $field["type"]) && $field["collation"] ? " $collate " . q($field["collation"]) : "")
; ;
} }
@@ -250,9 +241,9 @@ function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = arra
<th><?php if ($display) { ?><input name="fields[<?php echo $i; ?>][field]" value="<?php echo h($field["field"]); ?>" onchange="<?php echo ($field["field"] != "" || count($fields) > 1 ? "" : "editingAddRow(this); "); ?>editingNameChange(this);" maxlength="64" autocapitalize="off"><?php } ?><input type="hidden" name="fields[<?php echo $i; ?>][orig]" value="<?php echo h($orig); ?>"> <th><?php if ($display) { ?><input name="fields[<?php echo $i; ?>][field]" value="<?php echo h($field["field"]); ?>" onchange="<?php echo ($field["field"] != "" || count($fields) > 1 ? "" : "editingAddRow(this); "); ?>editingNameChange(this);" maxlength="64" autocapitalize="off"><?php } ?><input type="hidden" name="fields[<?php echo $i; ?>][orig]" value="<?php echo h($orig); ?>">
<?php edit_type("fields[$i]", $field, $collations, $foreign_keys); ?> <?php edit_type("fields[$i]", $field, $collations, $foreign_keys); ?>
<?php if ($type == "TABLE") { ?> <?php if ($type == "TABLE") { ?>
<td><?php echo checkbox("fields[$i][null]", 1, $field["null"]); ?> <td><?php echo checkbox("fields[$i][null]", 1, $field["null"], "", "", "block"); ?>
<td><input type="radio" name="auto_increment_col" value="<?php echo $i; ?>"<?php if ($field["auto_increment"]) { ?> checked<?php } ?> onclick="var field = this.form['fields[' + this.value + '][field]']; if (!field.value) { field.value = 'id'; field.onchange(); }"> <td><label class="block"><input type="radio" name="auto_increment_col" value="<?php echo $i; ?>"<?php if ($field["auto_increment"]) { ?> checked<?php } ?> onclick="var field = this.form['fields[' + this.value + '][field]']; if (!field.value) { field.value = 'id'; field.onchange(); }"></label><td><?php
<td><?php echo checkbox("fields[$i][has_default]", 1, $field["has_default"]); ?><input name="fields[<?php echo $i; ?>][default]" value="<?php echo h($field["default"]); ?>" onchange="this.previousSibling.checked = true;"> echo checkbox("fields[$i][has_default]", 1, $field["has_default"]); ?><input name="fields[<?php echo $i; ?>][default]" value="<?php echo h($field["default"]); ?>" onchange="this.previousSibling.checked = true;">
<?php echo (support("comment") ? "<td" . ($comments ? "" : " class='hidden'") . "><input name='fields[$i][comment]' value='" . h($field["comment"]) . "' maxlength='" . ($connection->server_info >= 5.5 ? 1024 : 255) . "'>" : ""); ?> <?php echo (support("comment") ? "<td" . ($comments ? "" : " class='hidden'") . "><input name='fields[$i][comment]' value='" . h($field["comment"]) . "' maxlength='" . ($connection->server_info >= 5.5 ? 1024 : 255) . "'>" : ""); ?>
<?php } ?> <?php } ?>
<?php <?php
@@ -269,7 +260,7 @@ function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = arra
/** Move fields up and down or add field /** Move fields up and down or add field
* @param array * @param array
* @return null * @return bool
*/ */
function process_fields(&$fields) { function process_fields(&$fields) {
ksort($fields); ksort($fields);
@@ -287,8 +278,7 @@ function process_fields(&$fields) {
} }
$offset++; $offset++;
} }
} } elseif ($_POST["down"]) {
if ($_POST["down"]) {
$found = false; $found = false;
foreach ($fields as $key => $field) { foreach ($fields as $key => $field) {
if (isset($field["field"]) && $found) { if (isset($field["field"]) && $found) {
@@ -301,11 +291,13 @@ function process_fields(&$fields) {
} }
$offset++; $offset++;
} }
} } elseif ($_POST["add"]) {
$fields = array_values($fields); $fields = array_values($fields);
if ($_POST["add"]) {
array_splice($fields, key($_POST["add"]), 0, array(array())); array_splice($fields, key($_POST["add"]), 0, array(array()));
} elseif (!$_POST["drop_col"]) {
return false;
} }
return true;
} }
/** Callback used in routine() /** Callback used in routine()
@@ -338,9 +330,12 @@ function grant($grant, $privileges, $columns, $on) {
} }
/** Drop old object and create a new one /** Drop old object and create a new one
* @param string drop query * @param string drop old object query
* @param string create query * @param string create new object query
* @param string rollback 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 * @param string
* @param string * @param string
@@ -348,32 +343,40 @@ function grant($grant, $privileges, $columns, $on) {
* @param string * @param string
* @return null redirect in success * @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"]) { if ($_POST["drop"]) {
query_redirect($drop, $location, $message_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 { } else {
if ($name != "") { queries_redirect(
queries($drop); $location,
} $message_alter,
queries_redirect($location, ($name != "" ? $message_alter : $message_create), queries($create)); queries($test) && queries($drop_test) && queries($drop) && queries($create)
if ($name != "") { );
queries($rollback);
}
} }
} }
/** Generate SQL query for creating trigger /** Generate SQL query for creating trigger
* @param string * @param string
* @return array result of trigger() * @param array result of trigger()
* @return string
*/ */
function create_trigger($on, $row) { function create_trigger($on, $row) {
global $jush; global $jush;
$timing_event = " $row[Timing] $row[Event]"; $timing_event = " $row[Timing] $row[Event]";
return "CREATE TRIGGER " return "CREATE TRIGGER "
. idf_escape($row["Trigger"]) . idf_escape($row["Trigger"])
. ($jush == "mssql" ? $on . $timing_event : $timing_event . $on) . ($jush == "mssql" ? $on . $timing_event : $timing_event . $on)
. rtrim(" $row[Type]\n$row[Statement]", ";") . rtrim(" $row[Type]\n$row[Statement]", ";")
. ";"; . ";"
;
} }
/** Generate SQL query for creating routine /** 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"); $set[] = (ereg("^($inout)\$", $field["inout"]) ? "$field[inout] " : "") . idf_escape($field["field"]) . process_type($field, "CHARACTER SET");
} }
} }
return "CREATE $routine " return "CREATE $routine "
. idf_escape(trim($row["name"])) . idf_escape(trim($row["name"]))
. " (" . implode(", ", $set) . ")" . " (" . implode(", ", $set) . ")"
. (isset($_GET["function"]) ? " RETURNS" . process_type($row["returns"], "CHARACTER SET") : "") . (isset($_GET["function"]) ? " RETURNS" . process_type($row["returns"], "CHARACTER SET") : "")
. ($row["language"] ? " LANGUAGE $row[language]" : "") . ($row["language"] ? " LANGUAGE $row[language]" : "")
. rtrim("\n$row[definition]", ";") . rtrim("\n$row[definition]", ";")
. ";"; . ";"
;
} }
/** Remove current user definer from SQL command /** 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 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
* @param string * @param TmpFile
* @return string * @return null prints the output
*/ */
function tar_file($filename, $contents) { function tar_file($filename, $tmp_file) {
$return = pack("a100a8a8a8a12a12", $filename, 644, 0, 0, decoct(strlen($contents)), decoct(time())); $return = pack("a100a8a8a8a12a12", $filename, 644, 0, 0, decoct($tmp_file->size), decoct(time()));
$checksum = 8*32; // space for checksum itself $checksum = 8*32; // space for checksum itself
for ($i=0; $i < strlen($return); $i++) { for ($i=0; $i < strlen($return); $i++) {
$checksum += ord($return[$i]); $checksum += ord($return[$i]);
} }
$return .= sprintf("%06o", $checksum) . "\0 "; $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 /** Get INI bytes value

View File

@@ -95,14 +95,16 @@ function nl_br($string) {
* @param bool * @param bool
* @param string * @param string
* @param string * @param string
* @param bool * @param string
* @return string * @return string
*/ */
function checkbox($name, $value, $checked, $label = "", $onclick = "", $jsonly = false) { function checkbox($name, $value, $checked, $label = "", $onclick = "", $class = "") {
static $id = 0; $return = "<input type='checkbox' name='$name' value='" . h($value) . "'"
$id++; . ($checked ? " checked" : "")
$return = "<input type='checkbox' name='$name' value='" . h($value) . "'" . ($checked ? " checked" : "") . ($onclick ? ' onclick="' . h($onclick) . '"' : '') . ($jsonly ? " class='jsonly'" : "") . " id='checkbox-$id'>"; . ($onclick ? ' onclick="' . h($onclick) . '"' : '')
return ($label != "" ? "<label for='checkbox-$id'>$return" . h($label) . "</label>" : $return); . ">"
;
return ($label != "" || $class ? "<label" . ($class ? " class='$class'" : "") . ">$return" . h($label) . "</label>" : $return);
} }
/** Generate list of HTML options /** Generate list of HTML options
@@ -303,7 +305,7 @@ function get_rows($query, $connection2 = null, $error = "<p class='error'>") {
/** Find unique identifier of a row /** Find unique identifier of a row
* @param array * @param array
* @param array result of indexes() * @param array result of indexes()
* @return array * @return array or null if there is no unique identifier
*/ */
function unique_array($row, $indexes) { function unique_array($row, $indexes) {
foreach ($indexes as $index) { foreach ($indexes as $index) {
@@ -318,13 +320,6 @@ function unique_array($row, $indexes) {
return $return; 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 /** Create SQL condition from parsed query string
@@ -338,12 +333,19 @@ function where($where, $fields = array()) {
$function_pattern = '(^[\w\(]+' . str_replace("_", ".*", preg_quote(idf_escape("_"))) . '\)+$)'; //! columns looking like functions $function_pattern = '(^[\w\(]+' . str_replace("_", ".*", preg_quote(idf_escape("_"))) . '\)+$)'; //! columns looking like functions
foreach ((array) $where["where"] as $key => $val) { foreach ((array) $where["where"] as $key => $val) {
$key = bracket_escape($key, 1); // 1 - back $key = bracket_escape($key, 1); // 1 - back
$return[] = (preg_match($function_pattern, $key) ? $key : idf_escape($key)) //! SQL injection $column = (preg_match($function_pattern, $key) ? $key : idf_escape($key)); //! SQL injection
. (($jush == "sql" && ereg('\\.', $val)) || $jush == "mssql" ? " LIKE " . exact_value(addcslashes($val, "%_\\")) : " = " . unconvert_field($fields[$key], exact_value($val))) // LIKE because of floats, but slow with ints, in MS SQL because of text $return[] = $column
. (($jush == "sql" && ereg('^[0-9]*\\.[0-9]*$', $val)) || $jush == "mssql"
? " LIKE " . q(addcslashes($val, "%_\\"))
: " = " . unconvert_field($fields[$key], q($val))
) // LIKE because of floats but slow with ints, in MS SQL because of text
; //! enum and set ; //! enum and set
if ($jush == "sql" && ereg("[^ -@]", $val)) { // not just [a-z] to catch non-ASCII characters
$return[] = "$column = " . q($val) . " COLLATE utf8_bin";
}
} }
foreach ((array) $where["null"] as $key) { foreach ((array) $where["null"] as $key) {
$return[] = idf_escape($key) . " IS NULL"; $return[] = (preg_match($function_pattern, $key) ? $key : idf_escape($key)) . " IS NULL";
} }
return implode(" AND ", $return); return implode(" AND ", $return);
} }
@@ -370,6 +372,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); 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 /** Set cookie valid for 1 month
* @param string * @param string
* @param string * @param string
@@ -482,12 +504,15 @@ function redirect($location, $message = null) {
*/ */
function query_redirect($query, $location, $message, $redirect = true, $execute = true, $failed = false) { function query_redirect($query, $location, $message, $redirect = true, $execute = true, $failed = false) {
global $connection, $error, $adminer; global $connection, $error, $adminer;
$time = "";
if ($execute) { if ($execute) {
$start = microtime();
$failed = !$connection->query($query); $failed = !$connection->query($query);
$time = "; -- " . format_time($start, microtime());
} }
$sql = ""; $sql = "";
if ($query) { if ($query) {
$sql = $adminer->messageQuery("$query;"); $sql = $adminer->messageQuery($query . $time);
} }
if ($failed) { if ($failed) {
$error = error() . $sql; $error = error() . $sql;
@@ -508,10 +533,13 @@ function queries($query = null) {
static $queries = array(); static $queries = array();
if ($query === null) { if ($query === null) {
// return executed queries without parameter // return executed queries without parameter
return implode(";\n", $queries); return implode("\n", $queries);
} }
$queries[] = (ereg(';$', $query) ? "DELIMITER ;;\n$query;\nDELIMITER " : $query); $start = microtime();
return $connection->query($query); $return = $connection->query($query);
$queries[] = (ereg(';$', $query) ? "DELIMITER ;;\n$query;\nDELIMITER " : $query)
. "; -- " . format_time($start, microtime());
return $return;
} }
/** Apply command to all array items /** Apply command to all array items
@@ -539,6 +567,15 @@ function queries_redirect($location, $message, $redirect) {
return query_redirect(queries(), $location, $message, $redirect, false, !$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 /** Remove parameter from query string
* @param string * @param string
* @return string * @return string
@@ -563,21 +600,34 @@ function pagination($page, $current) {
*/ */
function get_file($key, $decompress = false) { function get_file($key, $decompress = false) {
$file = $_FILES[$key]; $file = $_FILES[$key];
if (!$file || $file["error"]) { if (!$file) {
return $file["error"]; return null;
} }
$return = file_get_contents($decompress && ereg('\\.gz$', $file["name"]) ? "compress.zlib://$file[tmp_name]" foreach ($file as $key => $val) {
: ($decompress && ereg('\\.bz2$', $file["name"]) ? "compress.bzip2://$file[tmp_name]" $file[$key] = (array) $val;
: $file["tmp_name"] }
)); //! may not be reachable because of open_basedir $return = '';
if ($decompress) { foreach ($file["error"] as $key => $error) {
$start = substr($return, 0, 3); if ($error) {
if (function_exists("iconv") && ereg("^\xFE\xFF|^\xFF\xFE", $start, $regs)) { // not ternary operator to save memory return $error;
$return = iconv("utf-16", "utf-8", $return);
} elseif ($start == "\xEF\xBB\xBF") { // UTF-8 BOM
$return = substr($return, 3);
} }
$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; return $return;
} }
@@ -657,6 +707,16 @@ function hidden_fields_get() {
echo '<input type="hidden" name="username" value="' . h($_GET["username"]) . '">'; echo '<input type="hidden" name="username" value="' . h($_GET["username"]) . '">';
} }
/** Get status of a single table and fall back to name on error
* @param string
* @param bool
* @return array
*/
function table_status1($table, $fast = false) {
$return = table_status($table, $fast);
return ($return ? $return : array("Name" => $table));
}
/** Find out foreign keys for each column /** Find out foreign keys for each column
* @param string * @param string
* @return array array($col => array()) * @return array array($col => array())
@@ -744,7 +804,7 @@ function input($field, $value, $function) {
} else { } else {
// int(3) is only a display hint // int(3) is only a display hint
$maxlength = (!ereg('int', $field["type"]) && preg_match('~^(\\d+)(,(\\d+))?$~', $field["length"], $match) ? ((ereg("binary", $field["type"]) ? 2 : 1) * $match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0)) : ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0)); $maxlength = (!ereg('int', $field["type"]) && preg_match('~^(\\d+)(,(\\d+))?$~', $field["length"], $match) ? ((ereg("binary", $field["type"]) ? 2 : 1) * $match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0)) : ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0));
if ($connection->server_info >= 5.6 && ereg('time', $field["type"])) { if ($jush == 'sql' && $connection->server_info >= 5.6 && ereg('time', $field["type"])) {
$maxlength += 7; // microtime $maxlength += 7; // microtime
} }
// type='date' and type='time' display localized value which may be confusing, type='datetime' uses 'T' as date and time separator // type='date' and type='time' display localized value which may be confusing, type='datetime' uses 'T' as date and time separator
@@ -803,7 +863,7 @@ function search_tables() {
$_GET["where"][0]["op"] = "LIKE %%"; $_GET["where"][0]["op"] = "LIKE %%";
$_GET["where"][0]["val"] = $_POST["query"]; $_GET["where"][0]["val"] = $_POST["query"];
$found = false; $found = false;
foreach (table_status() as $table => $table_status) { foreach (table_status('', true) as $table => $table_status) {
$name = $adminer->tableName($table_status); $name = $adminer->tableName($table_status);
if (isset($table_status["Engine"]) && $name != "" && (!$_POST["tables"] || in_array($table, $_POST["tables"]))) { 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)); $result = $connection->query("SELECT" . limit("1 FROM " . table($table), " WHERE " . implode(" AND ", $adminer->selectSearchProcess(fields($table), array())), 1));
@@ -834,6 +894,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" : "")); header("Content-Disposition: attachment; filename=" . $adminer->dumpFilename($identifier) . ".$return" . ($output != "file" && !ereg('[^0-9a-z]', $output) ? ".$output" : ""));
} }
session_write_close(); session_write_close();
ob_flush();
flush();
return $return; return $return;
} }
@@ -860,9 +922,10 @@ function apply_sql_function($function, $column) {
} }
/** Read password from file adminer.key in temporary directory or create one /** Read password from file adminer.key in temporary directory or create one
* @param bool
* @return string or false if the file can not be created * @return string or false if the file can not be created
*/ */
function password_file() { function password_file($create) {
$dir = ini_get("upload_tmp_dir"); // session_save_path() may contain other storage path $dir = ini_get("upload_tmp_dir"); // session_save_path() may contain other storage path
if (!$dir) { if (!$dir) {
if (function_exists('sys_get_temp_dir')) { if (function_exists('sys_get_temp_dir')) {
@@ -878,7 +941,7 @@ function password_file() {
} }
$filename = "$dir/adminer.key"; $filename = "$dir/adminer.key";
$return = @file_get_contents($filename); // @ - can not exist $return = @file_get_contents($filename); // @ - can not exist
if ($return) { if ($return || !$create) {
return $return; return $return;
} }
$fp = @fopen($filename, "w"); // @ - can have insufficient rights //! is not atomic $fp = @fopen($filename, "w"); // @ - can have insufficient rights //! is not atomic

View File

@@ -3,33 +3,34 @@
$langs = array( $langs = array(
'en' => 'English', // Jakub Vrána - http://www.vrana.cz 'en' => 'English', // Jakub Vrána - http://www.vrana.cz
'cs' => 'Čeština', // Jakub Vrána - http://www.vrana.cz 'ar' => 'العربية', // Y.M Amine - Algeria - nbr7@live.fr
'sk' => 'Slovenčina', // Ivan Suchy - http://www.ivansuchy.com, Juraj Krivda - http://www.jstudio.cz 'bn' => 'বাংলা', // Dipak Kumar - dipak.ndc@gmail.com
'nl' => 'Nederlands', // Maarten Balliauw - http://blog.maartenballiauw.be
'es' => 'Español', // Klemens Häckel - http://clickdimension.wordpress.com
'de' => 'Deutsch', // Klemens Häckel - http://clickdimension.wordpress.com
'fr' => 'Français', // Francis Gagné, Aurélien Royer
'it' => 'Italiano', // Alessandro Fiorotto, Paolo Asperti
'et' => 'Eesti', // Priit Kallas
'hu' => 'Magyar', // Borsos Szilárd (Borsosfi) - http://www.borsosfi.hu, info@borsosfi.hu
'pl' => 'Polski', // Radosław Kowalewski - http://srsbiz.pl/
'ca' => 'Català', // Joan Llosas 'ca' => 'Català', // Joan Llosas
'pt' => 'Português', // Gian Live - gian@live.com, Davi Alexandre davi@davialexandre.com.br 'cs' => 'Čeština', // Jakub Vrána - http://www.vrana.cz
'sl' => 'Slovenski', // Matej Ferlan - www.itdinamik.com, matej.ferlan@itdinamik.com 'de' => 'Deutsch', // Klemens Häckel - http://clickdimension.wordpress.com
'lt' => 'Lietuvių', // Paulius Leščinskas - http://www.lescinskas.lt 'es' => 'Español', // Klemens Häckel - http://clickdimension.wordpress.com
'tr' => 'Türkçe', // Bilgehan Korkmaz - turktron.com 'et' => 'Eesti', // Priit Kallas
'ro' => 'Limba Română', // .nick .messing - dot.nick.dot.messing@gmail.com 'fa' => 'فارسی', // mojtaba barghbani - Iran - mbarghbani@gmail.com
'fr' => 'Français', // Francis Gagné, Aurélien Royer
'hu' => 'Magyar', // Borsos Szilárd (Borsosfi) - http://www.borsosfi.hu, info@borsosfi.hu
'id' => 'Bahasa Indonesia', // Ivan Lanin - http://ivan.lanin.org 'id' => 'Bahasa Indonesia', // Ivan Lanin - http://ivan.lanin.org
'it' => 'Italiano', // Alessandro Fiorotto, Paolo Asperti
'ja' => '日本語', // Hitoshi Ozawa - http://sourceforge.jp/projects/oss-ja-jpn/releases/
'ko' => '한국어', // dalli - skcha67@gmail.com
'lt' => 'Lietuvių', // Paulius Leščinskas - http://www.lescinskas.lt
'nl' => 'Nederlands', // Maarten Balliauw - http://blog.maartenballiauw.be
'pl' => 'Polski', // Radosław Kowalewski - http://srsbiz.pl/
'pt' => 'Português', // Gian Live - gian@live.com, Davi Alexandre davi@davialexandre.com.br
'ro' => 'Limba Română', // .nick .messing - dot.nick.dot.messing@gmail.com
'ru' => 'Русский язык', // Maksim Izmaylov 'ru' => 'Русский язык', // Maksim Izmaylov
'uk' => 'Українська', // Valerii Kryzhov 'sk' => 'Slovenčina', // Ivan Suchy - http://www.ivansuchy.com, Juraj Krivda - http://www.jstudio.cz
'sl' => 'Slovenski', // Matej Ferlan - www.itdinamik.com, matej.ferlan@itdinamik.com
'sr' => 'Српски', // Nikola Radovanović - cobisimo@gmail.com 'sr' => 'Српски', // Nikola Radovanović - cobisimo@gmail.com
'ta' => 'த‌மிழ்', // G. Sampath Kumar, Chennai, India, sampathkumar11@gmail.com
'tr' => 'Türkçe', // Bilgehan Korkmaz - turktron.com
'uk' => 'Українська', // Valerii Kryzhov
'zh' => '简体中文', // Mr. Lodar 'zh' => '简体中文', // Mr. Lodar
'zh-tw' => '繁體中文', // http://tzangms.com 'zh-tw' => '繁體中文', // http://tzangms.com
'ja' => '日本語', // Hitoshi Ozawa - http://sourceforge.jp/projects/oss-ja-jpn/releases/
'ta' => 'த‌மிழ்', // G. Sampath Kumar, Chennai, India, sampathkumar11@gmail.com
'bn' => 'বাংলা', // Dipak Kumar - dipak.ndc@gmail.com
'ar' => 'العربية', // Y.M Amine - Algeria - nbr7@live.fr
'fa' => 'فارسی', // mojtaba barghbani - Iran - mbarghbani@gmail.com
); );
/** Get current language /** Get current language

View File

@@ -6,7 +6,7 @@ if (extension_loaded('pdo')) {
function __construct() { function __construct() {
global $adminer; global $adminer;
$pos = array_search("", $adminer->operators); $pos = array_search("SQL", $adminer->operators);
if ($pos !== false) { if ($pos !== false) {
unset($adminer->operators[$pos]); 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 <?php
$VERSION = "3.6.4"; $VERSION = "3.7.1";

View File

@@ -79,6 +79,9 @@ function decrypt_string($str, $key) {
if ($str == "") { if ($str == "") {
return ""; return "";
} }
if (!$key) {
return false;
}
$key = array_values(unpack("V*", pack("H*", md5($key)))); $key = array_values(unpack("V*", pack("H*", md5($key))));
$v = str2long($str, false); $v = str2long($str, false);
$n = count($v) - 1; $n = count($v) - 1;

View File

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

View File

@@ -1,7 +1,7 @@
<?php <?php
$TABLE = $_GET["indexes"]; $TABLE = $_GET["indexes"];
$index_types = array("PRIMARY", "UNIQUE", "INDEX"); $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"])) { if (eregi("MyISAM|M?aria" . ($connection->server_info >= 5.6 ? "|InnoDB" : ""), $table_status["Engine"])) {
$index_types[] = "FULLTEXT"; $index_types[] = "FULLTEXT";
} }
@@ -10,29 +10,40 @@ if ($jush == "sqlite") { // doesn't support primary key
unset($index_types[0]); unset($index_types[0]);
unset($indexes[""]); unset($indexes[""]);
} }
$row = $_POST;
if ($_POST && !$error && !$_POST["add"]) { if ($_POST && !$error && !$_POST["add"]) {
$alter = array(); $alter = array();
foreach ($_POST["indexes"] as $index) { foreach ($row["indexes"] as $index) {
$name = $index["name"]; $name = $index["name"];
if (in_array($index["type"], $index_types)) { if (in_array($index["type"], $index_types)) {
$columns = array(); $columns = array();
$lengths = array(); $lengths = array();
$descs = array();
$set = array(); $set = array();
ksort($index["columns"]); ksort($index["columns"]);
foreach ($index["columns"] as $key => $column) { foreach ($index["columns"] as $key => $column) {
if ($column != "") { if ($column != "") {
$length = $index["lengths"][$key]; $length = $index["lengths"][$key];
$set[] = idf_escape($column) . ($length ? "(" . (+$length) . ")" : ""); $desc = $index["descs"][$key];
$set[] = idf_escape($column) . ($length ? "(" . (+$length) . ")" : "") . ($desc ? " DESC" : "");
$columns[] = $column; $columns[] = $column;
$lengths[] = ($length ? $length : null); $lengths[] = ($length ? $length : null);
$descs[] = $desc;
} }
} }
if ($columns) { if ($columns) {
$existing = $indexes[$name]; $existing = $indexes[$name];
if ($existing) { if ($existing) {
ksort($existing["columns"]); ksort($existing["columns"]);
ksort($existing["lengths"]); ksort($existing["lengths"]);
if ($index["type"] == $existing["type"] && array_values($existing["columns"]) === $columns && (!$existing["lengths"] || array_values($existing["lengths"]) === $lengths)) { ksort($existing["descs"]);
if ($index["type"] == $existing["type"]
&& array_values($existing["columns"]) === $columns
&& (!$existing["lengths"] || array_values($existing["lengths"]) === $lengths)
&& array_values($existing["descs"]) === $descs
) {
// skip existing index // skip existing index
unset($indexes[$name]); unset($indexes[$name]);
continue; continue;
@@ -42,6 +53,7 @@ if ($_POST && !$error && !$_POST["add"]) {
} }
} }
} }
// drop removed indexes // drop removed indexes
foreach ($indexes as $name => $existing) { foreach ($indexes as $name => $existing) {
$alter[] = array($existing["type"], $name, "DROP"); $alter[] = array($existing["type"], $name, "DROP");
@@ -55,26 +67,28 @@ if ($_POST && !$error && !$_POST["add"]) {
page_header(lang('Indexes'), $error, array("table" => $TABLE), $TABLE); page_header(lang('Indexes'), $error, array("table" => $TABLE), $TABLE);
$fields = array_keys(fields($TABLE)); $fields = array_keys(fields($TABLE));
$row = array("indexes" => $indexes); if ($_POST["add"]) {
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 {
foreach ($row["indexes"] as $key => $index) { foreach ($row["indexes"] as $key => $index) {
$row["indexes"][$key]["name"] = $key; if ($index["columns"][count($index["columns"])] != "") {
$row["indexes"][$key]["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')
|| array_filter($index["descs"])
) {
$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 +100,16 @@ $j = 1;
foreach ($row["indexes"] as $index) { 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>"; 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"]); ksort($index["columns"]);
$i = 1; $i = 1;
foreach ($index["columns"] as $key => $column) { 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 "<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 echo ($jush == "sql" || $jush == "mssql" ? "<input type='number' name='indexes[$j][lengths][$i]' class='size' value='" . h($index["lengths"][$key]) . "'>" : "");
echo ($jush != "sql" ? checkbox("indexes[$j][descs][$i]", 1, $index["descs"][$key], lang('descending')) : "");
echo " </span>";
$i++; $i++;
} }
echo "<td><input name='indexes[$j][name]' value='" . h($index["name"]) . "' autocapitalize='off'>\n"; echo "<td><input name='indexes[$j][name]' value='" . h($index["name"]) . "' autocapitalize='off'>\n";
$j++; $j++;
} }

View File

@@ -11,6 +11,7 @@ $translations = array(
'Logged as: %s' => 'Přihlášen jako: %s', 'Logged as: %s' => 'Přihlášen jako: %s',
'Logout successful.' => 'Odhlášení proběhlo v pořádku.', 'Logout successful.' => 'Odhlášení proběhlo v pořádku.',
'Invalid credentials.' => 'Neplatné přihlašovací údaje.', 'Invalid credentials.' => 'Neplatné přihlašovací údaje.',
'Master password expired. <a href="http://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'Platnost hlavního hesla vypršela. <a href="http://www.adminer.org/cs/extension/" target="_blank">Implementujte</a> metodu %s, aby platilo stále.',
'Language' => 'Jazyk', 'Language' => 'Jazyk',
'Invalid CSRF token. Send the form again.' => 'Neplatný token CSRF. Odešlete formulář znovu.', 'Invalid CSRF token. Send the form again.' => 'Neplatný token CSRF. Odešlete formulář znovu.',
'No extension' => 'Žádné rozšíření', 'No extension' => 'Žádné rozšíření',
@@ -64,6 +65,7 @@ $translations = array(
'Unable to upload a file.' => 'Nepodařilo se nahrát soubor.', 'Unable to upload a file.' => 'Nepodařilo se nahrát soubor.',
'Maximum allowed file size is %sB.' => 'Maximální povolená velikost souboru je %sB.', 'Maximum allowed file size is %sB.' => 'Maximální povolená velikost souboru je %sB.',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Příliš velká POST data. Zmenšete data nebo zvyšte hodnotu konfigurační direktivy %s.', 'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Příliš velká POST data. Zmenšete data nebo zvyšte hodnotu konfigurační direktivy %s.',
'You can upload a big SQL file via FTP and import it from server.' => 'Velký SQL soubor můžete nahrát pomocí FTP a importovat ho ze serveru.',
'Export' => 'Export', 'Export' => 'Export',
'Dump' => 'Export', 'Dump' => 'Export',
@@ -240,6 +242,7 @@ $translations = array(
'Import' => 'Import', 'Import' => 'Import',
'%d row(s) have been imported.' => array('Byl importován %d záznam.', 'Byly importovány %d záznamy.', 'Bylo importováno %d záznamů.'), '%d row(s) have been imported.' => array('Byl importován %d záznam.', 'Byly importovány %d záznamy.', 'Bylo importováno %d záznamů.'),
'File must be in UTF-8 encoding.' => 'Soubor musí být v kódování UTF-8.',
// in-place editing in select // in-place editing in select
'Ctrl+click on a value to modify it.' => 'Ctrl+klikněte na políčko, které chcete změnit.', 'Ctrl+click on a value to modify it.' => 'Ctrl+klikněte na políčko, které chcete změnit.',

270
adminer/lang/ko.inc.php Normal file
View File

@@ -0,0 +1,270 @@
<?php
$translations = array(
'Login' => '로그인',
'Logout successful.' => '로그아웃',
'Invalid credentials.' => '잘못된 로그인',
'Server' => '서버',
'Username' => '사용자이름',
'Password' => '비밀번호',
'Select database' => '데이터베이스를 선택하십시오.',
'Invalid database.' => '잘못된 데이터베이스입니다.',
'Create new database' => '새 데이터베이스 만들기',
'Table has been dropped.' => '테이블을 삭제했습니다.',
'Table has been altered.' => '테이블을 변경했습니다.',
'Table has been created.' => '테이블을 만들었습니다.',
'Alter table' => '테이블 변경',
'Create table' => '테이블 만들기',
'Table name' => '테이블 이름',
'engine' => '엔진',
'collation' => '정렬',
'Column name' => '열 이름',
'Type' => '형',
'Length' => '길이',
'Auto Increment' => '자동증가',
'Options' => '설정',
'Save' => '저장',
'Drop' => '삭제',
'Database has been dropped.' => '데이터베이스를 삭제했습니다.',
'Database has been created.' => '데이터베이스를 만들었습니다.',
'Database has been renamed.' => '데이터베이스의 이름을 바꾸었습니다.',
'Database has been altered.' => '데이터베이스를 변경했습니다.',
'Alter database' => '데이터베이스 변경',
'Create database' => '데이터베이스 만들기',
'SQL command' => 'SQL 명령',
'Dump' => '덤프',
'Logout' => '로그아웃',
'database' => '데이터베이스',
'Use' => '사용',
'No tables.' => '테이블이 없습니다.',
'select' => '선택',
'Create new table' => '테이블 만들기',
'Item has been deleted.' => '항목을 삭제했습니다.',
'Item has been updated.' => '항목을 갱신했습니다.',
'Edit' => '편집',
'Insert' => '삽입',
'Save and insert next' => '저장하고 다음에 추가',
'Delete' => '삭제',
'Database' => '데이터베이스',
'Routines' => '루틴',
'Indexes have been altered.' => '인덱스를 변경했습니다.',
'Indexes' => '색인',
'Alter indexes' => '인덱스 변경',
'Add next' => '추가',
'Language' => '언어',
'Select' => '선택',
'New item' => '항목 만들기',
'Search' => '검색',
'Sort' => '정렬',
'descending' => '역순',
'Limit' => '제약',
'No rows.' => '행이 없습니다.',
'Action' => '실행',
'edit' => '편집',
'Page' => '페이지',
'Query executed OK, %d row(s) affected.' => '쿼리를 실행했습니다. %d 행을 변경했습니다.',
'Error in query' => '쿼리의 오류',
'Execute' => '실행',
'Table' => '테이블',
'Foreign keys' => '외부 키',
'Triggers' => '트리거',
'View' => '보기',
'Unable to select the table' => '테이블을 선택할 수 없습니다.',
'Invalid CSRF token. Send the form again.' => '잘못된 CSRF 토큰. 다시 보내주십시오.',
'Comment' => '코멘트',
'Default values' => '기본값',
'%d byte(s)' => '%d 바이트',
'No commands to execute.' => '실행할 수 있는 명령이 없습니다.',
'Unable to upload a file.' => '파일을 업로드 할 수 없습니다.',
'File upload' => '파일 올리기',
'File uploads are disabled.' => '파일 업로드가 잘못되었습니다.',
'Routine has been called, %d row(s) affected.' => '루틴을 호출했습니다. %d 행을 변경했습니다.',
'Call' => '외침',
'No extension' => '확장 기능이 없습니다.',
'None of the supported PHP extensions (%s) are available.' => 'PHP 확장 (%s)가 설치되어 있지 않습니다.',
'Session support must be enabled.' => '세션을 사용하십시오.',
'Session expired, please login again.' => '세션 만료. 다시 로그인하십시오.',
'Text length' => '문자열의 길이',
'Foreign key has been dropped.' => '외부 키를 제거했습니다.',
'Foreign key has been altered.' => '외부 키를 변경했습니다.',
'Foreign key has been created.' => '외부 키를 만들었습니다.',
'Foreign key' => '외부 키',
'Target table' => '테이블',
'Change' => '변경',
'Source' => '소스',
'Target' => '타겟',
'Add column' => '열 추가',
'Alter' => '변경',
'Add foreign key' => '외부 키를 추가',
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Index Type' => '인덱스 형',
'Column (length)' => '열 (길이)',
'View has been dropped.' => '보기를 삭제했습니다.',
'View has been altered.' => '보기를 변경했습니다.',
'View has been created.' => '보기를 만들었습니다.',
'Alter view' => '보기 변경',
'Create view' => '뷰 만들기',
'Name' => '이름',
'Process list' => '프로세스 목록',
'%d process(es) have been killed.' => '%d 프로세스를 강제 종료되었습니다.',
'Kill' => '강제 종료',
'Parameter name' => '참조 여명',
'Database schema' => '구조',
'Create procedure' => '시저 만들기',
'Create function' => '함수 만들기',
'Routine has been dropped.' => '루틴 만들기',
'Routine has been altered.' => '루틴 변경',
'Routine has been created.' => '루틴 만들기',
'Alter function' => '함수의 변경',
'Alter procedure' => '시저 변경',
'Return type' => '반환 형식',
'Add trigger' => '트리거 추가',
'Trigger has been dropped.' => '트리거를 제거했습니다.',
'Trigger has been altered.' => '트리거를 변경했습니다.',
'Trigger has been created.' => '트리거를 추가했습니다.',
'Alter trigger' => '트리거 변경',
'Create trigger' => '트리거 만들기',
'Time' => '시간',
'Event' => '이벤트',
'%s version: %s through PHP extension %s' => '%s 버전 %s, PHP 확장 %s',
'%d row(s)' => '%d 행',
'Remove' => '제외',
'Are you sure?' => '실행 하시겠습니까?',
'Privileges' => '권한',
'Create user' => '사용자 만들기',
'User has been dropped.' => '사용자 삭제',
'User has been altered.' => '사용자 변경',
'User has been created.' => '사용자 만들기',
'Hashed' => 'Hashed',
'Column' => '열',
'Routine' => '루틴',
'Grant' => '권한 부여',
'Revoke' => '권한 취소',
'Logged as: %s' => '로그 : %s',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'POST 데이터가 너무 큽니다. 데이터 크기를 줄이거나 %s 설정을 늘리십시오.',
'Move up' => '상',
'Move down' => '아래',
'Export' => '내보내기',
'Tables' => '테이블',
'Data' => '데이터',
'Output' => '출력',
'open' => '열',
'save' => '저장',
'Format' => '형식',
'Functions' => '함수',
'Aggregation' => '집합',
'Event has been dropped.' => '삭제했습니다.',
'Event has been altered.' => '변경했습니다.',
'Event has been created.' => '만들었습니다.',
'Alter event' => '변경',
'Create event' => '만들기',
'Start' => '시작',
'End' => '종료',
'Every' => '매번',
'Status' => '상태',
'On completion preserve' => '완성 후 저장',
'Events' => '이벤트',
'Schedule' => '일정',
'At given time' => '지정 시간',
'Tables have been truncated.' => '테이블을 truncate했습니다.',
'Tables have been moved.' => '테이블을 옮겼습니다.',
'Tables and views' => '테이블과 뷰',
'Engine' => '엔진',
'Collation' => '정렬',
'Data Length' => '데이터 길이',
'Index Length' => '인덱스 길이',
'Data Free' => '여유',
'Rows' => '행',
',' => ',',
'Analyze' => '분석',
'Optimize' => '최적화',
'Check' => '확인',
'Repair' => '복구',
'Truncate' => 'Truncate',
'Move to other database' => '다른 데이터베이스로 이동',
'Move' => '이동',
'Save and continue edit' => '저장하고 계속',
'original' => '원래',
'%d item(s) have been affected.' => '%d를 갱신했습니다.',
'whole result' => '모든 결과',
'Tables have been dropped.' => '테이블을 삭제했습니다.',
'Clone' => '복제',
'Maximum number of allowed fields exceeded. Please increase %s.' => '정의 가능한 최대 필드 수를 초과했습니다. %s를 늘리십시오.',
'Partition by' => '파티션',
'Partitions' => '파티션',
'Partition name' => '파티션 이름',
'Values' => '값',
'%d row(s) have been imported.' => '%d 행을 가져 왔습니다.',
'Show structure' => '구조',
'anywhere' => '모든',
'Import' => '가져 오기',
'Stop on error' => '오류의 경우 중지',
'Select data' => '데이터',
'%.3f s' => '%.3f 초',
'$1-$3-$5' => '$1-$3-$5',
'[yyyy]-mm-dd' => '[yyyy]-mm-dd',
'History' => '역사',
'Variables' => '변수',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => '원본 및 대상 열은 동일한 데이터 형식이어야합니다. 목표 컬럼에 인덱스와 데이터가 존재해야합니다.',
'Relations' => '관계',
'Run file' => '파일을 실행',
'Clear' => '삭제',
'Maximum allowed file size is %sB.' => '파일의 최대 크기 %sB',
'Numbers' => '숫자',
'Date and time' => '시간',
'Strings' => '문자열',
'Binary' => '이진',
'Lists' => '목록',
'Editor' => '에디터',
'E-mail' => '메일',
'From' => '보낸 사람',
'Subject' => '제목',
'Send' => '보내기',
'%d e-mail(s) have been sent.' => '%d 메일을 보냈습니다.',
'Webserver file %s' => 'Web 서버 파일 %s',
'File does not exist.' => '파일이 존재하지 않습니다.',
'%d in total' => '총 %d',
'Permanent login' => '영구적으로 로그인',
'Databases have been dropped.' => '데이터베이스를 삭제했습니다.',
'Search data in tables' => '데이터 검색',
'schema' => '스키마',
'Schema' => '스키마',
'Alter schema' => '스키마 변경',
'Create schema' => '스키마 추가',
'Schema has been dropped.' => '스키마를 삭제했습니다.',
'Schema has been created.' => '스키마를 추가했습니다.',
'Schema has been altered.' => '스키마를 변경했습니다.',
'Sequences' => '시퀀스',
'Create sequence' => '시퀀스 만들기',
'Alter sequence' => '순서 변경',
'Sequence has been dropped.' => '시퀀스를 제거했습니다.',
'Sequence has been created.' => '시퀀스를 추가했습니다.',
'Sequence has been altered.' => '순서를 변경했습니다.',
'User types' => '사용자 정의 형',
'Create type' => '사용자 정의 형식 만들기',
'Alter type' => '사용자 정의 형식 변경',
'Type has been dropped.' => '사용자 정의 형식을 삭제했습니다.',
'Type has been created.' => '사용자 정의 형식을 추가했습니다.',
'Use edit link to modify this value.' => '링크 편집',
'last' => '마지막',
'From server' => '서버에서 실행',
'System' => '데이터베이스 형식',
'empty' => '하늘',
'Network' => '네트워크 형',
'Geometry' => '기하 형',
'File exists.' => '파일이 이미 있습니다.',
'Attachments' => '첨부 파일',
'Item%s has been inserted.' => '%s 항목을 삽입했습니다.',
'now' => '현재 시간',
'%d query(s) executed OK.' => '%d 쿼리를 실행했습니다.',
'Show only errors' => '오류 만 표시',
'Refresh' => '새로 고침',
'Invalid schema.' => '잘못된 스키마',
'Please use one of the extensions %s.' => '하나의 확장 기능을 사용하십시오 %s',
'ltr' => 'ltr',
'Tables have been copied.' => '테이블을 복사했습니다',
'Copy' => '복사',
'Permanent link' => '영구 링크',
'Edit all' => '모든 편집',
'HH:MM:SS' => '시:분:초',
);

View File

@@ -11,6 +11,7 @@ $translations = array(
'Logged as: %s' => 'xx', 'Logged as: %s' => 'xx',
'Logout successful.' => 'xx', 'Logout successful.' => 'xx',
'Invalid credentials.' => 'xx', 'Invalid credentials.' => 'xx',
'Master password expired. <a href="http://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'xx',
'Language' => 'xx', 'Language' => 'xx',
'Invalid CSRF token. Send the form again.' => 'xx', 'Invalid CSRF token. Send the form again.' => 'xx',
'No extension' => 'xx', 'No extension' => 'xx',
@@ -64,6 +65,7 @@ $translations = array(
'Unable to upload a file.' => 'xx', 'Unable to upload a file.' => 'xx',
'Maximum allowed file size is %sB.' => 'xx', 'Maximum allowed file size is %sB.' => 'xx',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'xx', 'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'xx',
'You can upload a big SQL file via FTP and import it from server.' => 'xx',
'Export' => 'xx', 'Export' => 'xx',
'Dump' => 'xx', 'Dump' => 'xx',
@@ -240,6 +242,7 @@ $translations = array(
'Import' => 'xx', 'Import' => 'xx',
'%d row(s) have been imported.' => array('xx', 'xx'), '%d row(s) have been imported.' => array('xx', 'xx'),
'File must be in UTF-8 encoding.' => 'xx',
// in-place editing in select // in-place editing in select
'Ctrl+click on a value to modify it.' => 'xx', 'Ctrl+click on a value to modify it.' => 'xx',

View File

@@ -12,6 +12,7 @@ function adminer_object() {
// specify enabled plugins here // specify enabled plugins here
new AdminerDatabaseHide(array('information_schema')), new AdminerDatabaseHide(array('information_schema')),
new AdminerDumpJson, new AdminerDumpJson,
new AdminerDumpBz2,
new AdminerDumpZip, new AdminerDumpZip,
new AdminerDumpXml, new AdminerDumpXml,
new AdminerDumpAlter, new AdminerDumpAlter,

View File

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

View File

@@ -1,32 +1,36 @@
<?php <?php
$PROCEDURE = $_GET["procedure"]; $PROCEDURE = $_GET["procedure"];
$routine = (isset($_GET["function"]) ? "FUNCTION" : "PROCEDURE"); $routine = (isset($_GET["function"]) ? "FUNCTION" : "PROCEDURE");
$routine_languages = routine_languages(); $row = $_POST;
$row = ($PROCEDURE == "" ? array("fields" => array()) : routine($PROCEDURE, $routine)); $row["fields"] = (array) $row["fields"];
$row["name"] = $PROCEDURE;
if ($_POST) { if ($_POST && !process_fields($row["fields"]) && !$error) {
if (!$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"] && !$_POST["down"]) { $temp_name = "$row[name]_adminer_" . uniqid();
drop_create( drop_create(
"DROP $routine " . idf_escape($PROCEDURE), "DROP $routine " . idf_escape($PROCEDURE),
create_routine($routine, $_POST), create_routine($routine, $row),
create_routine($routine, $row), "DROP $routine " . idf_escape($row["name"]),
substr(ME, 0, -1), create_routine($routine, array("name" => $temp_name) + $row),
lang('Routine has been dropped.'), "DROP $routine " . idf_escape($temp_name),
lang('Routine has been altered.'), substr(ME, 0, -1),
lang('Routine has been created.'), lang('Routine has been dropped.'),
$PROCEDURE lang('Routine has been altered.'),
); lang('Routine has been created.'),
} $PROCEDURE,
$row = $_POST; $row["name"]
$row["fields"] = (array) $row["fields"]; );
process_fields($row["fields"]);
} }
page_header(($PROCEDURE != "" ? (isset($_GET["function"]) ? lang('Alter function') : lang('Alter procedure')) . ": " . h($PROCEDURE) : (isset($_GET["function"]) ? lang('Create function') : lang('Create procedure'))), $error); 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"); $collations = get_vals("SHOW CHARACTER SET");
sort($collations); sort($collations);
$routine_languages = routine_languages();
?> ?>
<form action="" method="post" id="form"> <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 // HTML valid because there is always at least one process
$i = -1; $i = -1;
foreach (process_list() as $i => $row) { foreach (process_list() as $i => $row) {
if (!$i) { if (!$i) {
echo "<thead><tr lang='en'>" . (support("kill") ? "<th>&nbsp;" : ""); echo "<thead><tr lang='en'>" . (support("kill") ? "<th>&nbsp;" : "");
foreach ($row as $key => $val) { 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>" ? "<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 : $key
); );
} }
echo "</thead>\n"; echo "</thead>\n";
} }
echo "<tr" . odd() . ">" . (support("kill") ? "<td>" . checkbox("kill[]", $row["Id"], 0) : ""); echo "<tr" . odd() . ">" . (support("kill") ? "<td>" . checkbox("kill[]", $row["Id"], 0) : "");
foreach ($row as $key => $val) { foreach ($row as $key => $val) {
echo "<td>" . ( 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)))) $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)) $referenced = array(); // target_table => array(table => array(left => target_column))
$lefts = array(); // float => bool $lefts = array(); // float => bool
foreach (table_status() as $table_status) { foreach (table_status('', true) as $table => $table_status) {
if (!isset($table_status["Engine"])) { // view if (is_view($table_status)) {
continue; continue;
} }
$pos = 0; $pos = 0;
$schema[$table_status["Name"]]["fields"] = array(); $schema[$table]["fields"] = array();
foreach (fields($table_status["Name"]) as $name => $field) { foreach (fields($table) as $name => $field) {
$pos += 1.25; $pos += 1.25;
$field["pos"] = $pos; $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)); $schema[$table]["pos"] = ($table_pos[$table] ? $table_pos[$table] : array($top, 0));
foreach ($adminer->foreignKeys($table_status["Name"]) as $val) { foreach ($adminer->foreignKeys($table) as $val) {
if (!$val["db"]) { if (!$val["db"]) {
$left = $base_left; $left = $base_left;
if ($table_pos[$table_status["Name"]][1] || $table_pos[$val["table"]][1]) { if ($table_pos[$table][1] || $table_pos[$val["table"]][1]) {
$left = min(floatval($table_pos[$table_status["Name"]][1]), floatval($table_pos[$val["table"]][1])) - 1; $left = min(floatval($table_pos[$table][1]), floatval($table_pos[$val["table"]][1])) - 1;
} else { } else {
$base_left -= .1; $base_left -= .1;
} }
@@ -40,12 +40,12 @@ foreach (table_status() as $table_status) {
// find free $left // find free $left
$left -= .0001; $left -= .0001;
} }
$schema[$table_status["Name"]]["references"][$val["table"]][(string) $left] = array($val["source"], $val["target"]); $schema[$table]["references"][$val["table"]][(string) $left] = array($val["source"], $val["target"]);
$referenced[$val["table"]][$table_status["Name"]][(string) $left] = $val["target"]; $referenced[$val["table"]][$table][(string) $left] = $val["target"];
$lefts[(string) $left] = true; $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) { 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 "<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>"; echo '<a href="' . h(ME) . 'table=' . urlencode($name) . '"><b>' . h($name) . "</b></a>";
foreach ($table["fields"] as $field) { foreach ($table["fields"] as $field) {
$val = '<span' . type_class($field["type"]) . ' title="' . h($field["full_type"] . ($field["null"] ? " NULL" : '')) . '">' . h($field["field"]) . '</span>'; $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); echo "<br>" . ($field["primary"] ? "<i>$val</i>" : $val);
} }
foreach ((array) $table["references"] as $target_name => $refs) { foreach ((array) $table["references"] as $target_name => $refs) {
foreach ($refs as $left => $ref) { foreach ($refs as $left => $ref) {
$left1 = $left - $table_pos[$name][1]; $left1 = $left - $table_pos[$name][1];
@@ -75,6 +77,7 @@ foreach ($schema as $name => $table) {
} }
} }
} }
foreach ((array) $referenced[$name] as $target_name => $refs) { foreach ((array) $referenced[$name] as $target_name => $refs) {
foreach ($refs as $left => $columns) { foreach ($refs as $left => $columns) {
$left1 = $left - $table_pos[$name][1]; $left1 = $left - $table_pos[$name][1];
@@ -84,8 +87,10 @@ foreach ($schema as $name => $table) {
} }
} }
} }
echo "\n</div>\n"; echo "\n</div>\n";
} }
foreach ($schema as $name => $table) { foreach ($schema as $name => $table) {
foreach ((array) $table["references"] as $target_name => $refs) { foreach ((array) $table["references"] as $target_name => $refs) {
foreach ($refs as $left => $ref) { foreach ($refs as $left => $ref) {

View File

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

View File

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

View File

@@ -1,11 +1,11 @@
<?php <?php
$TABLE = $_GET["select"]; $TABLE = $_GET["select"];
$table_status = table_status($TABLE); $table_status = table_status1($TABLE);
$indexes = indexes($TABLE); $indexes = indexes($TABLE);
$fields = fields($TABLE); $fields = fields($TABLE);
$foreign_keys = column_foreign_keys($TABLE); $foreign_keys = column_foreign_keys($TABLE);
$oid = ""; $oid = "";
if ($table_status["Oid"] == "t") { if ($table_status["Oid"]) {
$oid = ($jush == "sqlite" ? "rowid" : "oid"); $oid = ($jush == "sqlite" ? "rowid" : "oid");
$indexes[] = array("type" => "PRIMARY", "columns" => array($oid)); $indexes[] = array("type" => "PRIMARY", "columns" => array($oid));
} }
@@ -17,7 +17,7 @@ $text_length = null;
foreach ($fields as $key => $field) { foreach ($fields as $key => $field) {
$name = $adminer->fieldName($field); $name = $adminer->fieldName($field);
if (isset($field["privileges"]["select"]) && $name != "") { 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)) { if (is_shortable($field)) {
$text_length = $adminer->selectLengthProcess(); $text_length = $adminer->selectLengthProcess();
} }
@@ -30,32 +30,26 @@ $is_group = count($group) < count($select);
$where = $adminer->selectSearchProcess($fields, $indexes); $where = $adminer->selectSearchProcess($fields, $indexes);
$order = $adminer->selectOrderProcess($fields, $indexes); $order = $adminer->selectOrderProcess($fields, $indexes);
$limit = $adminer->selectLimitProcess(); $limit = $adminer->selectLimitProcess();
$from = ($select ? implode(", ", $select) : "*" . ($oid ? ", $oid" : "")); $from = ($select ? implode(", ", $select) : "*" . ($oid ? ", $oid" : ""))
if ($jush == "sql") { . convert_fields($columns, $fields, $select)
foreach ($columns as $key => $val) { . "\nFROM " . table($TABLE);
if ($select && !$select[$key]) {
continue;
}
$as = convert_field($fields[$key]);
if ($as) {
$from .= ", $as AS " . idf_escape($key);
}
}
}
$from .= "\nFROM " . table($TABLE);
$group_by = ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : ""); $group_by = ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : "");
if ($_GET["val"] && is_ajax()) { if ($_GET["val"] && is_ajax()) {
header("Content-Type: text/plain; charset=utf-8"); header("Content-Type: text/plain; charset=utf-8");
foreach ($_GET["val"] as $unique_idf => $row) { foreach ($_GET["val"] as $unique_idf => $row) {
$as = convert_field($fields[key($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; exit;
} }
if ($_POST && !$error) { 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; $primary = $unselected = null;
foreach ($indexes as $index) { foreach ($indexes as $index) {
if ($index["type"] == "PRIMARY") { if ($index["type"] == "PRIMARY") {
@@ -69,16 +63,13 @@ if ($_POST && !$error) {
unset($unselected[$key]); unset($unselected[$key]);
} }
} }
if ($_POST["export"]) { if ($_POST["export"]) {
cookie("adminer_import", "output=" . urlencode($_POST["output"]) . "&format=" . urlencode($_POST["format"])); cookie("adminer_import", "output=" . urlencode($_POST["output"]) . "&format=" . urlencode($_POST["format"]));
dump_headers($TABLE); dump_headers($TABLE);
$adminer->dumpTable($TABLE, ""); $adminer->dumpTable($TABLE, "");
if (!is_array($_POST["check"]) || $unselected === array()) { if (!is_array($_POST["check"]) || $unselected === array()) {
$where2 = $where; $query = "SELECT $from$where_check$group_by";
if (is_array($_POST["check"])) {
$where2[] = "($where_check)";
}
$query = "SELECT $from" . ($where2 ? "\nWHERE " . implode(" AND ", $where2) : "") . $group_by;
} else { } else {
$union = array(); $union = array();
foreach ($_POST["check"] as $val) { foreach ($_POST["check"] as $val) {
@@ -90,6 +81,7 @@ if ($_POST && !$error) {
$adminer->dumpData($TABLE, "table", $query); $adminer->dumpData($TABLE, "table", $query);
exit; exit;
} }
if (!$adminer->selectEmailProcess($where, $foreign_keys)) { if (!$adminer->selectEmailProcess($where, $foreign_keys)) {
if ($_POST["save"] || $_POST["delete"]) { // edit if ($_POST["save"] || $_POST["delete"]) { // edit
$result = true; $result = true;
@@ -119,13 +111,13 @@ if ($_POST && !$error) {
$command = "INSERT"; $command = "INSERT";
$query = "INTO $query"; $query = "INTO $query";
} }
if ($_POST["all"] || ($unselected === array() && $_POST["check"]) || $is_group) { if ($_POST["all"] || ($unselected === array() && is_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; $affected = $connection->affected_rows;
} else { } else {
foreach ((array) $_POST["check"] as $val) { foreach ((array) $_POST["check"] as $val) {
// where is not unique so OR can't be used // 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) { if (!$result) {
break; break;
} }
@@ -142,6 +134,7 @@ if ($_POST && !$error) {
} }
queries_redirect(remove_from_uri($_POST["all"] && $_POST["delete"] ? "page" : ""), $message, $result); queries_redirect(remove_from_uri($_POST["all"] && $_POST["delete"] ? "page" : ""), $message, $result);
//! display edit page in case of an error //! display edit page in case of an error
} elseif (!$_POST["import"]) { // modify } elseif (!$_POST["import"]) { // modify
if (!$_POST["val"]) { if (!$_POST["val"]) {
$error = lang('Ctrl+click on a value to modify it.'); $error = lang('Ctrl+click on a value to modify it.');
@@ -156,7 +149,7 @@ if ($_POST && !$error) {
} }
$query = table($TABLE) . " SET " . implode(", ", $set); $query = table($TABLE) . " SET " . implode(", ", $set);
$where2 = " WHERE " . where_check($unique_idf, $fields) . ($where ? " AND " . implode(" AND ", $where) : ""); $where2 = " WHERE " . where_check($unique_idf, $fields) . ($where ? " AND " . implode(" AND ", $where) : "");
$result = queries("UPDATE" . ($is_group ? " $query$where2" : limit1($query, $where2))); // can change row on a different page without unique key $result = queries("UPDATE" . ($is_group || $unselected === array() ? " $query$where2" : limit1($query, $where2))); // can change row on a different page without unique key
if (!$result) { if (!$result) {
break; break;
} }
@@ -164,8 +157,12 @@ if ($_POST && !$error) {
} }
queries_redirect(remove_from_uri(), lang('%d item(s) have been affected.', $affected), $result); 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 } elseif (!is_string($file = get_file("csv_file", true))) {
$error = upload_error($file);
} elseif (!preg_match('~~u', $file)) {
$error = lang('File must be in UTF-8 encoding.');
} else {
cookie("adminer_import", "output=" . urlencode($adminer_import["output"]) . "&format=" . urlencode($_POST["separator"])); cookie("adminer_import", "output=" . urlencode($adminer_import["output"]) . "&format=" . urlencode($_POST["separator"]));
$result = true; $result = true;
$cols = array_keys($fields); $cols = array_keys($fields);
@@ -195,8 +192,7 @@ if ($_POST && !$error) {
} }
queries_redirect(remove_from_uri("page"), lang('%d row(s) have been imported.', $affected), $result); queries_redirect(remove_from_uri("page"), lang('%d row(s) have been imported.', $affected), $result);
queries("ROLLBACK"); // after queries_redirect() to not overwrite error queries("ROLLBACK"); // after queries_redirect() to not overwrite error
} else {
$error = upload_error($file);
} }
} }
} }
@@ -316,6 +312,7 @@ if (!$columns) {
next($select); next($select);
} }
} }
$lengths = array(); $lengths = array();
if ($_GET["modify"]) { if ($_GET["modify"]) {
foreach ($rows as $row) { foreach ($rows as $row) {
@@ -324,15 +321,26 @@ if (!$columns) {
} }
} }
} }
echo ($backward_keys ? "<th>" . lang('Relations') : "") . "</thead>\n"; echo ($backward_keys ? "<th>" . lang('Relations') : "") . "</thead>\n";
if (is_ajax()) { if (is_ajax()) {
if ($limit % 2 == 1 && $page % 2 == 1) { if ($limit % 2 == 1 && $page % 2 == 1) {
odd(); odd();
} }
ob_end_clean(); ob_end_clean();
} }
foreach ($adminer->rowDescriptions($rows, $foreign_keys) as $n => $row) { foreach ($adminer->rowDescriptions($rows, $foreign_keys) as $n => $row) {
$unique_array = unique_array($rows[$n], $indexes); $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 = ""; $unique_idf = "";
foreach ($unique_array as $key => $val) { foreach ($unique_array as $key => $val) {
if (strlen($val) > 64) { if (strlen($val) > 64) {
@@ -342,12 +350,14 @@ if (!$columns) {
$unique_idf .= "&" . ($val !== null ? urlencode("where[" . bracket_escape($key) . "]") . "=" . urlencode($val) : "null%5B%5D=" . urlencode($key)); $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>")); 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) { foreach ($row as $key => $val) {
if (isset($names[$key])) { if (isset($names[$key])) {
$field = $fields[$key]; $field = $fields[$key];
if ($val != "" && (!isset($email_fields[$key]) || $email_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 $email_fields[$key] = (is_mail($val) ? $names[$key] : ""); //! filled e-mails can be contained on other pages
} }
$link = ""; $link = "";
$val = $adminer->editVal($val, $field); $val = $adminer->editVal($val, $field);
if ($val !== null) { if ($val !== null) {
@@ -376,6 +386,7 @@ if (!$columns) {
} }
} }
} }
if ($key == "COUNT(*)") { //! columns looking like functions if ($key == "COUNT(*)") { //! columns looking like functions
$link = ME . "select=" . urlencode($TABLE); $link = ME . "select=" . urlencode($TABLE);
$i = 0; $i = 0;
@@ -388,7 +399,9 @@ if (!$columns) {
$link .= where_link($i++, $k, $v); $link .= where_link($i++, $k, $v);
} }
} }
} }
if (!$link && ($link = $adminer->selectLink($row[$key], $field)) === null) { if (!$link && ($link = $adminer->selectLink($row[$key], $field)) === null) {
if (is_mail($row[$key])) { if (is_mail($row[$key])) {
$link = "mailto:$row[$key]"; $link = "mailto:$row[$key]";
@@ -400,6 +413,7 @@ if (!$columns) {
); );
} }
} }
$id = h("val[$unique_idf][" . bracket_escape($key) . "]"); $id = h("val[$unique_idf][" . bracket_escape($key) . "]");
$value = $_POST["val"][$unique_idf][bracket_escape($key)]; $value = $_POST["val"][$unique_idf][bracket_escape($key)];
$h_value = h($value !== null ? $value : $row[$key]); $h_value = h($value !== null ? $value : $row[$key]);
@@ -412,12 +426,14 @@ if (!$columns) {
); );
} }
} }
if ($backward_keys) { if ($backward_keys) {
echo "<td>"; echo "<td>";
} }
$adminer->backwardKeysPrint($backward_keys, $rows[$n]); $adminer->backwardKeysPrint($backward_keys, $rows[$n]);
echo "</tr>\n"; // close to allow white-space: pre echo "</tr>\n"; // close to allow white-space: pre
} }
if (is_ajax()) { if (is_ajax()) {
exit; exit;
} }
@@ -436,6 +452,7 @@ if (!$columns) {
$exact_count = false; $exact_count = false;
} }
} }
if (+$limit && ($found_rows === false || $found_rows > $limit || $page)) { if (+$limit && ($found_rows === false || $found_rows > $limit || $page)) {
echo "<p class='pages'>"; echo "<p class='pages'>";
// display first, previous 4, next 4 and last page // display first, previous 4, next 4 and last page
@@ -457,6 +474,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 (($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 "<p>\n";
echo ($found_rows !== false ? "(" . ($exact_count ? "" : "~ ") . lang('%d row(s)', $found_rows) . ") " : ""); echo ($found_rows !== false ? "(" . ($exact_count ? "" : "~ ") . lang('%d row(s)', $found_rows) . ") " : "");
echo checkbox("all", 1, 0, lang('whole result')) . "\n"; echo checkbox("all", 1, 0, lang('whole result')) . "\n";
@@ -471,7 +489,14 @@ if (!$columns) {
</div></fieldset> </div></fieldset>
<?php <?php
} }
$format = $adminer->dumpFormat(); $format = $adminer->dumpFormat();
foreach ((array) $_GET["columns"] as $column) {
if ($column["fun"]) {
unset($format['sql']);
break;
}
}
if ($format) { if ($format) {
print_fieldset("export", lang('Export')); print_fieldset("export", lang('Export'));
$output = $adminer->dumpOutput(); $output = $adminer->dumpOutput();
@@ -481,6 +506,7 @@ if (!$columns) {
echo "</div></fieldset>\n"; echo "</div></fieldset>\n";
} }
} }
if ($adminer->selectImportPrint()) { if ($adminer->selectImportPrint()) {
print_fieldset("import", lang('Import'), !$rows); print_fieldset("import", lang('Import'), !$rows);
echo "<input type='file' name='csv_file'> "; echo "<input type='file' name='csv_file'> ";

View File

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

View File

@@ -20,18 +20,20 @@ if (!$error && $_POST) {
$fp = false; $fp = false;
$query = $_POST["query"]; $query = $_POST["query"];
if ($_POST["webfile"]) { if ($_POST["webfile"]) {
$fp = @fopen((file_exists("adminer.sql") ? "adminer.sql" $fp = @fopen((file_exists("adminer.sql")
: (file_exists("adminer.sql.gz") ? "compress.zlib://adminer.sql.gz" ? "adminer.sql"
: "compress.bzip2://adminer.sql.bz2" : "compress.zlib://adminer.sql.gz"
)), "rb"); ), "rb");
$query = ($fp ? fread($fp, 1e6) : false); $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); $query = get_file("sql_file", true);
} }
if (is_string($query)) { // get_file() returns error as number, fread() as false if (is_string($query)) { // get_file() returns error as number, fread() as false
if (function_exists('memory_get_usage')) { 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 @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 if ($query != "" && strlen($query) < 1e6) { // don't add big queries
$q = $query . (ereg(";[ \t\r\n]*\$", $query) ? "" : ";"); //! doesn't work with DELIMITER | $q = $query . (ereg(";[ \t\r\n]*\$", $query) ? "" : ";"); //! doesn't work with DELIMITER |
if (!$history || reset(end($history)) != $q) { // no repeated queries if (!$history || reset(end($history)) != $q) { // no repeated queries
@@ -41,6 +43,7 @@ if (!$error && $_POST) {
stop_session(); stop_session();
} }
} }
$space = "(?:\\s|/\\*.*\\*/|(?:#|-- )[^\n]*\n|--\n)"; $space = "(?:\\s|/\\*.*\\*/|(?:#|-- )[^\n]*\n|--\n)";
$delimiter = ";"; $delimiter = ";";
$offset = 0; $offset = 0;
@@ -57,6 +60,7 @@ if (!$error && $_POST) {
parse_str($_COOKIE["adminer_export"], $adminer_export); parse_str($_COOKIE["adminer_export"], $adminer_export);
$dump_format = $adminer->dumpFormat(); $dump_format = $adminer->dumpFormat();
unset($dump_format["sql"]); unset($dump_format["sql"]);
while ($query != "") { while ($query != "") {
if (!$offset && preg_match("~^$space*DELIMITER\\s+(\\S+)~i", $query, $match)) { if (!$offset && preg_match("~^$space*DELIMITER\\s+(\\S+)~i", $query, $match)) {
$delimiter = $match[1]; $delimiter = $match[1];
@@ -71,6 +75,7 @@ if (!$error && $_POST) {
break; break;
} }
$offset = $pos + strlen($found); $offset = $pos + strlen($found);
if ($found && rtrim($found) != $delimiter) { // find matching quote or comment end 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 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]; $s = $match[0][0];
@@ -83,6 +88,7 @@ if (!$error && $_POST) {
} }
} }
} }
} else { // end of a query } else { // end of a query
$empty = false; $empty = false;
$q = substr($query, 0, $pos); $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)) { if ($connection->multi_query($q) && is_object($connection2) && preg_match("~^$space*USE\\b~isU", $q)) {
$connection2->query($q); $connection2->query($q);
} }
do { do {
$result = $connection->store_result(); $result = $connection->store_result();
$end = microtime(); $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) { if ($connection->error) {
echo ($_POST["only_errors"] ? $print : ""); echo ($_POST["only_errors"] ? $print : "");
echo "<p class='error'>" . lang('Error in query') . ($connection->errno ? " ($connection->errno)" : "") . ": " . error() . "\n"; 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"]) { if ($_POST["error_stops"]) {
break 2; break 2;
} }
} elseif (is_object($result)) { } elseif (is_object($result)) {
$orgtables = select($result, $connection2); $orgtables = select($result, $connection2);
if (!$_POST["only_errors"]) { if (!$_POST["only_errors"]) {
@@ -132,6 +143,7 @@ if (!$error && $_POST) {
} }
echo "</form>\n"; echo "</form>\n";
} }
} else { } else {
if (preg_match("~^$space*(CREATE|DROP|ALTER)$space+(DATABASE|SCHEMA)\\b~isU", $q)) { if (preg_match("~^$space*(CREATE|DROP|ALTER)$space+(DATABASE|SCHEMA)\\b~isU", $q)) {
restart_session(); 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"; echo "<p class='message' title='" . h($connection->info) . "'>" . lang('Query executed OK, %d row(s) affected.', $connection->affected_rows) . "$time\n";
} }
} }
$start = $end; $start = $end;
} while ($connection->next_result()); } while ($connection->next_result());
$line += substr_count($q.$found, "\n"); $line += substr_count($q.$found, "\n");
$query = substr($query, $offset); $query = substr($query, $offset);
$offset = 0; $offset = 0;
} }
} }
} }
} }
if ($empty) { if ($empty) {
echo "<p class='message'>" . lang('No commands to execute.') . "\n"; echo "<p class='message'>" . lang('No commands to execute.') . "\n";
} elseif ($_POST["only_errors"]) { } 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) { } elseif ($errors && $commands > 1) {
echo "<p class='error'>" . lang('Error in query') . ": " . implode("", $errors) . "\n"; echo "<p class='error'>" . lang('Error in query') . ": " . implode("", $errors) . "\n";
} }
//! MS SQL - SET SHOWPLAN_ALL OFF //! MS SQL - SET SHOWPLAN_ALL OFF
} else { } else {
echo "<p class='error'>" . upload_error($query) . "\n"; echo "<p class='error'>" . upload_error($query) . "\n";
} }
@@ -176,9 +194,12 @@ if ($_POST) {
$q = $history[$_GET["history"]][0]; $q = $history[$_GET["history"]][0];
} }
textarea("query", $q, 20); 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") 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.') : 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"; 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; "); print_fieldset("webfile", lang('From server'), $_POST["webfile"], "document.getElementById('form')['only_errors'].checked = true; ");
$compress = array(); echo lang('Webserver file %s', "<code>adminer.sql" . (extension_loaded("zlib") ? "[.gz]" : "") . "</code>");
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 ' <input type="submit" name="webfile" value="' . lang('Run file') . '">'; echo ' <input type="submit" name="webfile" value="' . lang('Run file') . '">';
echo "</div></fieldset>\n"; echo "</div></fieldset>\n";

View File

@@ -21,6 +21,8 @@ code { background: #eee; }
tbody tr:hover td, tbody tr:hover th { background: #eee; } tbody tr:hover td, tbody tr:hover th { background: #eee; }
pre { margin: 1em 0 0; } pre { margin: 1em 0 0; }
input[type=image] { vertical-align: middle; } input[type=image] { vertical-align: middle; }
input.default { box-shadow: 1px 1px 1px #777; }
.block { display: block; }
.version { color: #777; font-size: 67%; } .version { color: #777; font-size: 67%; }
.js .hidden, .nojs .jsonly { display: none; } .js .hidden, .nojs .jsonly { display: none; }
.js .column { position: absolute; background: #ddf; padding: .3em 1ex .3em 0; margin-top: -.3em; } .js .column { position: absolute; background: #ddf; padding: .3em 1ex .3em 0; margin-top: -.3em; }
@@ -35,7 +37,7 @@ input[type=image] { vertical-align: middle; }
.enum { color: #007F7F; } .enum { color: #007F7F; }
.binary { color: red; } .binary { color: red; }
.odd td { background: #F5F5F5; } .odd td { background: #F5F5F5; }
.js .checked td, .js .checked th { background: #ddf; } .js .checkable .checked td, .js .checkable .checked th { background: #ddf; }
.time { color: silver; font-size: 70%; } .time { color: silver; font-size: 70%; }
.function { text-align: right; } .function { text-align: right; }
.number { text-align: right; } .number { text-align: right; }
@@ -70,6 +72,16 @@ input[type=image] { vertical-align: middle; }
.rtl #breadcrumb { left: auto; right: 21em; margin: 0 -18px 0 0; } .rtl #breadcrumb { left: auto; right: 21em; margin: 0 -18px 0 0; }
.rtl #lang, .rtl #menu { left: auto; right: 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 { @media print {
#lang, #menu { display: none; } #lang, #menu { display: none; }
#content { margin-left: 1em; } #content { margin-left: 1em; }

View File

@@ -76,7 +76,7 @@ function loginDriver(driver) {
var dbCtrl; var dbCtrl;
var dbPrevious; var dbPrevious = {};
/** Check if database should be opened to a new window /** Check if database should be opened to a new window
* @param MouseEvent * @param MouseEvent
@@ -84,8 +84,8 @@ var dbPrevious;
*/ */
function dbMouseDown(event, el) { function dbMouseDown(event, el) {
dbCtrl = isCtrl(event); dbCtrl = isCtrl(event);
if (dbPrevious == undefined) { if (dbPrevious[el.name] == undefined) {
dbPrevious = el.value; dbPrevious[el.name] = el.value;
} }
} }
@@ -98,9 +98,9 @@ function dbChange(el) {
} }
el.form.submit(); el.form.submit();
el.form.target = ''; el.form.target = '';
if (dbCtrl && dbPrevious != undefined) { if (dbCtrl && dbPrevious[el.name] != undefined) {
el.value = dbPrevious; el.value = dbPrevious[el.name];
dbPrevious = undefined; dbPrevious[el.name] = undefined;
} }
} }
@@ -291,11 +291,11 @@ function editingAddRow(button, focus) {
var match = /(\d+)(\.\d+)?/.exec(button.name); var match = /(\d+)(\.\d+)?/.exec(button.name);
var x = match[0] + (match[2] ? added.substr(match[2].length) : added) + '1'; var x = match[0] + (match[2] ? added.substr(match[2].length) : added) + '1';
var row = parentTag(button, 'tr'); var row = parentTag(button, 'tr');
var row2 = row.cloneNode(true); var row2 = cloneNode(row);
var tags = row.getElementsByTagName('select'); var tags = row.getElementsByTagName('select');
var tags2 = row2.getElementsByTagName('select'); var tags2 = row2.getElementsByTagName('select');
for (var i=0; i < tags.length; i++) { for (var i=0; i < tags.length; i++) {
tags2[i].name = tags[i].name.replace(/([0-9.]+)/, x); tags2[i].name = tags[i].name.replace(/[0-9.]+/, x);
tags2[i].selectedIndex = tags[i].selectedIndex; tags2[i].selectedIndex = tags[i].selectedIndex;
} }
tags = row.getElementsByTagName('input'); tags = row.getElementsByTagName('input');
@@ -363,7 +363,7 @@ function editingTypeChange(type) {
el.className = (/(char|text|enum|set)$/.test(text) ? '' : 'hidden'); el.className = (/(char|text|enum|set)$/.test(text) ? '' : 'hidden');
} }
if (el.name == name + '[unsigned]') { 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]') { if (el.name == name + '[on_update]') {
el.className = (text == 'timestamp' ? '' : 'hidden'); el.className = (text == 'timestamp' ? '' : 'hidden');
@@ -416,7 +416,7 @@ function columnShow(checked, column) {
*/ */
function editingHideDefaults() { function editingHideDefaults() {
if (innerWidth < document.documentElement.scrollWidth) { if (innerWidth < document.documentElement.scrollWidth) {
document.getElementById('defaults').checked = false; document.getElementById('form')['defaults'].checked = false;
columnShow(false, 5); columnShow(false, 5);
} }
} }
@@ -434,7 +434,7 @@ function partitionByChange(el) {
* @param HTMLInputElement * @param HTMLInputElement
*/ */
function partitionNameChange(el) { function partitionNameChange(el) {
var row = parentTag(el, 'tr').cloneNode(true); var row = cloneNode(parentTag(el, 'tr'));
row.firstChild.firstChild.value = ''; row.firstChild.firstChild.value = '';
parentTag(el, 'table').appendChild(row); parentTag(el, 'table').appendChild(row);
el.onchange = function () {}; el.onchange = function () {};
@@ -447,7 +447,7 @@ function partitionNameChange(el) {
*/ */
function foreignAddRow(field) { function foreignAddRow(field) {
field.onchange = function () { }; field.onchange = function () { };
var row = parentTag(field, 'tr').cloneNode(true); var row = cloneNode(parentTag(field, 'tr'));
var selects = row.getElementsByTagName('select'); var selects = row.getElementsByTagName('select');
for (var i=0; i < selects.length; i++) { for (var i=0; i < selects.length; i++) {
selects[i].name = selects[i].name.replace(/\]/, '1$&'); selects[i].name = selects[i].name.replace(/\]/, '1$&');
@@ -463,7 +463,7 @@ function foreignAddRow(field) {
*/ */
function indexesAddRow(field) { function indexesAddRow(field) {
field.onchange = function () { }; field.onchange = function () { };
var row = parentTag(field, 'tr').cloneNode(true); var row = cloneNode(parentTag(field, 'tr'));
var selects = row.getElementsByTagName('select'); var selects = row.getElementsByTagName('select');
for (var i=0; i < selects.length; i++) { for (var i=0; i < selects.length; i++) {
selects[i].name = selects[i].name.replace(/indexes\[\d+/, '$&1'); selects[i].name = selects[i].name.replace(/indexes\[\d+/, '$&1');
@@ -503,10 +503,10 @@ function indexesAddColumn(field, prefix) {
}; };
var select = field.form[field.name.replace(/\].*/, '][type]')]; var select = field.form[field.name.replace(/\].*/, '][type]')];
if (!select.selectedIndex) { if (!select.selectedIndex) {
select.selectedIndex = 3; select.selectedIndex = select.options.length - 1;
select.onchange(); select.onchange();
} }
var column = field.parentNode.cloneNode(true); var column = cloneNode(field.parentNode);
select = column.getElementsByTagName('select')[0]; select = column.getElementsByTagName('select')[0];
select.name = select.name.replace(/\]\[\d+/, '$&1'); select.name = select.name.replace(/\]\[\d+/, '$&1');
select.selectedIndex = 0; select.selectedIndex = 0;

View File

@@ -240,7 +240,7 @@ function selectAddRow(field) {
selectFieldChange(field.form); selectFieldChange(field.form);
}; };
field.onchange(); field.onchange();
var row = field.parentNode.cloneNode(true); var row = cloneNode(field.parentNode);
var selects = row.getElementsByTagName('select'); var selects = row.getElementsByTagName('select');
for (var i=0; i < selects.length; i++) { for (var i=0; i < selects.length; i++) {
selects[i].name = selects[i].name.replace(/[a-z]\[\d+/, '$&1'); selects[i].name = selects[i].name.replace(/[a-z]\[\d+/, '$&1');
@@ -258,7 +258,7 @@ function selectAddRow(field) {
/** Clear column name after resetting search /** Clear column name after resetting search
* @param HTMLInputElement * @param HTMLInputElement
*/ */
function selectSearch(el) { function selectSearchSearch(el) {
if (!el.value) { if (!el.value) {
el.parentNode.firstChild.selectedIndex = 0; el.parentNode.firstChild.selectedIndex = 0;
} }
@@ -474,6 +474,7 @@ function selectClick(td, event, text, warning) {
} }
td.innerHTML = ''; td.innerHTML = '';
td.appendChild(input); td.appendChild(input);
setupSubmitHighlight(td);
input.focus(); input.focus();
if (text == 2) { // long text if (text == 2) { // long text
return ajax(location.href + '&' + encodeURIComponent(td.id) + '=', function (request) { return ajax(location.href + '&' + encodeURIComponent(td.id) + '=', function (request) {
@@ -536,3 +537,88 @@ function eventStop(event) {
event.cancelBubble = true; 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) { if (!$fields) {
$error = error(); $error = error();
} }
$table_status = ($fields ? table_status($TABLE) : array()); $table_status = table_status1($TABLE, true);
page_header(($fields && is_view($table_status) ? lang('View') : lang('Table')) . ": " . h($TABLE), $error); page_header(($fields && is_view($table_status) ? lang('View') : lang('Table')) . ": " . h($TABLE), $error);
$adminer->selectLinks($table_status); $adminer->selectLinks($table_status);
$comment = $table_status["Comment"]; $comment = $table_status["Comment"];
if ($comment != "") { if ($comment != "") {
@@ -26,7 +27,7 @@ if ($fields) {
echo "</table>\n"; echo "</table>\n";
if (!is_view($table_status)) { if (!is_view($table_status)) {
echo "<h3>" . lang('Indexes') . "</h3>\n"; echo "<h3 id='indexes'>" . lang('Indexes') . "</h3>\n";
$indexes = indexes($TABLE); $indexes = indexes($TABLE);
if ($indexes) { if ($indexes) {
echo "<table cellspacing='0'>\n"; echo "<table cellspacing='0'>\n";
@@ -34,7 +35,10 @@ if ($fields) {
ksort($index["columns"]); // enforce correct columns order ksort($index["columns"]); // enforce correct columns order
$print = array(); $print = array();
foreach ($index["columns"] as $key => $val) { foreach ($index["columns"] as $key => $val) {
$print[] = "<i>" . h($val) . "</i>" . ($index["lengths"][$key] ? "(" . $index["lengths"][$key] . ")" : ""); $print[] = "<i>" . h($val) . "</i>"
. ($index["lengths"][$key] ? "(" . $index["lengths"][$key] . ")" : "")
. ($index["descs"][$key] ? " DESC" : "")
;
} }
echo "<tr title='" . h($name) . "'><th>$index[type]<td>" . implode(", ", $print) . "\n"; echo "<tr title='" . h($name) . "'><th>$index[type]<td>" . implode(", ", $print) . "\n";
} }
@@ -43,7 +47,7 @@ if ($fields) {
echo '<p><a href="' . h(ME) . 'indexes=' . urlencode($TABLE) . '">' . lang('Alter indexes') . "</a>\n"; echo '<p><a href="' . h(ME) . 'indexes=' . urlencode($TABLE) . '">' . lang('Alter indexes') . "</a>\n";
if (fk_support($table_status)) { 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); $foreign_keys = foreign_keys($TABLE);
if ($foreign_keys) { if ($foreign_keys) {
echo "<table cellspacing='0'>\n"; echo "<table cellspacing='0'>\n";
@@ -68,7 +72,7 @@ if ($fields) {
} }
if (support("trigger")) { if (support("trigger")) {
echo "<h3>" . lang('Triggers') . "</h3>\n"; echo "<h3 id='triggers'>" . lang('Triggers') . "</h3>\n";
$triggers = triggers($TABLE); $triggers = triggers($TABLE);
if ($triggers) { if ($triggers) {
echo "<table cellspacing='0'>\n"; echo "<table cellspacing='0'>\n";
@@ -79,5 +83,6 @@ if ($fields) {
} }
echo '<p><a href="' . h(ME) . 'trigger=' . urlencode($TABLE) . '">' . lang('Add trigger') . "</a>\n"; echo '<p><a href="' . h(ME) . 'trigger=' . urlencode($TABLE) . '">' . lang('Add trigger') . "</a>\n";
} }
} }
} }

View File

@@ -1,27 +1,36 @@
<?php <?php
$TABLE = $_GET["trigger"]; $TABLE = $_GET["trigger"];
$name = $_GET["name"];
$trigger_options = trigger_options(); $trigger_options = trigger_options();
$trigger_event = array("INSERT", "UPDATE", "DELETE"); $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 ($_POST) {
if (!$error && in_array($_POST["Timing"], $trigger_options["Timing"]) && in_array($_POST["Event"], $trigger_event) && in_array($_POST["Type"], $trigger_options["Type"])) { 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); $on = " ON " . table($TABLE);
drop_create( $drop = "DROP TRIGGER " . idf_escape($name) . ($jush == "pgsql" ? $on : "");
"DROP TRIGGER " . idf_escape($_GET["name"]) . ($jush == "pgsql" ? $on : ""), $location = ME . "table=" . urlencode($TABLE);
create_trigger($on, $_POST), if ($_POST["drop"]) {
create_trigger($on, $row + array("Type" => reset($trigger_options["Type"]))), query_redirect($drop, $location, lang('Trigger has been dropped.'));
ME . "table=" . urlencode($TABLE), } else {
lang('Trigger has been dropped.'), if ($name != "") {
lang('Trigger has been altered.'), queries($drop);
lang('Trigger has been created.'), }
$_GET["name"] 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; $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"> <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><?php textarea("Statement", $row["Statement"]); ?>
<p> <p>
<input type="submit" value="<?php echo lang('Save'); ?>"> <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; ?>"> <input type="hidden" name="token" value="<?php echo $token; ?>">
</form> </form>

View File

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

View File

@@ -26,6 +26,7 @@ if ($_POST) {
} }
$grants = array(); $grants = array();
$old_pass = ""; $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 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()) { 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 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) . ")"); $pass = $connection->result("SELECT PASSWORD(" . q($pass) . ")");
$error = !$pass; $error = !$pass;
} }
$created = false; $created = false;
if (!$error) { if (!$error) {
if ($old_user != $new_user) { if ($old_user != $new_user) {
@@ -65,6 +67,7 @@ if ($_POST && !$error) {
queries("SET PASSWORD FOR $new_user = " . q($pass)); queries("SET PASSWORD FOR $new_user = " . q($pass));
} }
} }
if (!$error) { if (!$error) {
$revoke = array(); $revoke = array();
foreach ($new_grants as $object => $grant) { foreach ($new_grants as $object => $grant) {
@@ -90,6 +93,7 @@ if ($_POST && !$error) {
} }
} }
} }
if (!$error && isset($_GET["host"])) { if (!$error && isset($_GET["host"])) {
if ($old_user != $new_user) { if ($old_user != $new_user) {
queries("DROP USER $old_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); queries_redirect(ME . "privileges=", (isset($_GET["host"]) ? lang('User has been altered.') : lang('User has been created.')), !$error);
if ($created) { if ($created) {
// delete new user in case of an error // delete new user in case of an error
$connection->query("DROP USER $new_user"); $connection->query("DROP USER $new_user");
@@ -120,7 +126,7 @@ if ($_POST) {
if ($old_pass != "") { if ($old_pass != "") {
$row["hashed"] = true; $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++; $i++;
} }
echo "</thead>\n"; echo "</thead>\n";
foreach (array( foreach (array(
"" => "", "" => "",
"Server Admin" => lang('Server'), "Server Admin" => lang('Server'),
@@ -162,12 +169,13 @@ foreach (array(
} elseif (isset($_GET["grant"])) { } elseif (isset($_GET["grant"])) {
echo "<td><select name=$name><option><option value='1'" . ($value ? " selected" : "") . ">" . lang('Grant') . "<option value='0'" . ($value == "0" ? " selected" : "") . ">" . lang('Revoke') . "</select>"; echo "<td><select name=$name><option><option value='1'" . ($value ? " selected" : "") . ">" . lang('Grant') . "<option value='0'" . ($value == "0" ? " selected" : "") . ">" . lang('Revoke') . "</select>";
} else { } else {
echo "<td align='center'><input type='checkbox' name=$name value='1'" . ($value ? " checked" : "") . ($privilege == "All privileges" ? " id='grants-$i-all'" : ($privilege == "Grant option" ? "" : " onclick=\"if (this.checked) formUncheck('grants-$i-all');\"")) . ">"; //! uncheck all except grant if all is checked echo "<td align='center'><label class='block'><input type='checkbox' name=$name value='1'" . ($value ? " checked" : "") . ($privilege == "All privileges" ? " id='grants-$i-all'" : ($privilege == "Grant option" ? "" : " onclick=\"if (this.checked) formUncheck('grants-$i-all');\"")) . "></label>"; //! uncheck all except grant if all is checked
} }
$i++; $i++;
} }
} }
} }
echo "</table>\n"; echo "</table>\n";
?> ?>
<p> <p>

View File

@@ -1,23 +1,39 @@
<?php <?php
$TABLE = $_GET["view"]; $TABLE = $_GET["view"];
$row = ($TABLE == "" ? array() : view($TABLE)); $row = $_POST;
$row["name"] = $TABLE;
if ($_POST) { if ($_POST && !$error) {
if (!$error) { $name = trim($row["name"]);
$name = trim($_POST["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_create(
"DROP VIEW " . table($TABLE), "DROP VIEW " . table($TABLE),
"CREATE VIEW " . table($name) . " AS\n$_POST[select]", "CREATE VIEW " . table($name) . $as,
"CREATE VIEW " . table($TABLE) . " AS\n$row[select]", "DROP VIEW " . table($name),
($_POST["drop"] ? substr(ME, 0, -1) : ME . "table=" . urlencode($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 dropped.'),
lang('View has been altered.'), $message,
lang('View has been created.'), lang('View has been created.'),
$TABLE $TABLE,
$name
); );
} }
$row = $_POST; }
if (!$_POST && $TABLE != "") {
$row = view($TABLE);
$row["name"] = $TABLE;
if (!$error) {
$error = $connection->error;
}
} }
page_header(($TABLE != "" ? lang('Alter view') : lang('Create view')), $error, array("table" => $TABLE), $TABLE); page_header(($TABLE != "" ? lang('Alter view') : lang('Create view')), $error, array("table" => $TABLE), $TABLE);

View File

@@ -1,3 +1,46 @@
Adminer (released 2013-06-29):
Increase click target for checkboxes
Use shadow for highlighting default button
Don't use LIMIT 1 if inline updating unique row
Don't check previous checkbox on added column in create table (bug #3614245)
Order table list by name
Verify UTF-8 encoding of CSV import
Notify user about expired master password for permanent login
Highlight table being altered in navigation
Send 404 for invalid database and schema
Fix title and links on invalid table pages
Display error on invalid alter table and view pages
MySQL: Speed up updating rows without numeric or UTF-8 primary key
Non-MySQL: Descending indexes
PostgreSQL: Fix detecting oid column in PDO
PostgreSQL: Handle timestamp types (bug #3614086)
Add Korean translation
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 PDO
Adminer 3.6.4 (released 2013-04-26): Adminer 3.6.4 (released 2013-04-26):
Display pagination on a fixed position Display pagination on a fixed position
Increase default select limit to 50 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]"); $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" || !$_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 $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" : ""); 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)) { } elseif (preg_match('~\\s*(\\$pos = (.+\n).+;)~sU', $return, $match2)) {
@@ -50,16 +63,19 @@ function put_file($match) {
return '$_SESSION[lang]'; return '$_SESSION[lang]';
} }
function lang(\$translation, \$number) { function lang(\$translation, \$number = null) {
\$pos = $match2[2]\t\t: " . (preg_match("~\\\$LANG == '$_SESSION[lang]'.* \\? (.+)\n~U", $match2[1], $match3) ? $match3[1] : "1") . ' if (is_array(\$translation)) {
); \$pos = $match2[2]\t\t\t: " . (preg_match("~\\\$LANG == '$_SESSION[lang]'.* \\? (.+)\n~U", $match2[1], $match3) ? $match3[1] : "1") . '
$translation = str_replace("%d", "%s", $translation[$pos]); );
$translation = $translation[$pos];
}
$translation = str_replace("%d", "%s", $translation);
$number = number_format($number, 0, ".", lang(\',\')); $number = number_format($number, 0, ".", lang(\',\'));
return sprintf($translation, $number); return sprintf($translation, $number);
} }
'; ';
} else { } else {
echo "lang() not found\n"; echo "lang() \$pos not found\n";
} }
} }
@@ -123,13 +139,19 @@ if ($_SESSION["translations_version"] != ' . $translations_version . ') {
$translations = array(); $translations = array();
$_SESSION["translations_version"] = ' . $translations_version . '; $_SESSION["translations_version"] = ' . $translations_version . ';
} }
if (!$translations) {
switch ($LANG) {' . $return . ' function get_translations($lang) {
switch ($lang) {' . $return . '
} }
$translations = array(); $translations = array();
foreach (explode("\n", lzw_decompress($compressed)) as $val) { foreach (explode("\n", lzw_decompress($compressed)) as $val) {
$translations[] = (strpos($val, "\t") ? explode("\t", $val) : $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 { #content:after {
clear: both; clear: both;
content: "."; content: "";
display: table;
}
#content > h2:before {
display: block; display: block;
height: 0; content: "";
overflow: hidden; 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 { #content > p {
@@ -231,11 +250,11 @@ table code {
background: #333; background: #333;
color: #FFF; color: #FFF;
height: 40px; height: 40px;
left: 0;
line-height: 40px; line-height: 40px;
padding: 0 0 0 40px; padding: 0 0 0 40px;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0;
width: 260px; width: 260px;
} }
@@ -281,12 +300,12 @@ table code {
#breadcrumb { #breadcrumb {
background: #333; background: #333;
color: #FFF; color: #FFF;
left: 300px;
line-height: 40px; line-height: 40px;
margin: 0; margin: 0;
padding: 0 0 0 20px; padding: 0 0 0 20px;
position: fixed; position: fixed;
top: 0; top: 0;
left: 300px;
width: 100%; width: 100%;
height: 40px; height: 40px;
} }
@@ -329,6 +348,12 @@ table code {
height: 100%; height: 100%;
} }
#content > p.tabs + *:after {
display: table;
clear: both;
content: "";
}
/* icons */ /* icons */
@@ -367,44 +392,27 @@ select[name="db"] option {
} }
#menu p a[href*="&select="] { #menu p a[href*="&select="] {
clear: left; display: inline-block;
display: block;
float: left;
margin-right: 8px; margin-right: 8px;
overflow: hidden; overflow: hidden;
padding-left: 0; padding-left: 0;
text-decoration: none; text-decoration: none;
width: 16px; width: 16px;
line-height: 16px; height: 16px;
} }
#menu p a[href*="&select="]:before { #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="); 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; padding-right: 5px;
} display: inline-block;
margin-top: 2px;
#menu p a[href*="&select="]:hover {
margin-left: -3px;
margin-top: -2px;
overflow: visible;
padding: 1px 2px;
position: absolute;
width: auto;
} }
#menu p a[href*="&table="], #menu p a[href*="&view="] { #menu p a[href*="&table="], #menu p a[href*="&view="] {
clear: right; display: inline-block;
display: block;
min-height: 20px;
margin-left: 24px;
padding-bottom: 1px;
text-decoration: none; text-decoration: none;
} }
#menu p br {
display: none;
}
a[href*="&create="] { 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; 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; padding-left: 22px;
@@ -537,7 +545,7 @@ input[name="delete"]:hover, input[name="drop"]:hover {
color: red; 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; 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; border: none;
cursor: pointer; cursor: pointer;

View File

@@ -0,0 +1,319 @@
/*
FLAT UI Flavored Adminer Theme by M. Mahbubur Rahman (mahbub@mahbubblog.com)
Screenshot : http://d.pr/i/cznH
Based on work by : Lukáš Brandejs
https://raw.github.com/vrana/adminer/master/designs/ng9/adminer.css
*/
@import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600);
* {
font: 14px/1.7 "Source Sans Pro","Droid Sans",Arial,Helvetica, sans-serif;
color:#333333;
margin:0px;
padding:0px;
}
a,a:visited {
color:#2980b9;
text-decoration:none;
padding:3px 1px;
}
#content table thead span, #content table thead a {
font-weight:bold;
color:black;
}
#content table thead a:hover {
background:none;
text-decoration:underline;
color:black;
}
a:hover {
text-decoration:underline;
}
h1 {
font-size:1.9em;
font-weight:normal;
background:white;
color:#1e5eb6;
border-bottom:1px solid rgb(85, 112, 139);
padding:20px;
margin:0px;
}
#menu h1 {
padding:0px 0px 5px 20px;
background:none;
}
h2,h3 {
font-size:1.7em;
font-weight:bold;
background:white;
color:#34495e;
border-bottom:1px solid #f4f4f4;
padding:10px 0px;
margin:0px;
}
fieldset {
padding:5px;
border:1px solid #DEDEDE;
}
input,select,textarea {
border:1px solid #e5e5e5;
margin:1px;
padding:3px;
}
input[type=submit] {
color:white;
background:#27ae60;
padding:4px 10px;
cursor:pointer;
border:0px solid;
}
input[type=submit]:hover{
background:#2c3e50;
}
input[type=checkbox]{
margin-right:5px;
}
input[type=image] {
border:1px solid #d0cdc4;
}
input[type=checkbox],input[type=radio]{
border:1px solid #e5e5e5;
padding:2px 5px;
}
code{
background:#f0ffe1;
border:1px dashed #d5f1b9;
padding:2px 4px;
font-family:"Monaco","Courier New";
}
code a:hover{background:transparent}
table{
margin:10px 0px;
border:1px solid #d0cdc4;
border-collapse:collapse;
}
tbody tr:hover td,tbody tr:hover th{
background:#edf4ff
}
thead th, thead td {
text-align:center;
vertical-align:middle;
font-weight:bold;
white-space:nowrap;
background:#ecf0f1;
color:#808080;
}
th,td{
border:1px solid #d0cdc4;
padding:3px 6px;
vertical-align:top;
}
th a {
font-weight:bold;
padding-bottom:0px;
}
th {
background:white;
}
tr.odd td {
background:#fcfaf5;
}
#content tbody tr.checked td, tr.checked.odd td {
background:#fbe2e2;
color:red;
}
.hidden{
display:none
}
.error,.message{
padding:0px;
background:transparent;
font-weight:bold
}
.error{
color:#c00
}
.message{
color:#090
}
#content{
margin:0px 0px 0px 320px;
padding:50px 20px 40px 0px;
height:100%;
}
#lang {
background:#ecf0f1;
color:#808080;
position:fixed;
top:0px;
left:0px;
width:100%;
padding:10px 20px;
z-index:1;
}
#breadcrumb {
position:fixed;
top:0px;
left:300px;
background:#34495e;
z-index:2;
width:100%;
color:#ecf0f1;
padding:10px;
font-size:15px;
font-weight:bold;
}
#breadcrumb a{
color:#ecf0f1;
font-size:15px;
font-weight:bold;
}
#menu {
background:#34495e;
position:fixed;
top:-10px;
color:#FFF;
padding:20px;
padding-top:40px;
bottom:0px;
overflow:auto;
left:0px;
width:240px;
border-right:5px solid #34495e;
}
#menu p{
border-bottom:1px solid rgb(85, 112, 139);
}
#menu a{
color:#FFF;
}
#schema .table {
padding:5px;
background:#fcfaf5;
border:1px solid #d0cdc4;
}
#schema .table b {
color:#006aeb;
font-weight:bold;
text-decoration:underline;
}
#schema .table b:hover {
color:white;
}
input[name=logout] {
color:#fce2e2;
background:#d73e3e;
}
input[name=drop] {
background-color:#c0392b;
}
input[name=logout]:hover {
background:#ea0202;
}
#logins a, #tables a {
background:none;
}
#logins a:hover, #tables a:hover {
}
#logout {
color:#FFF;
text-decoration:none;
}
#logout:hover {
color:red;
}
.js .column {
background:#ecf0f1;
}
#content table thead a.text:hover {
text-decoration:none;
}
#version, .version {
font-size:50%;
}
#h1:hover {
color:white;
}
input[type=submit] {
font-size:13px;
font-weight:normal;
-moz-border-radius:2px;
-webkit-border-radius:2px;
border-radius:2px;
border:0px solid #469df5;
padding:3px 10px;
text-decoration:none;
background:-webkit-gradient( linear, left top, left bottom, color-stop(5%, #63b8ee), color-stop(100%, #468ccf) );
background:-moz-linear-gradient( center top, #63b8ee 5%, #468ccf 100% );
background:-ms-linear-gradient( top, #63b8ee 5%, #468ccf 100% );
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#63b8ee', endColorstr='#468ccf');
background-color:#63b8ee;
color:#ffffff;
display:inline-block;
text-shadow:1px 1px 0px #287ace;
-webkit-box-shadow:inset 0px 0px 0px 0px #cae3fc;
-moz-box-shadow:inset 0px 0px 0px 0px #cae3fc;
box-shadow:inset 0px 0px 0px 0px #cae3fc;
}
input[type=submit]:hover {
background:-webkit-gradient( linear, left top, left bottom, color-stop(5%, #4197ee), color-stop(100%, #79bbff) );
background:-moz-linear-gradient( center top, #4197ee 5%, #79bbff 100% );
background:-ms-linear-gradient( top, #4197ee 5%, #79bbff 100% );
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#4197ee', endColorstr='#79bbff');
background-color:#4197ee;
}
input[type=submit]:active {
position:relative;
top:1px;
}

View File

@@ -9,6 +9,7 @@ if ($adminer->homepage()) {
} }
echo "<table cellspacing='0' class='nowrap checkable' onclick='tableClick(event);'>\n"; 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"; 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) { foreach (table_status() as $table => $row) {
$name = $adminer->tableName($row); $name = $adminer->tableName($row);
if (isset($row["Engine"]) && $name != "") { 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 "<td align='right'><a href='" . h(ME . "edit=") . urlencode($table) . "'>" . ($row["Engine"] == "InnoDB" && $val ? "~ $val" : $val) . "</a>";
} }
} }
echo "</table>\n"; echo "</table>\n";
echo "<script type='text/javascript'>tableCheck();</script>\n"; echo "<script type='text/javascript'>tableCheck();</script>\n";
echo "</form>\n"; echo "</form>\n";

View File

@@ -13,17 +13,19 @@ class Adminer {
return array(SERVER, $_GET["username"], get_session("pwds")); return array(SERVER, $_GET["username"], get_session("pwds"));
} }
function permanentLogin() { function permanentLogin($create = false) {
return password_file(); return password_file($create);
} }
function database() { function database() {
global $connection; global $connection;
$databases = $this->databases(false); if ($connection) {
return (!$databases $databases = $this->databases(false);
? $connection->result("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', 1)") // username without the database list return (!$databases
: $databases[(information_schema($databases[0]) ? 1 : 0)] // first available database ? $connection->result("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', 1)") // username without the database list
); : $databases[(information_schema($databases[0]) ? 1 : 0)] // first available database
);
}
} }
function databases($flush = true) { function databases($flush = true) {
@@ -49,7 +51,7 @@ class Adminer {
<tr><th><?php echo lang('Password'); ?><td><input type="password" name="auth[password]"> <tr><th><?php echo lang('Password'); ?><td><input type="password" name="auth[password]">
</table> </table>
<script type="text/javascript"> <script type="text/javascript">
document.getElementById('username').focus(); focus(document.getElementById('username'));
</script> </script>
<?php <?php
echo "<p><input type='submit' value='" . lang('Login') . "'>\n"; echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
@@ -92,7 +94,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"]; $return[$row["TABLE_NAME"]]["keys"][$row["CONSTRAINT_NAME"]][$row["COLUMN_NAME"]] = $row["REFERENCED_COLUMN_NAME"];
} }
foreach ($return as $key => $val) { foreach ($return as $key => $val) {
$name = $this->tableName(table_status($key)); $name = $this->tableName(table_status($key, true));
if ($name != "") { if ($name != "") {
$search = preg_quote($tableName); $search = preg_quote($tableName);
$separator = "(:|\\s*-)?\\s+"; $separator = "(:|\\s*-)?\\s+";
@@ -143,7 +145,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
// find all used ids // find all used ids
$ids = array(); $ids = array();
foreach ($rows as $row) { foreach ($rows as $row) {
$ids[$row[$key]] = exact_value($row[$key]); $ids[$row[$key]] = q($row[$key]);
} }
// uses constant number of queries to get the descriptions, join would be complex, multiple queries would be slow // uses constant number of queries to get the descriptions, join would be complex, multiple queries would be slow
$descriptions = $this->_values[$table]; $descriptions = $this->_values[$table];
@@ -234,7 +236,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
if (($val["col"] == "" || $columns[$val["col"]]) && "$val[col]$val[val]" != "") { 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 "<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 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++; $i++;
} }
} }
@@ -355,6 +357,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
} }
foreach (($index_order != "" ? array($indexes[$index_order]) : $indexes) as $index) { foreach (($index_order != "" ? array($indexes[$index_order]) : $indexes) as $index) {
if ($index_order != "" || $index["type"] == "INDEX") { if ($index_order != "" || $index["type"] == "INDEX") {
$has_desc = array_filter($index["descs"]);
$desc = false; $desc = false;
foreach ($index["columns"] as $val) { foreach ($index["columns"] as $val) {
if (ereg('date|timestamp', $fields[$val]["type"])) { if (ereg('date|timestamp', $fields[$val]["type"])) {
@@ -363,8 +366,8 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
} }
} }
$return = array(); $return = array();
foreach ($index["columns"] as $val) { foreach ($index["columns"] as $key => $val) {
$return[] = idf_escape($val) . ($desc ? " DESC" : ""); $return[] = idf_escape($val) . (($has_desc ? $index["descs"][$key] : $desc) ? " DESC" : "");
} }
return $return; return $return;
} }
@@ -562,7 +565,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
<?php <?php
$this->databasesPrint($missing); $this->databasesPrint($missing);
if ($missing != "db" && $missing != "ns") { if ($missing != "db" && $missing != "ns") {
$table_status = table_status(); $table_status = table_status('', true);
if (!$table_status) { if (!$table_status) {
echo "<p class='message'>" . lang('No tables.') . "\n"; echo "<p class='message'>" . lang('No tables.') . "\n";
} else { } else {
@@ -580,7 +583,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
foreach ($tables as $row) { foreach ($tables as $row) {
$name = $this->tableName($row); $name = $this->tableName($row);
if (isset($row["Engine"]) && $name != "") { // ignore views and tables without name if (isset($row["Engine"]) && $name != "") { // ignore views and tables without name
echo "<a href='" . h(ME) . 'select=' . urlencode($row["Name"]) . "'" . bold($_GET["select"] == $row["Name"]) . " title='" . lang('Select data') . "'>$name</a><br>\n"; echo "<a href='" . h(ME) . 'select=' . urlencode($row["Name"]) . "'" . bold($_GET["select"] == $row["Name"] || $_GET["edit"] == $row["Name"]) . " title='" . lang('Select data') . "'>$name</a><br>\n";
} }
} }
} }

View File

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

View File

@@ -3,11 +3,12 @@ if ($_GET["script"] == "kill") {
$connection->query("KILL " . (+$_POST["kill"])); $connection->query("KILL " . (+$_POST["kill"]));
} elseif (list($table, $id, $name) = $adminer->_foreignColumn(column_foreign_keys($_GET["source"]), $_GET["field"])) { } elseif (list($table, $id, $name) = $adminer->_foreignColumn(column_foreign_keys($_GET["source"]), $_GET["field"])) {
$result = $connection->query("SELECT $id, $name FROM " . table($table) . " WHERE " . (ereg('^[0-9]+$', $_GET["value"]) ? "$id = $_GET[value] OR " : "") . "$name LIKE " . q("$_GET[value]%") . " ORDER BY 2 LIMIT 11"); $limit = 11;
for ($i=0; $i < 10 && ($row = $result->fetch_row()); $i++) { $result = $connection->query("SELECT $id, $name FROM " . table($table) . " WHERE " . (ereg('^[0-9]+$', $_GET["value"]) ? "$id = $_GET[value] OR " : "") . "$name LIKE " . q("$_GET[value]%") . " ORDER BY 2 LIMIT $limit");
for ($i=1; ($row = $result->fetch_row()) && $i < $limit; $i++) {
echo "<a href='" . h(ME . "edit=" . urlencode($table) . "&where" . urlencode("[" . bracket_escape(idf_unescape($id)) . "]") . "=" . urlencode($row[0])) . "'>" . h($row[1]) . "</a><br>\n"; echo "<a href='" . h(ME . "edit=" . urlencode($table) . "&where" . urlencode("[" . bracket_escape(idf_unescape($id)) . "]") . "=" . urlencode($row[0])) . "'>" . h($row[1]) . "</a><br>\n";
} }
if ($i == 10) { if ($row) {
echo "...\n"; echo "...\n";
} }
} }

41
plugins/dump-bz2.php Normal file
View File

@@ -0,0 +1,41 @@
<?php
/** Dump to Bzip2 format
* @link http://www.adminer.org/plugins/#use
* @uses bzopen(), tempnam("")
* @author Jakub Vrana, http://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/
class AdminerDumpBz2 {
/** @access protected */
var $filename, $fp;
function dumpOutput() {
if (!function_exists('bzopen')) {
return array();
}
return array('bz2' => 'bzip2');
}
function _bz2($string, $state) {
bzwrite($this->fp, $string);
if ($state & PHP_OUTPUT_HANDLER_END) {
bzclose($this->fp);
$return = file_get_contents($this->filename);
unlink($this->filename);
return $return;
}
return "";
}
function dumpHeaders($identifier, $multi_table = false) {
if ($_POST["output"] == "bz2") {
$this->filename = tempnam("", "bz2");
$this->fp = bzopen($this->filename, 'w');
header("Content-Type: application/x-bzip");
ob_start(array($this, '_bz2'), 1e6);
}
}
}

View File

@@ -35,8 +35,8 @@ class AdminerDumpZip {
} }
function dumpHeaders($identifier, $multi_table = false) { function dumpHeaders($identifier, $multi_table = false) {
$this->filename = "$identifier." . ($multi_table && ereg("[ct]sv", $_POST["format"]) ? "tar" : $_POST["format"]);
if ($_POST["output"] == "zip") { if ($_POST["output"] == "zip") {
$this->filename = "$identifier." . ($multi_table && ereg("[ct]sv", $_POST["format"]) ? "tar" : $_POST["format"]);
header("Content-Type: application/zip"); header("Content-Type: application/zip");
ob_start(array($this, '_zip')); ob_start(array($this, '_zip'));
} }

View File

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

View File

@@ -63,7 +63,7 @@
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>checkbox-3</td> <td>name=comments</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>

View File

@@ -68,7 +68,7 @@
</tr> </tr>
<tr> <tr>
<td>click</td> <td>click</td>
<td>checkbox-3</td> <td>name=comments</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>

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) 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" Add title to Logout, edit (in select) and select (in menu) for style "hever"
Export by GET parameters 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) 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) <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 Define foreign keys name - http://forum.zdrojak.root.cz/index.php?topic=185.msg1255#msg1255
@@ -22,11 +21,9 @@ Rank, Tree structure
MySQL: MySQL:
Data longer than max_allowed_packet can be sent by mysqli_stmt_send_long_data() Data longer than max_allowed_packet can be sent by mysqli_stmt_send_long_data()
? Geometry support
SQLite: SQLite:
Copy tables Copy tables
ASC and DESC instead of text length in index
Delimiter in export and SQL command Delimiter in export and SQL command
Backward keys in Editor Backward keys in Editor