Select from foreign keys in Editor

git-svn-id: https://adminer.svn.sourceforge.net/svnroot/adminer/trunk@883 7c3ca157-0c34-0410-bff1-cbf682f78f5c
This commit is contained in:
jakubvrana 2009-07-23 14:42:38 +00:00
parent f13efa8684
commit 1e4d11e920
7 changed files with 109 additions and 53 deletions

View file

@ -57,7 +57,7 @@ if ($in) {
if (strlen($value) && ($field["type"] == "enum" || $field["type"] == "set")) {
$value = intval($value);
}
input($key, $field, $value, (string) $_POST["function"][$name]); // param name can be empty
input($field, $value, (string) $_POST["function"][$name]); // param name can be empty
echo "\n";
}
echo "</table>\n";

View file

@ -79,7 +79,7 @@ if ($fields) {
: ($_POST["clone"] && $field["auto_increment"] ? "" : (isset($_GET["select"]) ? false : $field["default"]))
);
$function = ($_POST["save"] ? (string) $_POST["function"][$name] : ($where && $field["on_update"] == "CURRENT_TIMESTAMP" ? "now" : ($value === false ? null : (isset($value) ? '' : 'NULL'))));
input($name, $field, $value, $function);
input($field, $value, $function);
if (isset($_GET["default"]) && $field["type"] == "timestamp") {
if (!isset($create) && !$_POST) {
//! disable sql_mode NO_FIELD_OPTIONS

View file

@ -90,9 +90,17 @@ function adminer_select_query($query) {
return call_adminer('select_query', "<p><code class='jush-sql'>" . htmlspecialchars($query) . "</code> <a href='" . htmlspecialchars($SELF) . "sql=" . urlencode($query) . "'>" . lang('Edit') . "</a>\n", $query);
}
/** Descriptions of selected data
/** Description of a row in a table
* @param string
* @return string SQL expression, empty string for no description
*/
function adminer_row_description($table) {
return call_adminer('row_description', "", $table);
}
/** Get descriptions of selected data
* @param array all data to print
* @param array foreign keys
* @param array
* @return array
*/
function adminer_row_descriptions($rows, $foreign_keys) {
@ -147,7 +155,16 @@ function adminer_edit_functions($field) {
if ($field["null"] || isset($_GET["default"])) {
array_unshift($return, "NULL");
}
return call_adminer('edit_functions', $return, $field);
return call_adminer('edit_functions', (isset($_GET["select"]) ? array("orig" => lang('original')) : array()) + $return, $field);
}
/** Get options to display edit field
* @param string table name
* @param array single field from fields()
* @return array options for <select> or empty to display <input>
*/
function adminer_edit_input($table, $field) {
return call_adminer('edit_input', false, $table, $field);
}
/** Prints navigation after Adminer title

View file

@ -13,14 +13,14 @@ function bracket_escape($idf, $back = false) {
return strtr($idf, ($back ? array_flip($trans) : $trans));
}
function optionlist($options, $selected = null) {
function optionlist($options, $selected = null, $use_keys = false) {
$return = "";
foreach ($options as $k => $v) {
if (is_array($v)) {
$return .= '<optgroup label="' . htmlspecialchars($k) . '">';
}
foreach ((is_array($v) ? $v : array($k => $v)) as $key => $val) {
$return .= '<option' . (is_string($key) ? ' value="' . htmlspecialchars($key) . '"' : '') . ((is_string($key) ? $key : $val) === $selected ? ' selected="selected"' : '') . '>' . htmlspecialchars($val);
$return .= '<option' . ($use_keys || is_string($key) ? ' value="' . htmlspecialchars($key) . '"' : '') . (($use_keys || is_string($key) ? (string) $key : $val) === $selected ? ' selected="selected"' : '') . '>' . htmlspecialchars($val);
}
if (is_array($v)) {
$return .= '</optgroup>';
@ -265,9 +265,19 @@ function hidden_fields($process, $ignore = array()) {
}
}
function input($name, $field, $value, $function) {
function column_foreign_keys($table) {
$return = array();
foreach (foreign_keys($table) as $foreign_key) {
foreach ($foreign_key["source"] as $val) {
$return[$val][] = $foreign_key;
}
}
return $return;
}
function input($field, $value, $function) {
global $types;
$name = htmlspecialchars(bracket_escape($name));
$name = htmlspecialchars(bracket_escape($field["field"]));
echo "<td class='function'>";
if ($field["type"] == "enum") {
echo "&nbsp;<td>" . (isset($_GET["select"]) ? ' <label><input type="radio" name="fields[' . $name . ']" value="-1" checked="checked"><em>' . lang('original') . '</em></label>' : "");
@ -284,11 +294,14 @@ function input($name, $field, $value, $function) {
echo ' <label><input type="radio" name="fields[' . $name . ']" value="' . (isset($_GET["default"]) ? (strlen($val) ? htmlspecialchars($val) : " ") : $i+1) . '"' . ($checked ? ' checked="checked"' : '') . '>' . htmlspecialchars($val) . '</label>';
}
} else {
$first = ($field["null"] || isset($_GET["default"])) + isset($_GET["select"]);
$functions = adminer_edit_functions($field);
$first = array_search("", $functions);
$onchange = ($first ? ' onchange="var f = this.form[\'function[' . addcslashes($name, "\r\n'\\") . ']\']; if (' . $first . ' > f.selectedIndex) f.selectedIndex = ' . $first . ';"' : '');
$options = adminer_edit_functions($field);
echo (count($options) > 1 || isset($_GET["select"]) ? '<select name="function[' . $name . ']">' . (isset($_GET["select"]) ? '<option value="orig">' . lang('original') : '') . optionlist($options, $function) . '</select>' : "&nbsp;") . '<td>';
if ($field["type"] == "set") { //! 64 bits
echo (count($functions) > 1 ? '<select name="function[' . $name . ']">' . optionlist($functions, $function) . '</select>' : "&nbsp;") . '<td>';
$options = adminer_edit_input($_GET["edit"], $field); // usage in call is without a table
if (is_array($options)) {
echo '<select name="fields[' . $name . ']"' . $onchange . '>' . optionlist($options, $value, true) . '</select>';
} elseif ($field["type"] == "set") { //! 64 bits
preg_match_all("~'((?:[^']+|'')*)'~", $field["length"], $matches);
foreach ($matches[1] as $i => $val) {
$val = stripcslashes(str_replace("''", "'", $val));
@ -302,7 +315,7 @@ function input($name, $field, $value, $function) {
} else {
// int(3) is only a display hint
$maxlength = (!ereg('int', $field["type"]) && preg_match('~^([0-9]+)(,([0-9]+))?$~', $field["length"], $match) ? ($match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0)) : ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0));
echo '<input name="fields[' . $name . ']" value="' . htmlspecialchars($value) . '"' . ($maxlength ? " maxlength='$maxlength'" : "") . $onchange . '>';
echo '<input name="fields[' . $name . ']" value="' . htmlspecialchars($value) . '"' . ($maxlength ? " maxlength='$maxlength'" : "") . "$onchange>";
}
}
}

View file

@ -20,7 +20,7 @@ unset($text_length);
foreach ($fields as $key => $field) {
$name = adminer_field_name($fields, $key);
if (isset($field["privileges"]["select"]) && strlen($name)) {
$columns[$key] = html_entity_decode(strip_tags($name)); //! numeric $key is problematic in optionlist()
$columns[$key] = html_entity_decode(strip_tags($name));
if (ereg('text|blob', $field["type"])) {
$text_length = (isset($_GET["text_length"]) ? $_GET["text_length"] : "100");
}
@ -196,11 +196,11 @@ if (!$columns) {
foreach ($select as $key => $val) {
$val = $_GET["columns"][$key];
echo "<div><select name='columns[$i][fun]'><option>" . optionlist($fun_group, $val["fun"]) . "</select>";
echo "<select name='columns[$i][col]'><option>" . optionlist($columns, $val["col"]) . "</select></div>\n";
echo "<select name='columns[$i][col]'><option>" . optionlist($columns, $val["col"], true) . "</select></div>\n";
$i++;
}
echo "<div><select name='columns[$i][fun]' onchange='this.nextSibling.onchange();'><option>" . optionlist($fun_group) . "</select>";
echo "<select name='columns[$i][col]' onchange='select_add_row(this);'><option>" . optionlist($columns) . "</select></div>\n";
echo "<select name='columns[$i][col]' onchange='select_add_row(this);'><option>" . optionlist($columns, null, true) . "</select></div>\n";
echo "</div></fieldset>\n";
echo '<fieldset><legend><a href="#fieldset-search" onclick="return !toggle(\'fieldset-search\');">' . lang('Search') . "</a></legend><div id='fieldset-search'" . ($where ? "" : " class='hidden'") . ">\n";
@ -215,13 +215,13 @@ if (!$columns) {
$i = 0;
foreach ((array) $_GET["where"] as $val) {
if (strlen("$val[col]$val[val]") && in_array($val["op"], $operators)) {
echo "<div><select name='where[$i][col]'><option value=''>" . lang('(anywhere)') . optionlist($columns, $val["col"]) . "</select>";
echo "<div><select name='where[$i][col]'><option value=''>" . lang('(anywhere)') . optionlist($columns, $val["col"], true) . "</select>";
echo "<select name='where[$i][op]'>" . optionlist($operators, $val["op"]) . "</select>";
echo "<input name='where[$i][val]' value=\"" . htmlspecialchars($val["val"]) . "\"></div>\n";
$i++;
}
}
echo "<div><select name='where[$i][col]' onchange='select_add_row(this);'><option value=''>" . lang('(anywhere)') . optionlist($columns) . "</select>";
echo "<div><select name='where[$i][col]' onchange='select_add_row(this);'><option value=''>" . lang('(anywhere)') . optionlist($columns, null, true) . "</select>";
echo "<select name='where[$i][op]'>" . optionlist($operators) . "</select>";
echo "<input name='where[$i][val]'></div>\n";
echo "</div></fieldset>\n";
@ -230,12 +230,12 @@ if (!$columns) {
$i = 0;
foreach ((array) $_GET["order"] as $key => $val) {
if (isset($columns[$val])) {
echo "<div><select name='order[$i]'><option>" . optionlist($columns, $val) . "</select>";
echo "<div><select name='order[$i]'><option>" . optionlist($columns, $val, true) . "</select>";
echo "<label><input type='checkbox' name='desc[$i]' value='1'" . (isset($_GET["desc"][$key]) ? " checked='checked'" : "") . ">" . lang('descending') . "</label></div>\n";
$i++;
}
}
echo "<div><select name='order[$i]' onchange='select_add_row(this);'><option>" . optionlist($columns) . "</select>";
echo "<div><select name='order[$i]' onchange='select_add_row(this);'><option>" . optionlist($columns, null, true) . "</select>";
echo "<label><input type='checkbox' name='desc[$i]' value='1'>" . lang('descending') . "</label></div>\n";
echo "</div></fieldset>\n";
@ -277,12 +277,7 @@ if (!$columns) {
: count($rows)
);
$foreign_keys = array();
foreach (foreign_keys($_GET["select"]) as $foreign_key) {
foreach ($foreign_key["source"] as $val) {
$foreign_keys[$val][] = $foreign_key;
}
}
$foreign_keys = column_foreign_keys($_GET["select"]);
$descriptions = adminer_row_descriptions($rows, $foreign_keys);
$backward_keys = adminer_backward_keys($_GET["select"]);

View file

@ -2,7 +2,7 @@ Adminer 2.0.0:
Editor: User friendly data editor
Customization: Adminer class
E-mail sending
Table relations
Table relations (Editor)
Create single column foreign key in table structure
Separate types to groups in table creation
Show type in field name title (thanks to Jakub Sochor)

View file

@ -62,6 +62,18 @@ function adminer_select_query($query) {
return call_adminer('select_query', "<!-- " . str_replace("--", "--><!--", $query) . " -->\n", $query);
}
function adminer_row_description($table) {
$return = "";
// first varchar column
foreach (fields($table) as $field) {
if ($field["type"] == "varchar") {
$return = idf_escape($field["field"]);
break;
}
}
return call_adminer('row_description', $return, $table);
}
function adminer_row_descriptions($rows, $foreign_keys) {
global $dbh;
$return = $rows;
@ -69,31 +81,26 @@ function adminer_row_descriptions($rows, $foreign_keys) {
foreach ((array) $foreign_keys[$key] as $foreign_key) {
if (count($foreign_key["source"]) == 1) {
$id = idf_escape($foreign_key["target"][0]);
// find out the description column - first varchar
$name = $id;
foreach (fields($foreign_key["table"]) as $field) {
if ($field["type"] == "varchar") {
$name = idf_escape($field["field"]);
break;
$name = adminer_row_description($foreign_key["table"]);
if (strlen($name)) {
// find all used ids
$ids = array();
foreach ($rows as $row) {
$ids[$row[$key]] = $dbh->quote($row[$key]);
}
// uses constant number of queries to get the descriptions, join would be complex, multiple queries would be slow
$descriptions = array();
$result = $dbh->query("SELECT $id, $name FROM " . idf_escape($foreign_key["table"]) . " WHERE $id IN (" . implode(", ", $ids) . ")");
while ($row = $result->fetch_row()) {
$descriptions[$row[0]] = $row[1];
}
$result->free();
// use the descriptions
foreach ($rows as $n => $row) {
$return[$n][$key] = $descriptions[$row[$key]];
}
break;
}
// find all used ids
$ids = array();
foreach ($rows as $row) {
$ids[$row[$key]] = $dbh->quote($row[$key]);
}
// uses constant number of queries to get the descriptions, join would be complex, multiple queries would be slow
$descriptions = array();
$result = $dbh->query("SELECT $id, $name FROM " . idf_escape($foreign_key["table"]) . " WHERE $id IN (" . implode(", ", $ids) . ")");
while ($row = $result->fetch_row()) {
$descriptions[$row[0]] = $row[1];
}
$result->free();
// use the descriptions
foreach ($rows as $n => $row) {
$return[$n][$key] = $descriptions[$row[$key]];
}
break;
}
}
}
@ -108,11 +115,35 @@ function adminer_select_val($val, $link) {
}
function adminer_message_query($query) {
return call_adminer('message_query', "<!-- " . str_replace("--", "--><!--", $query) . " -->", $query);
return call_adminer('message_query', "<!--\n" . str_replace("--", "--><!--", $query) . "\n-->", $query);
}
function adminer_edit_functions($field) {
return call_adminer('edit_functions', array(""), $field);
return call_adminer('edit_functions', (isset($_GET["select"]) ? array("orig" => lang('original')) : array()) + array(""), $field);
}
function adminer_edit_input($table, $field) {
global $dbh;
$return = null;
$foreign_keys = column_foreign_keys($table);
foreach ((array) $foreign_keys[$field["field"]] as $foreign_key) {
if (count($foreign_key["source"]) == 1) {
$id = idf_escape($foreign_key["target"][0]);
$name = adminer_row_description($foreign_key["table"]);
if (strlen($name) && $dbh->result($dbh->query("SELECT COUNT(*) FROM " . idf_escape($foreign_key["table"]))) <= 1000) { // optionlist with more than 1000 options would be too big
if ($field["null"]) {
$return[""] = "";
}
$result = $dbh->query("SELECT $id, $name FROM " . idf_escape($foreign_key["table"]) . " ORDER BY 2");
while ($row = $result->fetch_row()) {
$return[$row[0]] = $row[1];
}
$result->free();
break;
}
}
}
return call_adminer('edit_input', $return, $table, $field);
}
function adminer_navigation($missing) {