]> git.joonet.de Git - adminer.git/commitdiff
SQLite: Full alter table
authorJakub Vrana <jakub@vrana.cz>
Sun, 15 Jul 2012 21:38:45 +0000 (14:38 -0700)
committerJakub Vrana <jakub@vrana.cz>
Sun, 15 Jul 2012 21:38:45 +0000 (14:38 -0700)
adminer/create.inc.php
adminer/drivers/mysql.inc.php
adminer/drivers/sqlite.inc.php
changes.txt

index e5bdc4d975f8442deef710c744aacbae6f36abd6..a382cfdeaedb398a1c83bc7bb35e060c56476827 100644 (file)
@@ -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"] : ""),
index 392a67128645d9980c38918591f1cafedfd2ed97..72a393aef0528b98a52546520fc341ea8e3dea33 100644 (file)
@@ -603,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])
                        );
                }
index 1f21b14cea50db713fa8f0f810075ff905cb3e88..c471f939330e7e53a2a969d4c8ee61f3f197cce5 100644 (file)
@@ -267,7 +267,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) {
@@ -402,14 +402,90 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
        }
        
        function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
+               $use_all_fields = ($table == "" || $foreign);
+               foreach ($fields as $field) {
+                       if ($field[0] != "" || !$field[1] || $field[2]) {
+                               $use_all_fields = true;
+                               break;
+                       }
+               }
                $alter = array();
+               $originals = array();
+               $primary_key = false;
                foreach ($fields as $field) {
                        if ($field[1]) {
-                               $alter[] = ($table != "" && $field[0] == "" ? "ADD " : "  ") . implode($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];
+                               }
                        }
                }
-               $alter = array_merge($alter, $foreign);
-               if ($table != "") {
+               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;
@@ -418,8 +494,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
@@ -567,7 +641,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";
index a43333e11b095e3f138722cd4529afb0c4d50799..0c5d365a1ccd0da0fa7a32d61ecff422557024b3 100644 (file)
@@ -1,3 +1,6 @@
+Adminer 3.4.1-dev:
+SQLite: Full alter table
+
 Adminer 3.4.0 (released 2012-06-30):
 Link to descending order
 Shift+click on checkbox to select consecutive rows