Permalink
Browse files

SQLite: Full alter table

  • Loading branch information...
1 parent 5fb2368 commit c2f95e005440658c2584d199dc48d0055dccc6b8 @vrana committed Jul 15, 2012
Showing with 99 additions and 12 deletions.
  1. +14 −4 adminer/create.inc.php
  2. +1 −1 adminer/drivers/mysql.inc.php
  3. +81 −7 adminer/drivers/sqlite.inc.php
  4. +3 −0 changes.txt
View
@@ -23,10 +23,12 @@
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 @@
$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 @@
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"] : ""),
@@ -603,7 +603,7 @@ function alter_table($table, $name, $fields, $foreign, $comment, $engine, $colla
$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])
);
}
@@ -267,7 +267,7 @@ function is_view($table_status) {
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 @@ function auto_increment() {
}
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 @@ function alter_table($table, $name, $fields, $foreign, $comment, $engine, $colla
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 @@ function show_status() {
}
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";
View
@@ -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

0 comments on commit c2f95e0

Please sign in to comment.