Create single column foreign key in table structure

git-svn-id: https://adminer.svn.sourceforge.net/svnroot/adminer/trunk@778 7c3ca157-0c34-0410-bff1-cbf682f78f5c
This commit is contained in:
jakubvrana 2009-07-02 22:37:10 +00:00
parent ab6d105b28
commit ced9de9d29
8 changed files with 92 additions and 19 deletions

View file

@ -1,6 +1,12 @@
<?php
$partition_by = array('HASH', 'LINEAR HASH', 'KEY', 'LINEAR KEY', 'RANGE', 'LIST');
$referencable_primary = referencable_primary($_GET["create"]);
$foreign_keys = array();
foreach ($referencable_primary as $table_name => $field) {
$foreign_keys[idf_escape($table_name) . "." . idf_escape($field["field"])] = $table_name;
}
if (strlen($_GET["create"])) {
$orig_fields = fields($_GET["create"]);
}
@ -28,9 +34,10 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
ksort($_POST["fields"]);
$after = "FIRST";
foreach ($_POST["fields"] as $key => $field) {
if (strlen($field["field"]) && isset($types[$field["type"]])) {
$fields[] = "\n" . (!strlen($_GET["create"]) ? " " : (strlen($field["orig"]) ? "CHANGE " . idf_escape($field["orig"]) . " " : "ADD "))
. idf_escape($field["field"]) . process_type($field)
$type_field = (isset($types[$field["type"]]) ? $field : $referencable_primary[$foreign_keys[$field["type"]]]);
if (strlen($field["field"]) && $type_field) {
$fields[] = "\n" . (strlen($_GET["create"]) ? (strlen($field["orig"]) ? "CHANGE " . idf_escape($field["orig"]) . " " : "ADD ") : " ")
. idf_escape($field["field"]) . process_type($type_field)
. ($field["null"] ? " NULL" : " NOT NULL") // NULL for timestamp
. (strlen($_GET["create"]) && strlen($field["orig"]) && isset($orig_fields[$field["orig"]]["default"]) && $field["type"] != "timestamp" ? " DEFAULT " . $dbh->quote($orig_fields[$field["orig"]]["default"]) : "") //! timestamp
. ($key == $_POST["auto_increment_col"] ? " AUTO_INCREMENT$auto_increment_index" : "")
@ -38,6 +45,9 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
. (strlen($_GET["create"]) ? " $after" : "")
;
$after = "AFTER " . idf_escape($field["field"]);
if (!isset($types[$field["type"]])) {
$fields[] = (strlen($_GET["create"]) ? " ADD" : "") . " FOREIGN KEY (" . idf_escape($field["field"]) . ") REFERENCES " . idf_escape($foreign_keys[$field["type"]]) . " (" . idf_escape($type_field["field"]) . ")";
}
} elseif (strlen($field["orig"])) {
$fields[] = "\nDROP " . idf_escape($field["orig"]);
}
@ -129,7 +139,7 @@ if ($suhosin && count($row["fields"]) > $suhosin) {
<input type="submit" value="<?php echo lang('Save'); ?>" />
</p>
<table cellspacing="0" id="edit-fields">
<?php $column_comments = edit_fields($row["fields"], $collations, "TABLE", $suhosin); ?>
<?php $column_comments = edit_fields($row["fields"], $collations, "TABLE", $suhosin, $foreign_keys); ?>
</table>
<p>
<?php echo lang('Auto Increment'); ?>: <input name="Auto_increment" size="4" value="<?php echo intval($row["Auto_increment"]); ?>" />

View file

@ -5,7 +5,7 @@ $statuses = array("ENABLED" => "ENABLE", "DISABLED" => "DISABLE", "SLAVESIDE_DIS
if ($_POST && !$error) {
if ($_POST["drop"]) {
query_redirect("DROP EVENT " . idf_escape($_GET["event"]), substr($SELF, 0, -1), lang('Event has been dropped.'));
} elseif (in_array($_POST["INTERVAL_FIELD"], $intervals) && in_array($_POST["STATUS"], $statuses)) {
} elseif (in_array($_POST["INTERVAL_FIELD"], $intervals) && isset($statuses[$_POST["STATUS"]])) {
$schedule = "\nON SCHEDULE " . ($_POST["INTERVAL_VALUE"]
? "EVERY " . $dbh->quote($_POST["INTERVAL_VALUE"]) . " $_POST[INTERVAL_FIELD]"
. ($_POST["STARTS"] ? " STARTS " . $dbh->quote($_POST["STARTS"]) : "")
@ -17,7 +17,7 @@ if ($_POST && !$error) {
? "ALTER EVENT " . idf_escape($_GET["event"]) . $schedule
. ($_GET["event"] != $_POST["EVENT_NAME"] ? "\nRENAME TO " . idf_escape($_POST["EVENT_NAME"]) : "")
: "CREATE EVENT " . idf_escape($_POST["EVENT_NAME"]) . $schedule
) . "\n$_POST[STATUS] COMMENT " . $dbh->quote($_POST["EVENT_COMMENT"])
) . "\n" . $statuses[$_POST["STATUS"]] . " COMMENT " . $dbh->quote($_POST["EVENT_COMMENT"])
. " DO\n$_POST[EVENT_DEFINITION]"
, substr($SELF, 0, -1), (strlen($_GET["event"]) ? lang('Event has been altered.') : lang('Event has been created.')));
}
@ -30,7 +30,6 @@ if ($_POST) {
} elseif (strlen($_GET["event"])) {
$result = $dbh->query("SELECT * FROM information_schema.EVENTS WHERE EVENT_SCHEMA = " . $dbh->quote($_GET["db"]) . " AND EVENT_NAME = " . $dbh->quote($_GET["event"]));
$row = $result->fetch_assoc();
$row["STATUS"] = $statuses[$row["STATUS"]];
$result->free();
}
?>

View file

@ -65,6 +65,48 @@ function select_add_row(field) {
var added = '.', row_count;
function re_escape(s) {
return s.replace(/[\[\]\\^$*+?.(){|}]/, '\\$&');
}
function idf_escape(s) {
return '`' + s.replace(/`/, '``') + '`';
}
function editing_name_change(field) {
var name = field.name.substr(0, field.name.length - 7);
var type = field.form[name + '[type]'];
var opts = type.options;
var table = re_escape(field.value);
var column = '';
var match;
if (match = /(.+)_(.+)/.exec(table)) { // limited to columns not containing underscores
table = match[1];
column = match[2];
}
var plural = '(?:e?s)?';
var tab_col = table + plural + '_?' + column;
var re = new RegExp('^' + idf_escape(table + plural) + '\\.' + idf_escape(column) + '$'
+ '|^' + idf_escape(tab_col) + '\\.'
+ '|\\.' + idf_escape(tab_col) + '$'
+ '|^' + idf_escape(column + plural) + '\\.' + idf_escape(table) + '$'
, 'i');
var candidate; // don't select anything with ambiguous match (like column `id`)
for (var i = opts.length; i--; ) {
if (re.test(opts[i].value)) {
if (candidate) {
return false;
} else {
candidate = i;
}
}
}
if (candidate) {
opts.selectedIndex = candidate;
editing_type_change(type);
}
}
function editing_add_row(button, allowed) {
if (allowed && row_count >= allowed) {
return false;
@ -91,7 +133,9 @@ function editing_add_row(button, allowed) {
tags2[i].value = '';
}
}
tags[0].onchange = function () { };
tags[0].onchange = function () {
editing_name_change(tags[0]);
};
row.parentNode.insertBefore(row2, row.nextSibling);
added += '0';
row_count++;

View file

@ -99,14 +99,32 @@ function process_input($name, $field) {
}
}
function edit_type($key, $field, $collations) {
function referencable_primary($self) {
$return = array(); // table_name => field
foreach (table_status_referencable() as $table_name => $table) {
if ($table_name != $self) {
foreach (fields($table_name) as $field) {
if ($field["primary"]) {
if ($return[$table_name]) { // multi column primary key
unset($return[$table_name]);
break;
}
$return[$table_name] = $field;
}
}
}
}
return $return;
}
function edit_type($key, $field, $collations, $foreign_keys = array()) {
global $types, $unsigned, $inout;
?>
<td><select name="<?php echo $key; ?>[type]" onchange="editing_type_change(this);"><?php echo optionlist(array_keys($types), $field["type"]); ?></select></td>
<td><select name="<?php echo $key; ?>[type]" onchange="editing_type_change(this);"><?php echo optionlist(array_keys($types) + ($foreign_keys ? array(lang('Foreign keys') => $foreign_keys) : array()), $field["type"]); ?></select></td>
<td><input name="<?php echo $key; ?>[length]" value="<?php echo htmlspecialchars($field["length"]); ?>" size="3" /></td>
<td><?php
echo "<select name=\"$key" . '[collation]"' . (preg_match('~char|text|enum|set~', $field["type"]) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')</option>' . optionlist($collations, $field["collation"]) . '</select>';
echo ($unsigned ? " <select name=\"$key" . '[unsigned]"' . (!$field["type"] || preg_match('~int|float|double|decimal~', $field["type"]) ? "" : " class='hidden'") . '><option></option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : '');
echo "<select name=\"$key" . '[collation]"' . (ereg('~(char|text|enum|set)$~', $field["type"]) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')</option>' . optionlist($collations, $field["collation"]) . '</select>';
echo ($unsigned ? " <select name=\"$key" . '[unsigned]"' . (!$field["type"] || ereg('~(int|float|double|decimal)$~', $field["type"]) ? "" : " class='hidden'") . '><option></option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : '');
?></td>
<?php
}
@ -120,7 +138,7 @@ function process_type($field, $collate = "COLLATE") {
;
}
function edit_fields($fields, $collations, $type = "TABLE", $allowed = 0) {
function edit_fields($fields, $collations, $type = "TABLE", $allowed = 0, $foreign_keys = array()) {
global $inout;
$column_comments = false;
foreach ($fields as $field) {
@ -149,8 +167,8 @@ function edit_fields($fields, $collations, $type = "TABLE", $allowed = 0) {
?>
<tr<?php echo ($display ? "" : " style='display: none;'"); ?>>
<?php if ($type == "PROCEDURE") { ?><td><select name="fields[<?php echo $i; ?>][inout]"><?php echo optionlist($inout, $field["inout"]); ?></select></td><?php } ?>
<th><?php if ($display) { ?><input name="fields[<?php echo $i; ?>][field]" value="<?php echo htmlspecialchars($field["field"]); ?>"<?php echo (strlen($field["field"]) || count($fields) > 1 ? "" : " onchange='editing_add_row(this, $allowed);'"); ?> maxlength="64" /><?php } ?><input type="hidden" name="fields[<?php echo $i; ?>][orig]" value="<?php echo htmlspecialchars($field[($_POST ? "orig" : "field")]); ?>" /></th>
<?php edit_type("fields[$i]", $field, $collations); ?>
<th><?php if ($display) { ?><input name="fields[<?php echo $i; ?>][field]" value="<?php echo htmlspecialchars($field["field"]); ?>" onchange="<?php echo (strlen($field["field"]) || count($fields) > 1 ? "" : "editing_add_row(this, $allowed); "); ?>editing_name_change(this);" maxlength="64" /><?php } ?><input type="hidden" name="fields[<?php echo $i; ?>][orig]" value="<?php echo htmlspecialchars($field[($_POST ? "orig" : "field")]); ?>" /></th>
<?php edit_type("fields[$i]", $field, $collations, $foreign_keys); ?>
<?php if ($type == "TABLE") { ?>
<td><input type="checkbox" name="fields[<?php echo $i; ?>][null]" value="1"<?php if ($field["null"]) { ?> checked="checked"<?php } ?> /></td>
<td><input type="radio" name="auto_increment_col" value="<?php echo $i; ?>"<?php if ($field["auto_increment"]) { ?> checked="checked"<?php } ?> /></td>

View file

@ -19,8 +19,8 @@ function optionlist($options, $selected = null) {
if (is_array($v)) {
$return .= '<optgroup label="' . htmlspecialchars($k) . '">';
}
foreach ((is_array($v) ? $v : array($v)) as $val) {
$return .= '<option' . ($val === $selected ? ' selected="selected"' : '') . '>' . htmlspecialchars($val) . '</option>';
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) . '</option>';
}
if (is_array($v)) {
$return .= '</optgroup>';

View file

@ -1,2 +1,2 @@
<?php
$VERSION = "1.11.0-dev";
$VERSION = "1.12.0-dev";

View file

@ -1,3 +1,6 @@
Adminer 1.12.0:
Create single column foreign key in table structure
Adminer 1.11.0:
Connection through socket by server :/path/to/socket
Simplify export

View file

@ -10,7 +10,6 @@ Highlight SQL textarea - may use external CodePress
Mass editation of individual rows
IE6 - <label for>
Edit default values directly in table creation
Single column foreign key definition in table creation
Offer enum and set items in search - whisperer
Use event $intervals + microseconds in relative date functions
Ability to select external style - list downloaded by JavaScript