mirror of
https://github.com/vrana/adminer.git
synced 2025-09-02 02:42:37 +02:00
Compare commits
35 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2d18afaf7f | ||
|
9a3b3db4f6 | ||
|
a4e38a266d | ||
|
ca32e71e42 | ||
|
4b4fa16a37 | ||
|
69d49e30c5 | ||
|
7fcfb0d16a | ||
|
1501d60f14 | ||
|
e5b1c99d87 | ||
|
b49061b863 | ||
|
5fd21e122a | ||
|
b783b9487d | ||
|
99343701ab | ||
|
c09a147b2e | ||
|
a0af3eec5c | ||
|
1dd6dbcce2 | ||
|
95f0a5f0f0 | ||
|
335ab7eab2 | ||
|
6a486181dd | ||
|
57e5896b55 | ||
|
ac668d1331 | ||
|
55831095b6 | ||
|
07e2c3b2a4 | ||
|
e2dbb9c7bd | ||
|
e8b95f127f | ||
|
f1153aa35a | ||
|
5e4b815893 | ||
|
a227ec1c97 | ||
|
98483e101d | ||
|
c2f95e0054 | ||
|
5fb2368b66 | ||
|
385fdd45b8 | ||
|
56cd77f0d1 | ||
|
7291ae608d | ||
|
6a3cf71db5 |
@@ -23,10 +23,12 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
|
||||
query_redirect("DROP TABLE " . table($TABLE), substr(ME, 0, -1), lang('Table has been dropped.'));
|
||||
} else {
|
||||
$fields = array();
|
||||
$all_fields = array();
|
||||
$use_all_fields = false;
|
||||
$foreign = array();
|
||||
ksort($_POST["fields"]);
|
||||
$orig_field = reset($orig_fields);
|
||||
$after = "FIRST";
|
||||
$after = " FIRST";
|
||||
foreach ($_POST["fields"] as $key => $field) {
|
||||
$foreign_key = $foreign_keys[$field["type"]];
|
||||
$type_field = ($foreign_key !== null ? $referencable_primary[$foreign_key] : $field); //! can collide with user defined type
|
||||
@@ -43,18 +45,26 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
|
||||
$field["auto_increment"] = true;
|
||||
}
|
||||
$process_field = process_field($field, $type_field);
|
||||
$all_fields[] = array($field["orig"], $process_field, $after);
|
||||
if ($process_field != process_field($orig_field, $orig_field)) {
|
||||
$fields[] = array($field["orig"], $process_field, $after);
|
||||
if ($field["orig"] != "" || $after) {
|
||||
$use_all_fields = true;
|
||||
}
|
||||
}
|
||||
if ($foreign_key !== null) {
|
||||
$foreign[idf_escape($field["field"])] = ($TABLE != "" ? "ADD" : " ") . " FOREIGN KEY (" . idf_escape($field["field"]) . ") REFERENCES " . table($foreign_keys[$field["type"]]) . " (" . idf_escape($type_field["field"]) . ")" . (ereg("^($on_actions)\$", $field["on_delete"]) ? " ON DELETE $field[on_delete]" : "");
|
||||
$foreign[idf_escape($field["field"])] = ($TABLE != "" && $jush != "sqlite" ? "ADD" : " ") . " FOREIGN KEY (" . idf_escape($field["field"]) . ") REFERENCES " . table($foreign_keys[$field["type"]]) . " (" . idf_escape($type_field["field"]) . ")" . (ereg("^($on_actions)\$", $field["on_delete"]) ? " ON DELETE $field[on_delete]" : "");
|
||||
}
|
||||
$after = "AFTER " . idf_escape($field["field"]);
|
||||
$after = " AFTER " . idf_escape($field["field"]);
|
||||
} elseif ($field["orig"] != "") {
|
||||
$use_all_fields = true;
|
||||
$fields[] = array($field["orig"]);
|
||||
}
|
||||
if ($field["orig"] != "") {
|
||||
$orig_field = next($orig_fields);
|
||||
if (!$orig_field) {
|
||||
$after = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
$partitioning = "";
|
||||
@@ -82,7 +92,7 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
|
||||
queries_redirect(ME . "table=" . urlencode($name), $message, alter_table(
|
||||
$TABLE,
|
||||
$name,
|
||||
$fields,
|
||||
($jush == "sqlite" && ($use_all_fields || $foreign) ? $all_fields : $fields),
|
||||
$foreign,
|
||||
$_POST["Comment"],
|
||||
($_POST["Engine"] && $_POST["Engine"] != $orig_status["Engine"] ? $_POST["Engine"] : ""),
|
||||
|
@@ -43,6 +43,7 @@ if (isset($_GET["mssql"])) {
|
||||
|
||||
function query($query, $unbuffered = false) {
|
||||
$result = sqlsrv_query($this->_link, $query); //! , array(), ($unbuffered ? array() : array("Scrollable" => "keyset"))
|
||||
$this->error = "";
|
||||
if (!$result) {
|
||||
$this->_get_error();
|
||||
return false;
|
||||
@@ -52,6 +53,7 @@ if (isset($_GET["mssql"])) {
|
||||
|
||||
function multi_query($query) {
|
||||
$this->_result = sqlsrv_query($this->_link, $query);
|
||||
$this->error = "";
|
||||
if (!$this->_result) {
|
||||
$this->_get_error();
|
||||
return false;
|
||||
@@ -159,6 +161,7 @@ if (isset($_GET["mssql"])) {
|
||||
|
||||
function query($query, $unbuffered = false) {
|
||||
$result = mssql_query($query, $this->_link); //! $unbuffered
|
||||
$this->error = "";
|
||||
if (!$result) {
|
||||
$this->error = mssql_get_last_message();
|
||||
return false;
|
||||
|
@@ -108,6 +108,7 @@ if (!defined("DRIVER")) {
|
||||
*/
|
||||
function query($query, $unbuffered = false) {
|
||||
$result = @($unbuffered ? mysql_unbuffered_query($query, $this->_link) : mysql_query($query, $this->_link)); // @ - mute mysql.trace_mode
|
||||
$this->error = "";
|
||||
if (!$result) {
|
||||
$this->error = mysql_error($this->_link);
|
||||
return false;
|
||||
@@ -602,7 +603,7 @@ if (!defined("DRIVER")) {
|
||||
$alter = array();
|
||||
foreach ($fields as $field) {
|
||||
$alter[] = ($field[1]
|
||||
? ($table != "" ? ($field[0] != "" ? "CHANGE " . idf_escape($field[0]) : "ADD") : " ") . " " . implode($field[1]) . ($table != "" ? " $field[2]" : "")
|
||||
? ($table != "" ? ($field[0] != "" ? "CHANGE " . idf_escape($field[0]) : "ADD") : " ") . " " . implode($field[1]) . ($table != "" ? $field[2] : "")
|
||||
: "DROP " . idf_escape($field[0])
|
||||
);
|
||||
}
|
||||
@@ -708,7 +709,7 @@ if (!defined("DRIVER")) {
|
||||
|
||||
/** Get information about trigger
|
||||
* @param string trigger name
|
||||
* @return array array("Trigger" => , "Timing" => , "Event" => , "Statement" => )
|
||||
* @return array array("Trigger" => , "Timing" => , "Event" => , "Type" => , "Statement" => )
|
||||
*/
|
||||
function trigger($name) {
|
||||
if ($name == "") {
|
||||
|
@@ -37,6 +37,7 @@ if (isset($_GET["oracle"])) {
|
||||
|
||||
function query($query, $unbuffered = false) {
|
||||
$result = oci_parse($this->_link, $query);
|
||||
$this->error = "";
|
||||
if (!$result) {
|
||||
$error = oci_error($this->_link);
|
||||
$this->error = $error["message"];
|
||||
|
@@ -58,6 +58,7 @@ if (isset($_GET["pgsql"])) {
|
||||
|
||||
function query($query, $unbuffered = false) {
|
||||
$result = @pg_query($this->_link, $query);
|
||||
$this->error = "";
|
||||
if (!$result) {
|
||||
$this->error = pg_last_error($this->_link);
|
||||
return false;
|
||||
|
@@ -19,6 +19,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
||||
|
||||
function query($query) {
|
||||
$result = @$this->_link->query($query);
|
||||
$this->error = "";
|
||||
if (!$result) {
|
||||
$this->error = $this->_link->lastErrorMsg();
|
||||
return false;
|
||||
@@ -93,6 +94,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
||||
function query($query, $unbuffered = false) {
|
||||
$method = ($unbuffered ? "unbufferedQuery" : "query");
|
||||
$result = @$this->_link->$method($query, SQLITE_BOTH, $error);
|
||||
$this->error = "";
|
||||
if (!$result) {
|
||||
$this->error = $error;
|
||||
return false;
|
||||
@@ -248,9 +250,12 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
||||
}
|
||||
|
||||
function table_status($name = "") {
|
||||
global $connection;
|
||||
$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) {
|
||||
$row["Oid"] = "t";
|
||||
$row["Auto_increment"] = "";
|
||||
$row["Rows"] = $connection->result("SELECT COUNT(*) FROM " . idf_escape($row["Name"]));
|
||||
$return[$row["Name"]] = $row;
|
||||
}
|
||||
foreach (get_rows("SELECT * FROM sqlite_sequence", null, "") as $row) {
|
||||
@@ -265,7 +270,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
||||
|
||||
function fk_support($table_status) {
|
||||
global $connection;
|
||||
return $_GET["create"] == "" && !$connection->result("SELECT sqlite_compileoption_used('OMIT_FOREIGN_KEY')");
|
||||
return !$connection->result("SELECT sqlite_compileoption_used('OMIT_FOREIGN_KEY')");
|
||||
}
|
||||
|
||||
function fields($table) {
|
||||
@@ -299,10 +304,12 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
||||
$return[""] = array("type" => "PRIMARY", "columns" => $primary, "lengths" => array());
|
||||
}
|
||||
foreach (get_rows("PRAGMA index_list(" . table($table) . ")") as $row) {
|
||||
$return[$row["name"]]["type"] = ($row["unique"] ? "UNIQUE" : "INDEX");
|
||||
$return[$row["name"]]["lengths"] = array();
|
||||
foreach (get_rows("PRAGMA index_info(" . idf_escape($row["name"]) . ")") as $row1) {
|
||||
$return[$row["name"]]["columns"][] = $row1["name"];
|
||||
if (!ereg("^sqlite_", $row["name"])) {
|
||||
$return[$row["name"]]["type"] = ($row["unique"] ? "UNIQUE" : "INDEX");
|
||||
$return[$row["name"]]["lengths"] = array();
|
||||
foreach (get_rows("PRAGMA index_info(" . idf_escape($row["name"]) . ")") as $row1) {
|
||||
$return[$row["name"]]["columns"][] = $row1["name"];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
@@ -398,14 +405,90 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
||||
}
|
||||
|
||||
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
|
||||
$alter = array();
|
||||
$use_all_fields = ($table == "" || $foreign);
|
||||
foreach ($fields as $field) {
|
||||
if ($field[1]) {
|
||||
$alter[] = ($table != "" && $field[0] == "" ? "ADD " : " ") . implode($field[1]);
|
||||
if ($field[0] != "" || !$field[1] || $field[2]) {
|
||||
$use_all_fields = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$alter = array_merge($alter, $foreign);
|
||||
if ($table != "") {
|
||||
$alter = array();
|
||||
$originals = array();
|
||||
$primary_key = false;
|
||||
foreach ($fields as $field) {
|
||||
if ($field[1]) {
|
||||
if ($field[1][6]) {
|
||||
$primary_key = true;
|
||||
}
|
||||
$alter[] = ($use_all_fields ? " " : "ADD ") . implode($field[1]);
|
||||
if ($field[0] != "") {
|
||||
$originals[$field[0]] = $field[1][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($use_all_fields) {
|
||||
if ($table != "") {
|
||||
queries("BEGIN");
|
||||
foreach (foreign_keys($table) as $foreign_key) {
|
||||
$columns = array();
|
||||
foreach ($foreign_key["source"] as $column) {
|
||||
if (!$originals[$column]) {
|
||||
continue 2;
|
||||
}
|
||||
$columns[] = $originals[$column];
|
||||
}
|
||||
$foreign[] = " FOREIGN KEY (" . implode(", ", $columns) . ") REFERENCES "
|
||||
. table($foreign_key["table"])
|
||||
. " (" . implode(", ", array_map('idf_escape', $foreign_key["target"]))
|
||||
. ") ON DELETE $foreign_key[on_delete] ON UPDATE $foreign_key[on_update]"
|
||||
;
|
||||
}
|
||||
$indexes = array();
|
||||
foreach (indexes($table) as $key_name => $index) {
|
||||
$columns = array();
|
||||
foreach ($index["columns"] as $column) {
|
||||
if (!$originals[$column]) {
|
||||
continue 2;
|
||||
}
|
||||
$columns[] = $originals[$column];
|
||||
}
|
||||
$columns = "(" . implode(", ", $columns) . ")";
|
||||
if ($index["type"] != "PRIMARY") {
|
||||
$indexes[] = array($index["type"], $key_name, $columns);
|
||||
} elseif (!$primary_key) {
|
||||
$foreign[] = " PRIMARY KEY $columns";
|
||||
}
|
||||
}
|
||||
}
|
||||
$alter = array_merge($alter, $foreign);
|
||||
if (!queries("CREATE TABLE " . table($table != "" ? "adminer_$name" : $name) . " (\n" . implode(",\n", $alter) . "\n)")) {
|
||||
// implicit ROLLBACK to not overwrite $connection->error
|
||||
return false;
|
||||
}
|
||||
if ($table != "") {
|
||||
if ($originals && !queries("INSERT INTO " . table("adminer_$name") . " (" . implode(", ", $originals) . ") SELECT " . implode(", ", array_map('idf_escape', array_keys($originals))) . " FROM " . table($table))) {
|
||||
return false;
|
||||
}
|
||||
$triggers = array();
|
||||
foreach (triggers($table) as $trigger_name => $timing_event) {
|
||||
$trigger = trigger($trigger_name);
|
||||
$triggers[] = "CREATE TRIGGER " . idf_escape($trigger_name) . " " . implode(" ", $timing_event) . " ON " . table($name) . "\n$trigger[Statement]";
|
||||
}
|
||||
if (!queries("DROP TABLE " . table($table))) { // drop before creating indexes and triggers to allow using old names
|
||||
return false;
|
||||
}
|
||||
queries("ALTER TABLE " . table("adminer_$name") . " RENAME TO " . table($name));
|
||||
if (!alter_indexes($name, $indexes)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($triggers as $trigger) {
|
||||
if (!queries($trigger)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
queries("COMMIT");
|
||||
}
|
||||
} else {
|
||||
foreach ($alter as $val) {
|
||||
if (!queries("ALTER TABLE " . table($table) . " $val")) {
|
||||
return false;
|
||||
@@ -414,8 +497,6 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
||||
if ($table != $name && !queries("ALTER TABLE " . table($table) . " RENAME TO " . table($name))) {
|
||||
return false;
|
||||
}
|
||||
} elseif (!queries("CREATE TABLE " . table($name) . " (\n" . implode(",\n", $alter) . "\n)")) {
|
||||
return false;
|
||||
}
|
||||
if ($auto_increment) {
|
||||
queries("UPDATE sqlite_sequence SET seq = $auto_increment WHERE name = " . q($name)); // ignores error
|
||||
@@ -563,7 +644,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
|
||||
}
|
||||
|
||||
function support($feature) {
|
||||
return ereg('^(view|trigger|variables|status|dump)$', $feature);
|
||||
return ereg('^(view|trigger|variables|status|dump|move_col|drop_col)$', $feature);
|
||||
}
|
||||
|
||||
$jush = "sqlite";
|
||||
|
@@ -48,14 +48,14 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
|
||||
foreach (array("FUNCTION", "PROCEDURE") as $routine) {
|
||||
foreach (get_rows("SHOW $routine STATUS WHERE Db = " . q($db), null, "-- ") as $row) {
|
||||
$out .= ($style != 'DROP+CREATE' ? "DROP $routine IF EXISTS " . idf_escape($row["Name"]) . ";;\n" : "")
|
||||
. $connection->result("SHOW CREATE $routine " . idf_escape($row["Name"]), 2) . ";;\n\n";
|
||||
. remove_definer($connection->result("SHOW CREATE $routine " . idf_escape($row["Name"]), 2)) . ";;\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($_POST["events"]) {
|
||||
foreach (get_rows("SHOW EVENTS", null, "-- ") as $row) {
|
||||
$out .= ($style != 'DROP+CREATE' ? "DROP EVENT IF EXISTS " . idf_escape($row["Name"]) . ";;\n" : "")
|
||||
. $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) {
|
||||
@@ -197,11 +197,11 @@ if (DB != "") {
|
||||
$name = $table_status["Name"];
|
||||
$prefix = ereg_replace("_.*", "", $name);
|
||||
$checked = ($TABLE == "" || $TABLE == (substr($TABLE, -1) == "%" ? "$prefix%" : $name)); //! % may be part of table name
|
||||
$print = "<tr><td>" . checkbox("tables[]", $name, $checked, $name, "formUncheck('check-tables');");
|
||||
$print = "<tr><td>" . checkbox("tables[]", $name, $checked, $name, "checkboxClick(event, this); formUncheck('check-tables');");
|
||||
if (is_view($table_status)) {
|
||||
$views .= "$print\n";
|
||||
} else {
|
||||
echo "$print<td align='right'><label>" . ($table_status["Engine"] == "InnoDB" && $table_status["Rows"] ? "~ " : "") . $table_status["Rows"] . checkbox("data[]", $name, $checked, "", "formUncheck('check-data');") . "</label>\n";
|
||||
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";
|
||||
}
|
||||
$prefixes[$prefix]++;
|
||||
}
|
||||
|
@@ -53,7 +53,7 @@ if ($_POST["save"]) {
|
||||
$select = array();
|
||||
foreach ($fields as $name => $field) {
|
||||
if (isset($field["privileges"]["select"])) {
|
||||
$select[] = ($_POST["clone"] && $field["auto_increment"] ? "'' AS " : (ereg("enum|set", $field["type"]) ? "1*" . idf_escape($name) . " AS " : "")) . idf_escape($name);
|
||||
$select[] = ($_POST["clone"] && $field["auto_increment"] ? "'' AS " : ($jush == "sql" && ereg("enum|set", $field["type"]) ? "1*" . idf_escape($name) . " AS " : "")) . idf_escape($name);
|
||||
}
|
||||
}
|
||||
$row = array();
|
||||
@@ -76,7 +76,7 @@ if ($fields) {
|
||||
echo "<tr><th>" . $adminer->fieldName($field);
|
||||
$default = $_GET["set"][bracket_escape($name)];
|
||||
$value = ($row !== null
|
||||
? ($row[$name] != "" && 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"])))
|
||||
);
|
||||
if (!$_POST["save"] && is_string($value)) {
|
||||
|
@@ -214,7 +214,7 @@ username.form['auth[driver]'].onchange();
|
||||
foreach ($select as $key => $val) {
|
||||
$val = $_GET["columns"][$key];
|
||||
echo "<div>" . html_select("columns[$i][fun]", array(-1 => "") + $fun_group, $val["fun"]);
|
||||
echo "(<select name='columns[$i][col]'><option>" . optionlist($columns, $val["col"], true) . "</select>)</div>\n";
|
||||
echo "(<select name='columns[$i][col]' onchange='selectFieldChange(this.form);'><option>" . optionlist($columns, $val["col"], true) . "</select>)</div>\n";
|
||||
$i++;
|
||||
}
|
||||
echo "<div>" . html_select("columns[$i][fun]", array(-1 => "") + $fun_group, "", "this.nextSibling.nextSibling.onchange();");
|
||||
@@ -279,7 +279,7 @@ username.form['auth[driver]'].onchange();
|
||||
*/
|
||||
function selectLimitPrint($limit) {
|
||||
echo "<fieldset><legend>" . lang('Limit') . "</legend><div>"; // <div> for easy styling
|
||||
echo "<input name='limit' size='3' value='" . h($limit) . "'>";
|
||||
echo "<input name='limit' size='3' value='" . h($limit) . "' onchange='selectFieldChange(this.form);'>";
|
||||
echo "</div></fieldset>\n";
|
||||
}
|
||||
|
||||
@@ -395,7 +395,7 @@ username.form['auth[driver]'].onchange();
|
||||
// find anywhere
|
||||
$cols = array();
|
||||
foreach ($fields as $name => $field) {
|
||||
if (is_numeric($val["val"]) || !ereg('int|float|double|decimal', $field["type"])) {
|
||||
if (is_numeric($val["val"]) || !ereg('int|float|double|decimal|bit', $field["type"])) {
|
||||
$name = idf_escape($name);
|
||||
$cols[] = ($jush == "sql" && ereg('char|text|enum|set', $field["type"]) && !ereg('^utf8', $field["collation"]) ? "CONVERT($name USING utf8)" : $name);
|
||||
}
|
||||
@@ -573,8 +573,7 @@ username.form['auth[driver]'].onchange();
|
||||
echo "DROP " . ($is_view ? "VIEW" : "TABLE") . " IF EXISTS " . table($table) . ";\n";
|
||||
}
|
||||
if ($is_view) {
|
||||
// remove DEFINER with current user
|
||||
$create = preg_replace('~^([A-Z =]+) DEFINER=`' . preg_replace('~@(.*)~', '`@`(%|\\1)', logged_user()) . '`~', '\\1', $create); //! proper escaping of user
|
||||
$create = remove_definer($create);
|
||||
}
|
||||
echo ($style != "CREATE+ALTER" ? $create : ($is_view ? substr_replace($create, " OR REPLACE", 6, 0) : substr_replace($create, " IF NOT EXISTS", 12, 0))) . ";\n\n";
|
||||
}
|
||||
@@ -672,25 +671,32 @@ DROP PROCEDURE adminer_alter;
|
||||
if ($result) {
|
||||
$insert = "";
|
||||
$buffer = "";
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$keys = array();
|
||||
while ($row = $result->fetch_row()) {
|
||||
if (!$keys) {
|
||||
foreach ($row as $val) {
|
||||
$field = $result->fetch_field();
|
||||
$keys[] = $field->name;
|
||||
}
|
||||
}
|
||||
if ($_POST["format"] != "sql") {
|
||||
if ($style == "table") {
|
||||
dump_csv(array_keys($row));
|
||||
dump_csv($keys);
|
||||
$style = "INSERT";
|
||||
}
|
||||
dump_csv($row);
|
||||
} else {
|
||||
if (!$insert) {
|
||||
$insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('idf_escape', array_keys($row))) . ") VALUES";
|
||||
$insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('idf_escape', $keys)) . ") VALUES";
|
||||
}
|
||||
foreach ($row as $key => $val) {
|
||||
$row[$key] = ($val !== null ? (ereg('int|float|double|decimal|bit', $fields[$key]["type"]) ? $val : q($val)) : "NULL"); //! columns looking like functions
|
||||
$row[$key] = ($val !== null ? (ereg('int|float|double|decimal|bit', $fields[$keys[$key]]["type"]) ? $val : q($val)) : "NULL"); //! columns looking like functions
|
||||
}
|
||||
$s = implode(",\t", $row);
|
||||
if ($style == "INSERT+UPDATE") {
|
||||
$set = array();
|
||||
foreach ($row as $key => $val) {
|
||||
$set[] = idf_escape($key) . " = $val";
|
||||
$set[] = idf_escape($keys[$key]) . " = $val";
|
||||
}
|
||||
echo "$insert ($s) ON DUPLICATE KEY UPDATE " . implode(", ", $set) . ";\n";
|
||||
} else {
|
||||
@@ -777,7 +783,7 @@ DROP PROCEDURE adminer_alter;
|
||||
foreach ($usernames as $username => $password) {
|
||||
if ($password !== null) {
|
||||
if ($first) {
|
||||
echo "<p>\n";
|
||||
echo "<p id='logins' onmouseover='menuOver(this);' onmouseout='menuOut(this);'>\n";
|
||||
$first = false;
|
||||
}
|
||||
echo "<a href='" . h(auth_url($driver, $server, $username)) . "'>($drivers[$driver]) " . h($username . ($server != "" ? "@$server" : "")) . "</a><br>\n";
|
||||
@@ -803,7 +809,7 @@ DROP PROCEDURE adminer_alter;
|
||||
</p>
|
||||
</form>
|
||||
<form action="">
|
||||
<p>
|
||||
<p id="dbs">
|
||||
<?php hidden_fields_get(); ?>
|
||||
<?php echo ($databases ? html_select("db", array("" => "(" . lang('database') . ")") + $databases, DB, "this.form.submit();") : '<input name="db" value="' . h(DB) . '">'); ?>
|
||||
<input type="submit" value="<?php echo lang('Use'); ?>"<?php echo ($databases ? " class='hidden'" : ""); ?>>
|
||||
@@ -815,31 +821,31 @@ DROP PROCEDURE adminer_alter;
|
||||
set_schema($_GET["ns"]);
|
||||
}
|
||||
}
|
||||
if ($_GET["ns"] !== "" && !$missing) {
|
||||
echo '<p><a href="' . h(ME) . 'create="' . bold($_GET["create"] === "") . ">" . lang('Create new table') . "</a>\n";
|
||||
$tables = tables_list();
|
||||
if (!$tables) {
|
||||
echo "<p class='message'>" . lang('No tables.') . "\n";
|
||||
} else {
|
||||
$this->tablesPrint($tables);
|
||||
$links = array();
|
||||
foreach ($tables as $table => $type) {
|
||||
$links[] = preg_quote($table, '/');
|
||||
}
|
||||
echo "<script type='text/javascript'>\n";
|
||||
echo "var jushLinks = { $jush: [ '" . js_escape(ME) . "table=\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n";
|
||||
foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) {
|
||||
echo "jushLinks.$val = jushLinks.$jush;\n";
|
||||
}
|
||||
echo "</script>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
echo (isset($_GET["sql"]) ? '<input type="hidden" name="sql" value="">'
|
||||
: (isset($_GET["schema"]) ? '<input type="hidden" name="schema" value="">'
|
||||
: (isset($_GET["dump"]) ? '<input type="hidden" name="dump" value="">'
|
||||
: "")));
|
||||
echo "</p></form>\n";
|
||||
if ($_GET["ns"] !== "" && !$missing && DB != "") {
|
||||
echo '<p><a href="' . h(ME) . 'create="' . bold($_GET["create"] === "") . ">" . lang('Create new table') . "</a>\n";
|
||||
$tables = tables_list();
|
||||
if (!$tables) {
|
||||
echo "<p class='message'>" . lang('No tables.') . "\n";
|
||||
} else {
|
||||
$this->tablesPrint($tables);
|
||||
$links = array();
|
||||
foreach ($tables as $table => $type) {
|
||||
$links[] = preg_quote($table, '/');
|
||||
}
|
||||
echo "<script type='text/javascript'>\n";
|
||||
echo "var jushLinks = { $jush: [ '" . js_escape(ME) . "table=\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n";
|
||||
foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) {
|
||||
echo "jushLinks.$val = jushLinks.$jush;\n";
|
||||
}
|
||||
echo "</script>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -848,7 +854,7 @@ DROP PROCEDURE adminer_alter;
|
||||
* @return null
|
||||
*/
|
||||
function tablesPrint($tables) {
|
||||
echo "<p id='tables'>\n";
|
||||
echo "<p id='tables' onmouseover='menuOver(this);' onmouseout='menuOut(this);'>\n";
|
||||
foreach ($tables as $table => $type) {
|
||||
echo '<a href="' . h(ME) . 'select=' . urlencode($table) . '"' . bold($_GET["select"] == $table) . ">" . lang('select') . "</a> ";
|
||||
echo '<a href="' . h(ME) . 'table=' . urlencode($table) . '"' . bold($_GET["table"] == $table) . " title='" . lang('Show structure') . "'>" . $this->tableName(array("Name" => $table)) . "</a><br>\n"; //! Adminer::tableName may work with full table status
|
||||
|
@@ -357,6 +357,14 @@ function drop_create($drop, $create, $location, $message_drop, $message_alter, $
|
||||
return $dropped;
|
||||
}
|
||||
|
||||
/** Remove current user definer from SQL command
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function remove_definer($query) {
|
||||
return preg_replace('~^([A-Z =]+) DEFINER=`' . preg_replace('~@(.*)~', '`@`(%|\\1)', logged_user()) . '`~', '\\1', $query); //! proper escaping of user
|
||||
}
|
||||
|
||||
/** Get string to add a file in TAR
|
||||
* @param string
|
||||
* @param string
|
||||
|
@@ -24,6 +24,7 @@ if (extension_loaded('pdo')) {
|
||||
|
||||
function query($query, $unbuffered = false) {
|
||||
$result = parent::query($query);
|
||||
$this->error = "";
|
||||
if (!$result) {
|
||||
$errorInfo = $this->errorInfo();
|
||||
$this->error = $errorInfo[2];
|
||||
|
@@ -1,2 +1,2 @@
|
||||
<?php
|
||||
$VERSION = "3.4.0";
|
||||
$VERSION = "3.5.1";
|
||||
|
@@ -24,7 +24,7 @@ foreach (process_list() as $i => $row) {
|
||||
echo "<tr" . odd() . ">" . (support("kill") ? "<td>" . checkbox("kill[]", $row["Id"], 0) : "");
|
||||
foreach ($row as $key => $val) {
|
||||
echo "<td>" . (
|
||||
($jush == "sql" && $key == "Info" && $row["Command"] == "Query" && $val != "") ||
|
||||
($jush == "sql" && $key == "Info" && ereg("Query|Killed", $row["Command"]) && $val != "") ||
|
||||
($jush == "pgsql" && $key == "current_query" && $val != "<IDLE>") ||
|
||||
($jush == "oracle" && $key == "sql_text" && $val != "")
|
||||
? "<code class='jush-$jush'>" . shorten_utf8($val, 100, "</code>") . ' <a href="' . h(ME . ($row["db"] != "" ? "db=" . urlencode($row["db"]) . "&" : "") . "sql=" . urlencode($val)) . '">' . lang('Edit') . '</a>'
|
||||
|
@@ -13,10 +13,10 @@ if ($_GET["script"] == "db") {
|
||||
foreach ($sums + array("Auto_increment" => 0, "Rows" => 0) as $key => $val) {
|
||||
if ($table_status[$key] != "") {
|
||||
$val = number_format($table_status[$key], 0, '.', lang(','));
|
||||
json_row("$key-$id", ($key == "Rows" && $val && (
|
||||
$table_status["Engine"] == "InnoDB" || // MySQL InnoDB
|
||||
$table_status["Engine"] == "table" // PostgreSQL table reltype
|
||||
) ? "~ $val" : $val));
|
||||
json_row("$key-$id", ($key == "Rows" && $val && $table_status["Engine"] == ($sql == "pgsql" ? "table" : "InnoDB")
|
||||
? "~ $val"
|
||||
: $val
|
||||
));
|
||||
if (isset($sums[$key])) {
|
||||
// ignore innodb_file_per_table because it is not active for tables created before it was enabled
|
||||
$sums[$key] += ($table_status["Engine"] != "InnoDB" || $key != "Data_free" ? $table_status[$key] : 0);
|
||||
|
@@ -4,8 +4,10 @@ $table_status = table_status($TABLE);
|
||||
$indexes = indexes($TABLE);
|
||||
$fields = fields($TABLE);
|
||||
$foreign_keys = column_foreign_keys($TABLE);
|
||||
$oid = "";
|
||||
if ($table_status["Oid"] == "t") {
|
||||
$indexes[] = array("type" => "PRIMARY", "columns" => array("oid"));
|
||||
$oid = ($jush == "sqlite" ? "rowid" : "oid");
|
||||
$indexes[] = array("type" => "PRIMARY", "columns" => array($oid));
|
||||
}
|
||||
parse_str($_COOKIE["adminer_import"], $adminer_import);
|
||||
|
||||
@@ -27,7 +29,7 @@ list($select, $group) = $adminer->selectColumnsProcess($columns, $indexes);
|
||||
$where = $adminer->selectSearchProcess($fields, $indexes);
|
||||
$order = $adminer->selectOrderProcess($fields, $indexes);
|
||||
$limit = $adminer->selectLimitProcess();
|
||||
$from = ($select ? implode(", ", $select) : ($table_status["Oid"] == "t" ? "oid, " : "") . "*") . "\nFROM " . table($TABLE);
|
||||
$from = ($select ? implode(", ", $select) : ($oid ? "$oid, " : "") . "*") . "\nFROM " . table($TABLE);
|
||||
$group_by = ($group && count($group) < count($select) ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : "");
|
||||
|
||||
if ($_GET["val"] && is_ajax()) {
|
||||
@@ -104,7 +106,7 @@ if ($_POST && !$error) {
|
||||
$query = "INTO $query";
|
||||
}
|
||||
if ($_POST["all"] || ($unselected === array() && $_POST["check"]) || count($group) < count($select)) {
|
||||
$result = queries($command . " $query" . ($_POST["all"] ? ($where ? "\nWHERE " . implode(" AND ", $where) : "") : "\nWHERE $where_check"));
|
||||
$result = queries("$command $query" . ($_POST["all"] ? ($where ? "\nWHERE " . implode(" AND ", $where) : "") : "\nWHERE $where_check"));
|
||||
$affected = $connection->affected_rows;
|
||||
} else {
|
||||
foreach ((array) $_POST["check"] as $val) {
|
||||
@@ -117,7 +119,14 @@ if ($_POST && !$error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
queries_redirect(remove_from_uri("page"), lang('%d item(s) have been affected.', $affected), $result);
|
||||
$message = lang('%d item(s) have been affected.', $affected);
|
||||
if ($_POST["clone"] && $result && $affected == 1) {
|
||||
$last_id = last_id();
|
||||
if ($last_id) {
|
||||
$message = lang('Item%s has been inserted.', " $last_id");
|
||||
}
|
||||
}
|
||||
queries_redirect(remove_from_uri("page"), $message, $result);
|
||||
//! display edit page in case of an error
|
||||
} elseif (!$_POST["import"]) { // modify
|
||||
if (!$_POST["val"]) {
|
||||
@@ -257,7 +266,7 @@ if (!$columns) {
|
||||
reset($select);
|
||||
$rank = 1;
|
||||
foreach ($rows[0] as $key => $val) {
|
||||
if ($table_status["Oid"] != "t" || $key != "oid") {
|
||||
if ($key != $oid) {
|
||||
$val = $_GET["columns"][key($select)];
|
||||
$field = $fields[$select ? ($val ? $val["col"] : current($select)) : $key];
|
||||
$name = ($field ? $adminer->fieldName($field, $rank) : "*");
|
||||
@@ -266,8 +275,16 @@ if (!$columns) {
|
||||
$names[$key] = $name;
|
||||
$column = idf_escape($key);
|
||||
$href = remove_from_uri('(order|desc)[^=]*|page') . '&order%5B0%5D=' . urlencode($key);
|
||||
echo '<th><a href="' . h($href) . '">' . (!$select || $val ? apply_sql_function($val["fun"], $name) : h(current($select))) . "</a>"; //! columns looking like functions
|
||||
echo "<a href='" . h("$href&desc%5B0%5D=1") . "' title='" . lang('descending') . "' class='text'> ↓</a>";
|
||||
$desc = "&desc%5B0%5D=1";
|
||||
echo '<th onmouseover="columnMouse(this);" onmouseout="columnMouse(this, \' hidden\');">';
|
||||
echo '<a href="' . h($href . ($order[0] == $column || $order[0] == $key || (!$order && count($group) < count($select) && $group[0] == $column) ? $desc : '')) . '">'; // $order[0] == $key - COUNT(*)
|
||||
echo (!$select || $val ? apply_sql_function($val["fun"], $name) : h(current($select))) . "</a>"; //! columns looking like functions
|
||||
echo "<span class='column hidden'>";
|
||||
echo "<a href='" . h($href . $desc) . "' title='" . lang('descending') . "' class='text'> ↓</a>";
|
||||
if (!$val["fun"]) {
|
||||
echo '<a href="#fieldset-search" onclick="selectSearch(\'' . h(js_escape($key)) . '\'); return false;" title="' . lang('Search') . '" class="text jsonly"> =</a>';
|
||||
}
|
||||
echo "</span>";
|
||||
}
|
||||
$functions[$key] = $val["fun"];
|
||||
next($select);
|
||||
|
@@ -58,7 +58,7 @@ if (!$error && $_POST) {
|
||||
$dump_format = $adminer->dumpFormat();
|
||||
unset($dump_format["sql"]);
|
||||
while ($query != "") {
|
||||
if (!$offset && preg_match("~^$space*DELIMITER\\s+(.+)~i", $query, $match)) {
|
||||
if (!$offset && preg_match("~^$space*DELIMITER\\s+(\\S+)~i", $query, $match)) {
|
||||
$delimiter = $match[1];
|
||||
$query = substr($query, strlen($match[0]));
|
||||
} else {
|
||||
|
@@ -23,6 +23,7 @@ pre { margin: 1em 0 0; }
|
||||
input[type=image] { vertical-align: middle; }
|
||||
.version { color: #777; font-size: 67%; }
|
||||
.js .hidden, .nojs .jsonly { display: none; }
|
||||
.js .column { position: absolute; background: #ddf; padding: .3em 1ex .3em 0; margin-top: -.3em; }
|
||||
.nowrap td, .nowrap th, td.nowrap { white-space: pre; }
|
||||
.wrap td { white-space: normal; }
|
||||
.error { color: red; background: #fee; }
|
||||
@@ -44,8 +45,11 @@ input[type=image] { vertical-align: middle; }
|
||||
.active { font-weight: bold; }
|
||||
.sqlarea { width: 98%; }
|
||||
.icon { width: 18px; height: 18px; }
|
||||
#menu { position: absolute; margin: 10px 0 0; padding: 0 0 30px 0; top: 2em; left: 0; width: 19em; overflow: auto; overflow-y: hidden; white-space: nowrap; }
|
||||
#menu { position: absolute; margin: 10px 0 0; padding: 0 0 30px 0; top: 2em; left: 0; width: 19em; white-space: nowrap; }
|
||||
#menu p { padding: .8em 1em; margin: 0; border-bottom: 1px solid #ccc; }
|
||||
#dbs { overflow: hidden; }
|
||||
#logins, #tables { overflow: auto; }
|
||||
#logins a, #tables a { background: #fff; }
|
||||
#content { margin: 2em 0 0 21em; padding: 10px 20px 20px 0; }
|
||||
#lang { position: absolute; top: 0; left: 0; line-height: 1.8em; padding: .3em 1em; }
|
||||
#breadcrumb { white-space: nowrap; position: absolute; top: 0; left: 21em; background: #eee; height: 2em; line-height: 1.8em; padding: 0 1em; margin: 0 0 0 -18px; }
|
||||
|
@@ -64,7 +64,7 @@ function typePassword(el, disable) {
|
||||
}
|
||||
|
||||
function loginDriver(driver) {
|
||||
var trs = driver.parentNode.parentNode.parentNode.rows;
|
||||
var trs = parentTag(driver, 'table').rows;
|
||||
for (var i=1; i < trs.length - 1; i++) {
|
||||
trs[i].className = (/sqlite/.test(driver.value) ? 'hidden' : '');
|
||||
}
|
||||
@@ -109,6 +109,64 @@ function textareaKeydown(target, event) {
|
||||
|
||||
|
||||
|
||||
/** Check whether the query will be executed with index
|
||||
* @param HTMLFormElement
|
||||
*/
|
||||
function selectFieldChange(form) {
|
||||
var ok = (function () {
|
||||
var inputs = form.getElementsByTagName('input');
|
||||
for (var i=0; i < inputs.length; i++) {
|
||||
if (inputs[i].value && /^fulltext/.test(inputs[i].name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
var ok = form.limit.value;
|
||||
var selects = form.getElementsByTagName('select');
|
||||
var group = false;
|
||||
var columns = {};
|
||||
for (var i=0; i < selects.length; i++) {
|
||||
var select = selects[i];
|
||||
var col = selectValue(select);
|
||||
var match = /^(where.+)col\]/.exec(select.name);
|
||||
if (match) {
|
||||
var op = selectValue(form[match[1] + 'op]']);
|
||||
var val = form[match[1] + 'val]'].value;
|
||||
if (col in indexColumns && (!/LIKE|REGEXP/.test(op) || (op == 'LIKE' && val.charAt(0) != '%'))) {
|
||||
return true;
|
||||
} else if (col || val) {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if ((match = /^(columns.+)fun\]/.exec(select.name))) {
|
||||
if (/^(avg|count|count distinct|group_concat|max|min|sum)$/.test(col)) {
|
||||
group = true;
|
||||
}
|
||||
var val = selectValue(form[match[1] + 'col]']);
|
||||
if (val) {
|
||||
columns[col && col != 'count' ? '' : val] = 1;
|
||||
}
|
||||
}
|
||||
if (col && /^order/.test(select.name)) {
|
||||
if (!(col in indexColumns)) {
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (group) {
|
||||
for (var col in columns) {
|
||||
if (!(col in indexColumns)) {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
})();
|
||||
setHtml('noindex', (ok ? '' : '!'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
var added = '.', rowCount;
|
||||
|
||||
/** Check if val is equal to a-delimiter-b where delimiter is '_', '' or big letter
|
||||
@@ -178,7 +236,7 @@ function editingAddRow(button, allowed, focus) {
|
||||
}
|
||||
var match = /(\d+)(\.\d+)?/.exec(button.name);
|
||||
var x = match[0] + (match[2] ? added.substr(match[2].length) : added) + '1';
|
||||
var row = button.parentNode.parentNode;
|
||||
var row = parentTag(button, 'tr');
|
||||
var row2 = row.cloneNode(true);
|
||||
var tags = row.getElementsByTagName('select');
|
||||
var tags2 = row2.getElementsByTagName('select');
|
||||
@@ -224,7 +282,7 @@ function editingAddRow(button, allowed, focus) {
|
||||
function editingRemoveRow(button) {
|
||||
var field = formField(button.form, button.name.replace(/drop_col(.+)/, 'fields$1[field]'));
|
||||
field.parentNode.removeChild(field);
|
||||
button.parentNode.parentNode.style.display = 'none';
|
||||
parentTag(button, 'tr').style.display = 'none';
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -310,9 +368,9 @@ function partitionByChange(el) {
|
||||
* @param HTMLInputElement
|
||||
*/
|
||||
function partitionNameChange(el) {
|
||||
var row = el.parentNode.parentNode.cloneNode(true);
|
||||
var row = parentTag(el, 'tr').cloneNode(true);
|
||||
row.firstChild.firstChild.value = '';
|
||||
el.parentNode.parentNode.parentNode.appendChild(row);
|
||||
parentTag(el, 'table').appendChild(row);
|
||||
el.onchange = function () {};
|
||||
}
|
||||
|
||||
@@ -323,13 +381,13 @@ function partitionNameChange(el) {
|
||||
*/
|
||||
function foreignAddRow(field) {
|
||||
field.onchange = function () { };
|
||||
var row = field.parentNode.parentNode.cloneNode(true);
|
||||
var row = parentTag(field, 'tr').cloneNode(true);
|
||||
var selects = row.getElementsByTagName('select');
|
||||
for (var i=0; i < selects.length; i++) {
|
||||
selects[i].name = selects[i].name.replace(/\]/, '1$&');
|
||||
selects[i].selectedIndex = 0;
|
||||
}
|
||||
field.parentNode.parentNode.parentNode.appendChild(row);
|
||||
parentTag(field, 'table').appendChild(row);
|
||||
}
|
||||
|
||||
|
||||
@@ -339,8 +397,7 @@ function foreignAddRow(field) {
|
||||
*/
|
||||
function indexesAddRow(field) {
|
||||
field.onchange = function () { };
|
||||
var parent = field.parentNode.parentNode;
|
||||
var row = parent.cloneNode(true);
|
||||
var row = parentTag(field, 'tr').cloneNode(true);
|
||||
var selects = row.getElementsByTagName('select');
|
||||
for (var i=0; i < selects.length; i++) {
|
||||
selects[i].name = selects[i].name.replace(/indexes\[\d+/, '$&1');
|
||||
@@ -351,7 +408,7 @@ function indexesAddRow(field) {
|
||||
inputs[i].name = inputs[i].name.replace(/indexes\[\d+/, '$&1');
|
||||
inputs[i].value = '';
|
||||
}
|
||||
parent.parentNode.appendChild(row);
|
||||
parentTag(field, 'table').appendChild(row);
|
||||
}
|
||||
|
||||
/** Change column in index
|
||||
@@ -359,7 +416,7 @@ function indexesAddRow(field) {
|
||||
* @param string name prefix
|
||||
*/
|
||||
function indexesChangeColumn(field, prefix) {
|
||||
var columns = field.parentNode.parentNode.getElementsByTagName('select');
|
||||
var columns = parentTag(field, 'td').getElementsByTagName('select');
|
||||
var names = [];
|
||||
for (var i=0; i < columns.length; i++) {
|
||||
var value = selectValue(columns[i]);
|
||||
@@ -390,7 +447,7 @@ function indexesAddColumn(field, prefix) {
|
||||
var input = column.getElementsByTagName('input')[0];
|
||||
input.name = input.name.replace(/\]\[\d+/, '$&1');
|
||||
input.value = '';
|
||||
field.parentNode.parentNode.appendChild(column);
|
||||
parentTag(field, 'td').appendChild(column);
|
||||
field.onchange();
|
||||
}
|
||||
|
||||
|
@@ -38,11 +38,24 @@ function selectValue(select) {
|
||||
return ((selected.attributes.value || {}).specified ? selected.value : selected.text);
|
||||
}
|
||||
|
||||
/** Get parent node with specified tag name.
|
||||
* @param HTMLElement
|
||||
* @param string
|
||||
* @return HTMLElement
|
||||
*/
|
||||
function parentTag(el, tag) {
|
||||
var re = new RegExp('^' + tag + '$', 'i');
|
||||
while (!re.test(el.tagName)) {
|
||||
el = el.parentNode;
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
/** Set checked class
|
||||
* @param HTMLInputElement
|
||||
*/
|
||||
function trCheck(el) {
|
||||
var tr = el.parentNode.parentNode;
|
||||
var tr = parentTag(el, 'tr');
|
||||
tr.className = tr.className.replace(/(^|\s)checked(\s|$)/, '$2') + (el.checked ? ' checked' : '');
|
||||
}
|
||||
|
||||
@@ -135,7 +148,7 @@ function checkboxClick(event, el) {
|
||||
}
|
||||
if (event.shiftKey && (!lastChecked || lastChecked.name == el.name)) {
|
||||
var checked = (lastChecked ? lastChecked.checked : true);
|
||||
var inputs = el.parentNode.parentNode.parentNode.getElementsByTagName('input');
|
||||
var inputs = parentTag(el, 'table').getElementsByTagName('input');
|
||||
var checking = !lastChecked;
|
||||
for (var i=0; i < inputs.length; i++) {
|
||||
var input = inputs[i];
|
||||
@@ -152,8 +165,9 @@ function checkboxClick(event, el) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lastChecked = el;
|
||||
}
|
||||
lastChecked = el;
|
||||
}
|
||||
|
||||
/** Set HTML code of an element
|
||||
@@ -195,6 +209,14 @@ function pageClick(href, page, event) {
|
||||
}
|
||||
}
|
||||
|
||||
function menuOver(el) {
|
||||
el.style.overflow = 'visible';
|
||||
}
|
||||
|
||||
function menuOut(el) {
|
||||
el.style.overflow = 'auto';
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Add row in select fieldset
|
||||
@@ -220,44 +242,41 @@ function selectAddRow(field) {
|
||||
field.parentNode.parentNode.appendChild(row);
|
||||
}
|
||||
|
||||
/** Check whether the query will be executed with index
|
||||
* @param HTMLFormElement
|
||||
*/
|
||||
function selectFieldChange(form) {
|
||||
var ok = (function () {
|
||||
var inputs = form.getElementsByTagName('input');
|
||||
for (var i=0; i < inputs.length; i++) {
|
||||
var input = inputs[i];
|
||||
if (/^fulltext/.test(input.name) && input.value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** Toggles column context menu
|
||||
* @param HTMLElement
|
||||
* @param [string] extra class name
|
||||
*/
|
||||
function columnMouse(el, className) {
|
||||
var spans = el.getElementsByTagName('span');
|
||||
for (var i=0; i < spans.length; i++) {
|
||||
if (/column/.test(spans[i].className)) {
|
||||
spans[i].className = 'column' + (className || '');
|
||||
}
|
||||
var ok = true;
|
||||
var selects = form.getElementsByTagName('select');
|
||||
for (var i=0; i < selects.length; i++) {
|
||||
var select = selects[i];
|
||||
var col = selectValue(select);
|
||||
var match = /^(where.+)col\]/.exec(select.name);
|
||||
if (match) {
|
||||
var op = selectValue(form[match[1] + 'op]']);
|
||||
var val = form[match[1] + 'val]'].value;
|
||||
if (col in indexColumns && (!/LIKE|REGEXP/.test(op) || (op == 'LIKE' && val.charAt(0) != '%'))) {
|
||||
return true;
|
||||
} else if (col || val) {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
//! take grouping in select into account
|
||||
if (col && /^order/.test(select.name)) {
|
||||
if (!(col in indexColumns)) {
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Fill column in search field
|
||||
* @param string
|
||||
*/
|
||||
function selectSearch(name) {
|
||||
var el = document.getElementById('fieldset-search');
|
||||
el.className = '';
|
||||
var divs = el.getElementsByTagName('div');
|
||||
for (var i=0; i < divs.length; i++) {
|
||||
var div = divs[i];
|
||||
if (/select/i.test(div.firstChild.tagName) && selectValue(div.firstChild) == name) {
|
||||
break;
|
||||
}
|
||||
return ok;
|
||||
})();
|
||||
setHtml('noindex', (ok ? '' : '!'));
|
||||
}
|
||||
if (i == divs.length) {
|
||||
div.firstChild.value = name;
|
||||
div.firstChild.onchange();
|
||||
}
|
||||
div.lastChild.focus();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -58,9 +58,7 @@ if ($fields) {
|
||||
echo "(<i>" . implode("</i>, <i>", array_map('h', $foreign_key["target"])) . "</i>)";
|
||||
echo "<td>" . nbsp($foreign_key["on_delete"]) . "\n";
|
||||
echo "<td>" . nbsp($foreign_key["on_update"]) . "\n";
|
||||
if ($jush != "sqlite") {
|
||||
echo '<td><a href="' . h(ME . 'foreign=' . urlencode($TABLE) . '&name=' . urlencode($name)) . '">' . lang('Alter') . '</a>';
|
||||
}
|
||||
echo ($jush == "sqlite" ? "" : '<td><a href="' . h(ME . 'foreign=' . urlencode($TABLE) . '&name=' . urlencode($name)) . '">' . lang('Alter') . '</a>');
|
||||
}
|
||||
echo "</table>\n";
|
||||
}
|
||||
|
13
changes.txt
13
changes.txt
@@ -1,3 +1,16 @@
|
||||
Adminer 3.5.1 (released 2012-08-10):
|
||||
Support same name fields in CSV export
|
||||
Support Shift+click in export
|
||||
|
||||
Adminer 3.5.0 (released 2012-08-05):
|
||||
Links for column search in select
|
||||
Autohide column context menu in select
|
||||
Autodisplay long table names in tables list
|
||||
Display assigned auto_increment after clone
|
||||
SQLite: Full alter table
|
||||
SQLite: Better editing in tables without primary key
|
||||
SQLite: Display number of rows in database overview
|
||||
|
||||
Adminer 3.4.0 (released 2012-06-30):
|
||||
Link to descending order
|
||||
Shift+click on checkbox to select consecutive rows
|
||||
|
@@ -193,7 +193,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
|
||||
|
||||
function selectSearchPrint($where, $columns, $indexes) {
|
||||
$where = (array) $_GET["where"];
|
||||
echo '<fieldset><legend>' . lang('Search') . "</legend><div>\n";
|
||||
echo '<fieldset id="fieldset-search"><legend>' . lang('Search') . "</legend><div>\n";
|
||||
$keys = array();
|
||||
foreach ($where as $key => $val) {
|
||||
$keys[$val["col"]] = $key;
|
||||
@@ -532,7 +532,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
|
||||
foreach ((array) $_SESSION["pwds"]["server"][""] as $username => $password) {
|
||||
if ($password !== null) {
|
||||
if ($first) {
|
||||
echo "<p>\n";
|
||||
echo "<p id='logins' onmouseover='menuOver(this);' onmouseout='menuOut(this);'>\n";
|
||||
$first = false;
|
||||
}
|
||||
echo "<a href='" . h(auth_url("server", "", $username)) . "'>" . ($username != "" ? h($username) : "<i>" . lang('empty') . "</i>") . "</a><br>\n";
|
||||
@@ -559,7 +559,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
|
||||
}
|
||||
|
||||
function tablesPrint($tables) {
|
||||
echo "<p id='tables'>\n";
|
||||
echo "<p id='tables' onmouseover='menuOver(this);' onmouseout='menuOut(this);'>\n";
|
||||
foreach ($tables as $row) {
|
||||
$name = $this->tableName($row);
|
||||
if (isset($row["Engine"]) && $name != "") { // ignore views and tables without name
|
||||
|
@@ -3,6 +3,9 @@
|
||||
function bodyLoad(version) {
|
||||
}
|
||||
|
||||
function selectFieldChange(form) {
|
||||
}
|
||||
|
||||
function whisperClick(event, field) {
|
||||
var el = event.target || event.srcElement;
|
||||
if (/^a$/i.test(el.tagName) && !(event.button || event.ctrlKey || event.shiftKey || event.altKey || event.metaKey)) {
|
||||
|
@@ -23,7 +23,7 @@ function tablesFilter(value) {
|
||||
</script>
|
||||
<p class="jsonly"><input onkeyup="tablesFilter(this.value);">
|
||||
<?php
|
||||
echo "<p id='tables'>\n";
|
||||
echo "<p id='tables' onmouseover='menuOver(this);' onmouseout='menuOut(this);'>\n";
|
||||
foreach ($tables as $table => $type) {
|
||||
echo '<span><a href="' . h(ME) . 'select=' . urlencode($table) . '"' . bold($_GET["select"] == $table) . ">" . lang('select') . "</a> ";
|
||||
echo '<a href="' . h(ME) . 'table=' . urlencode($table) . '"' . bold($_GET["table"] == $table) . ">" . h($table) . "</a><br></span>\n";
|
||||
|
@@ -38,7 +38,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>verifyTextPresent</td>
|
||||
<td>1 item has been affected.</td>
|
||||
<td>Item 2 has been inserted.</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
|
1
todo.txt
1
todo.txt
@@ -3,7 +3,6 @@ Create view and routine options
|
||||
Variables editation
|
||||
Blob download and image display in edit form (important for Editor with hidden fields in select and SQL command)
|
||||
Add title to Logout, edit (in select) and select (in menu) for style "hever"
|
||||
Shift-click in checkboxes to select range
|
||||
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)
|
||||
|
Reference in New Issue
Block a user