]> git.joonet.de Git - adminer.git/commitdiff
Create single column foreign key in table structure
authorjakubvrana <jakubvrana@7c3ca157-0c34-0410-bff1-cbf682f78f5c>
Thu, 2 Jul 2009 22:37:10 +0000 (22:37 +0000)
committerjakubvrana <jakubvrana@7c3ca157-0c34-0410-bff1-cbf682f78f5c>
Thu, 2 Jul 2009 22:37:10 +0000 (22:37 +0000)
git-svn-id: https://adminer.svn.sourceforge.net/svnroot/adminer/trunk@778 7c3ca157-0c34-0410-bff1-cbf682f78f5c

adminer/create.inc.php
adminer/event.inc.php
adminer/functions.js
adminer/include/editing.inc.php
adminer/include/functions.inc.php
adminer/include/version.inc.php
changes.txt
todo.txt

index 62fffc459e995a28298b7e07baf5e0be1eea4221..2c7271127709de9015eb6fb92ec63d86ba4f8c59 100644 (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"]); ?>" />
index 25caf3ffd3e03d2947ee316cab1ca26be9755a95..21eec46fc6cc85dce4786ab788c8de77abcb8746 100644 (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();
 }
 ?>
index f7e6980e277c71185870a034c5180cf0c6a8301e..2f5750cf69e0776d31265a4d4b880f58fb1fba9d 100644 (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++;
index 02b6dfa49719bfa218a5831f8c8b4478ce3c9646..abb9da6b41abddaef2e4649bf0d8e1449853e3a2 100644 (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>
index 514d1e519e66ba4be853f7d36a94bd1081024248..580a2ba4884e5ea044800b3345ca5d218b179248 100644 (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>';
index 5d1cd8167f7ce4a7a4a5dde225af1b643090e799..54ba5207401c0916cefa8b2ece0e7eaa3dcd85c6 100644 (file)
@@ -1,2 +1,2 @@
 <?php
-$VERSION = "1.11.0-dev";
+$VERSION = "1.12.0-dev";
index 99b3900865cc0448745940e5de9b8dc3080035b1..ae1d16b0db492cb825a53765bb0b387520d18cf3 100644 (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
index 688bbb630958aa95960dc284b19d9d45c8cf209d..a89e816cacfda17582bc64bc87f3b6542bf42711 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -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