<?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"]);
}
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" : "")
. (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"]);
}
<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"]); ?>" />
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"]) : "")
? "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.')));
}
} 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();
}
?>
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;
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++;
}
}
-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
}
;
}
-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) {
?>
<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>
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>';
<?php
-$VERSION = "1.11.0-dev";
+$VERSION = "1.12.0-dev";
+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
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