diff --git a/adminer/dump.inc.php b/adminer/dump.inc.php
index d4d33934..57fe60bc 100644
--- a/adminer/dump.inc.php
+++ b/adminer/dump.inc.php
@@ -8,7 +8,7 @@ if ($_POST) {
}
cookie("adminer_export", substr($cookie, 1));
$ext = dump_headers(($TABLE != "" ? $TABLE : DB), (DB == "" || count((array) $_POST["tables"] + (array) $_POST["data"]) > 1));
- $is_sql = ($_POST["format"] == "sql");
+ $is_sql = ereg('sql', $_POST["format"]);
if ($is_sql) {
echo "-- Adminer $VERSION " . $drivers[DRIVER] . " dump
@@ -29,20 +29,18 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
}
}
foreach ((array) $databases as $db) {
+ $adminer->dumpDatabase($db);
if ($connection->select_db($db)) {
if ($is_sql && ereg('CREATE', $style) && ($create = $connection->result("SHOW CREATE DATABASE " . idf_escape($db), 1))) {
if ($style == "DROP+CREATE") {
echo "DROP DATABASE IF EXISTS " . idf_escape($db) . ";\n";
}
- echo ($style == "CREATE+ALTER" ? preg_replace('~^CREATE DATABASE ~', '\\0IF NOT EXISTS ', $create) : $create) . ";\n";
+ echo "$create;\n";
}
if ($is_sql) {
if ($style) {
echo use_sql($db) . ";\n\n";
}
- if (in_array("CREATE+ALTER", array($style, $_POST["table_style"]))) {
- echo "SET @adminer_alter = '';\n\n";
- }
$out = "";
if ($_POST["routines"]) {
foreach (array("FUNCTION", "PROCEDURE") as $routine) {
@@ -97,46 +95,6 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
echo pack("x512");
}
}
-
- if ($style == "CREATE+ALTER" && $is_sql) {
- // drop old tables
- $query = "SELECT TABLE_NAME, ENGINE, TABLE_COLLATION, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()";
- echo "DELIMITER ;;
-CREATE PROCEDURE adminer_alter (INOUT alter_command text) BEGIN
- DECLARE _table_name, _engine, _table_collation varchar(64);
- DECLARE _table_comment varchar(64);
- DECLARE done bool DEFAULT 0;
- DECLARE tables CURSOR FOR $query;
- DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
- OPEN tables;
- REPEAT
- FETCH tables INTO _table_name, _engine, _table_collation, _table_comment;
- IF NOT done THEN
- CASE _table_name";
- foreach (get_rows($query) as $row) {
- $comment = q($row["ENGINE"] == "InnoDB" ? preg_replace('~(?:(.+); )?InnoDB free: .*~', '\\1', $row["TABLE_COMMENT"]) : $row["TABLE_COMMENT"]);
- echo "
- WHEN " . q($row["TABLE_NAME"]) . " THEN
- " . (isset($row["ENGINE"]) ? "IF _engine != '$row[ENGINE]' OR _table_collation != '$row[TABLE_COLLATION]' OR _table_comment != $comment THEN
- ALTER TABLE " . idf_escape($row["TABLE_NAME"]) . " ENGINE=$row[ENGINE] COLLATE=$row[TABLE_COLLATION] COMMENT=$comment;
- END IF" : "BEGIN END") . ";";
- }
- echo "
- ELSE
- SET alter_command = CONCAT(alter_command, 'DROP TABLE `', REPLACE(_table_name, '`', '``'), '`;\\n');
- END CASE;
- END IF;
- UNTIL done END REPEAT;
- CLOSE tables;
-END;;
-DELIMITER ;
-CALL adminer_alter(@adminer_alter);
-DROP PROCEDURE adminer_alter;
-";
- }
- if (in_array("CREATE+ALTER", array($style, $_POST["table_style"])) && $is_sql) {
- echo "SELECT @adminer_alter;\n";
- }
}
}
if ($is_sql) {
@@ -154,9 +112,7 @@ page_header(lang('Export'), "", ($_GET["export"] != "" ? array("table" => $_GET[
$db_style = array('', 'USE', 'DROP+CREATE', 'CREATE');
$table_style = array('', 'DROP+CREATE', 'CREATE');
$data_style = array('', 'TRUNCATE+INSERT', 'INSERT');
-if ($jush == "sql") {
- $db_style[] = 'CREATE+ALTER';
- $table_style[] = 'CREATE+ALTER';
+if ($jush == "sql") { //! use insert_update() in all drivers
$data_style[] = 'INSERT+UPDATE';
}
parse_str($_COOKIE["adminer_export"], $row);
diff --git a/adminer/include/adminer.inc.php b/adminer/include/adminer.inc.php
index ba77b5f7..7ea16c64 100644
--- a/adminer/include/adminer.inc.php
+++ b/adminer/include/adminer.inc.php
@@ -585,6 +585,13 @@ username.form['auth[driver]'].onchange();
return array('sql' => 'SQL', 'csv' => 'CSV,', 'csv;' => 'CSV;', 'tsv' => 'TSV');
}
+ /** Export database structure
+ * @param string
+ * @return null prints data
+ */
+ function dumpDatabase($db) {
+ }
+
/** Export table structure
* @param string
* @param string
@@ -606,78 +613,7 @@ username.form['auth[driver]'].onchange();
if ($is_view) {
$create = remove_definer($create);
}
- echo ($style != "CREATE+ALTER" ? $create : ($is_view ? substr_replace($create, " OR REPLACE", 6, 0) : substr_replace($create, " IF NOT EXISTS", 12, 0))) . ";\n\n";
- }
- if ($style == "CREATE+ALTER" && !$is_view) {
- // create procedure which iterates over original columns and adds new and removes old
- $query = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, COLLATION_NAME, COLUMN_TYPE, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . q($table) . " ORDER BY ORDINAL_POSITION";
- echo "DELIMITER ;;
-CREATE PROCEDURE adminer_alter (INOUT alter_command text) BEGIN
- DECLARE _column_name, _collation_name, after varchar(64) DEFAULT '';
- DECLARE _column_type, _column_default text;
- DECLARE _is_nullable char(3);
- DECLARE _extra varchar(30);
- DECLARE _column_comment varchar(255);
- DECLARE done, set_after bool DEFAULT 0;
- DECLARE add_columns text DEFAULT '";
- $fields = array();
- $after = "";
- foreach (get_rows($query) as $row) {
- $default = $row["COLUMN_DEFAULT"];
- $row["default"] = ($default !== null ? q($default) : "NULL");
- $row["after"] = q($after); //! rgt AFTER lft, lft AFTER id doesn't work
- $row["alter"] = escape_string(idf_escape($row["COLUMN_NAME"])
- . " $row[COLUMN_TYPE]"
- . ($row["COLLATION_NAME"] ? " COLLATE $row[COLLATION_NAME]" : "")
- . ($default !== null ? " DEFAULT " . ($default == "CURRENT_TIMESTAMP" ? $default : $row["default"]) : "")
- . ($row["IS_NULLABLE"] == "YES" ? "" : " NOT NULL")
- . ($row["EXTRA"] ? " $row[EXTRA]" : "")
- . ($row["COLUMN_COMMENT"] ? " COMMENT " . q($row["COLUMN_COMMENT"]) : "")
- . ($after ? " AFTER " . idf_escape($after) : " FIRST")
- );
- echo ", ADD $row[alter]";
- $fields[] = $row;
- $after = $row["COLUMN_NAME"];
- }
- echo "';
- DECLARE columns CURSOR FOR $query;
- DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
- SET @alter_table = '';
- OPEN columns;
- REPEAT
- FETCH columns INTO _column_name, _column_default, _is_nullable, _collation_name, _column_type, _extra, _column_comment;
- IF NOT done THEN
- SET set_after = 1;
- CASE _column_name";
- foreach ($fields as $row) {
- echo "
- WHEN " . q($row["COLUMN_NAME"]) . " THEN
- SET add_columns = REPLACE(add_columns, ', ADD $row[alter]', IF(
- _column_default <=> $row[default] AND _is_nullable = '$row[IS_NULLABLE]' AND _collation_name <=> " . (isset($row["COLLATION_NAME"]) ? "'$row[COLLATION_NAME]'" : "NULL") . " AND _column_type = " . q($row["COLUMN_TYPE"]) . " AND _extra = '$row[EXTRA]' AND _column_comment = " . q($row["COLUMN_COMMENT"]) . " AND after = $row[after]
- , '', ', MODIFY $row[alter]'));"
- ; //! don't replace in comment
- }
- echo "
- ELSE
- SET @alter_table = CONCAT(@alter_table, ', DROP ', _column_name);
- SET set_after = 0;
- END CASE;
- IF set_after THEN
- SET after = _column_name;
- END IF;
- END IF;
- UNTIL done END REPEAT;
- CLOSE columns;
- IF @alter_table != '' OR add_columns != '' THEN
- SET alter_command = CONCAT(alter_command, 'ALTER TABLE " . table($table) . "', SUBSTR(CONCAT(add_columns, @alter_table), 2), ';\\n');
- END IF;
-END;;
-DELIMITER ;
-CALL adminer_alter(@adminer_alter);
-DROP PROCEDURE adminer_alter;
-
-";
- //! indexes
+ echo "$create;\n\n";
}
}
}
@@ -766,7 +702,7 @@ DROP PROCEDURE adminer_alter;
*/
function dumpHeaders($identifier, $multi_table = false) {
$output = $_POST["output"];
- $ext = ($_POST["format"] == "sql" ? "sql" : ($multi_table ? "tar" : "csv")); // multiple CSV packed to TAR
+ $ext = (ereg('sql', $_POST["format"]) ? "sql" : ($multi_table ? "tar" : "csv")); // multiple CSV packed to TAR
header("Content-Type: " .
($output == "bz2" ? "application/x-bzip" :
($output == "gz" ? "application/x-gzip" :
diff --git a/adminer/plugin.php b/adminer/plugin.php
index 0e94373c..d6a7f9a3 100644
--- a/adminer/plugin.php
+++ b/adminer/plugin.php
@@ -14,6 +14,7 @@ function adminer_object() {
new AdminerDumpJson,
new AdminerDumpZip,
new AdminerDumpXml,
+ new AdminerDumpAlter,
//~ new AdminerSqlLog("past-" . rtrim(`git describe --tags --abbrev=0`) . ".sql"),
//~ new AdminerEditCalendar("\n\n\n\n\n\n\n\n\n", "../externals/jquery-ui/ui/i18n/jquery.ui.datepicker-%s.js"),
//~ new AdminerTinymce("../externals/tinymce/jscripts/tiny_mce/tiny_mce_dev.js"),
diff --git a/changes.txt b/changes.txt
index 159945c2..d3fe1b36 100644
--- a/changes.txt
+++ b/changes.txt
@@ -7,6 +7,7 @@ Stay on the same page after deleting rows (bug #3605845)
Handle max_input_vars
Disable autocapitalize in identifiers on mobile browsers
MySQL: Compatibility with MySQL 5.6
+MySQL: Move ALTER export to plugin
SQLite: Export indexes
Adminer 3.6.3 (released 2013-01-23):
diff --git a/editor/include/adminer.inc.php b/editor/include/adminer.inc.php
index a376eca1..b2e9235d 100644
--- a/editor/include/adminer.inc.php
+++ b/editor/include/adminer.inc.php
@@ -498,6 +498,9 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
return array('csv' => 'CSV,', 'csv;' => 'CSV;', 'tsv' => 'TSV');
}
+ function dumpDatabase($db) {
+ }
+
function dumpTable() {
echo "\xef\xbb\xbf"; // UTF-8 byte order mark
}
diff --git a/plugins/dump-alter.php b/plugins/dump-alter.php
new file mode 100644
index 00000000..5f74b9ec
--- /dev/null
+++ b/plugins/dump-alter.php
@@ -0,0 +1,151 @@
+ 'Alter');
+ }
+ }
+
+ function _database() {
+ // drop old tables
+ $query = "SELECT TABLE_NAME, ENGINE, TABLE_COLLATION, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()";
+ echo "DELIMITER ;;
+CREATE PROCEDURE adminer_alter (INOUT alter_command text) BEGIN
+ DECLARE _table_name, _engine, _table_collation varchar(64);
+ DECLARE _table_comment varchar(64);
+ DECLARE done bool DEFAULT 0;
+ DECLARE tables CURSOR FOR $query;
+ DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
+ OPEN tables;
+ REPEAT
+ FETCH tables INTO _table_name, _engine, _table_collation, _table_comment;
+ IF NOT done THEN
+ CASE _table_name";
+ foreach (get_rows($query) as $row) {
+ $comment = q($row["ENGINE"] == "InnoDB" ? preg_replace('~(?:(.+); )?InnoDB free: .*~', '\\1', $row["TABLE_COMMENT"]) : $row["TABLE_COMMENT"]);
+ echo "
+ WHEN " . q($row["TABLE_NAME"]) . " THEN
+ " . (isset($row["ENGINE"]) ? "IF _engine != '$row[ENGINE]' OR _table_collation != '$row[TABLE_COLLATION]' OR _table_comment != $comment THEN
+ ALTER TABLE " . idf_escape($row["TABLE_NAME"]) . " ENGINE=$row[ENGINE] COLLATE=$row[TABLE_COLLATION] COMMENT=$comment;
+ END IF" : "BEGIN END") . ";";
+ }
+ echo "
+ ELSE
+ SET alter_command = CONCAT(alter_command, 'DROP TABLE `', REPLACE(_table_name, '`', '``'), '`;\\n');
+ END CASE;
+ END IF;
+ UNTIL done END REPEAT;
+ CLOSE tables;
+END;;
+DELIMITER ;
+CALL adminer_alter(@adminer_alter);
+DROP PROCEDURE adminer_alter;
+
+SELECT @adminer_alter;
+";
+ }
+
+ function dumpDatabase($db) {
+ static $first = true;
+ if ($_POST["format"] == "sql_alter") {
+ if ($first) {
+ $first = false;
+ echo "SET @adminer_alter = '';\n\n";
+ register_shutdown_function(array($this, '_database'));
+ } else {
+ $this->_database();
+ }
+ return true;
+ }
+ }
+
+ function dumpTable($table, $style, $is_view = false) {
+ if ($_POST["format"] == "sql_alter") {
+ $create = create_sql($table, $_POST["auto_increment"]);
+ if ($is_view) {
+ echo substr_replace($create, " OR REPLACE", 6, 0) . ";\n\n";
+ } else {
+ echo substr_replace($create, " IF NOT EXISTS", 12, 0) . ";\n\n";
+ // create procedure which iterates over original columns and adds new and removes old
+ $query = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, COLLATION_NAME, COLUMN_TYPE, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . q($table) . " ORDER BY ORDINAL_POSITION";
+ echo "DELIMITER ;;
+CREATE PROCEDURE adminer_alter (INOUT alter_command text) BEGIN
+ DECLARE _column_name, _collation_name, after varchar(64) DEFAULT '';
+ DECLARE _column_type, _column_default text;
+ DECLARE _is_nullable char(3);
+ DECLARE _extra varchar(30);
+ DECLARE _column_comment varchar(255);
+ DECLARE done, set_after bool DEFAULT 0;
+ DECLARE add_columns text DEFAULT '";
+ $fields = array();
+ $after = "";
+ foreach (get_rows($query) as $row) {
+ $default = $row["COLUMN_DEFAULT"];
+ $row["default"] = ($default !== null ? q($default) : "NULL");
+ $row["after"] = q($after); //! rgt AFTER lft, lft AFTER id doesn't work
+ $row["alter"] = escape_string(idf_escape($row["COLUMN_NAME"])
+ . " $row[COLUMN_TYPE]"
+ . ($row["COLLATION_NAME"] ? " COLLATE $row[COLLATION_NAME]" : "")
+ . ($default !== null ? " DEFAULT " . ($default == "CURRENT_TIMESTAMP" ? $default : $row["default"]) : "")
+ . ($row["IS_NULLABLE"] == "YES" ? "" : " NOT NULL")
+ . ($row["EXTRA"] ? " $row[EXTRA]" : "")
+ . ($row["COLUMN_COMMENT"] ? " COMMENT " . q($row["COLUMN_COMMENT"]) : "")
+ . ($after ? " AFTER " . idf_escape($after) : " FIRST")
+ );
+ echo ", ADD $row[alter]";
+ $fields[] = $row;
+ $after = $row["COLUMN_NAME"];
+ }
+ echo "';
+ DECLARE columns CURSOR FOR $query;
+ DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
+ SET @alter_table = '';
+ OPEN columns;
+ REPEAT
+ FETCH columns INTO _column_name, _column_default, _is_nullable, _collation_name, _column_type, _extra, _column_comment;
+ IF NOT done THEN
+ SET set_after = 1;
+ CASE _column_name";
+ foreach ($fields as $row) {
+ echo "
+ WHEN " . q($row["COLUMN_NAME"]) . " THEN
+ SET add_columns = REPLACE(add_columns, ', ADD $row[alter]', IF(
+ _column_default <=> $row[default] AND _is_nullable = '$row[IS_NULLABLE]' AND _collation_name <=> " . (isset($row["COLLATION_NAME"]) ? "'$row[COLLATION_NAME]'" : "NULL") . " AND _column_type = " . q($row["COLUMN_TYPE"]) . " AND _extra = '$row[EXTRA]' AND _column_comment = " . q($row["COLUMN_COMMENT"]) . " AND after = $row[after]
+ , '', ', MODIFY $row[alter]'));"
+ ; //! don't replace in comment
+ }
+ echo "
+ ELSE
+ SET @alter_table = CONCAT(@alter_table, ', DROP ', _column_name);
+ SET set_after = 0;
+ END CASE;
+ IF set_after THEN
+ SET after = _column_name;
+ END IF;
+ END IF;
+ UNTIL done END REPEAT;
+ CLOSE columns;
+ IF @alter_table != '' OR add_columns != '' THEN
+ SET alter_command = CONCAT(alter_command, 'ALTER TABLE " . table($table) . "', SUBSTR(CONCAT(add_columns, @alter_table), 2), ';\\n');
+ END IF;
+END;;
+DELIMITER ;
+CALL adminer_alter(@adminer_alter);
+DROP PROCEDURE adminer_alter;
+
+";
+ //! indexes
+ }
+ return true;
+ }
+ }
+
+}
diff --git a/plugins/plugin.php b/plugins/plugin.php
index 6c3233be..8762330d 100644
--- a/plugins/plugin.php
+++ b/plugins/plugin.php
@@ -301,6 +301,11 @@ class AdminerPlugin extends Adminer {
return $this->_applyPlugin(__FUNCTION__, $args);
}
+ function dumpDatabase() {
+ $args = func_get_args();
+ return $this->_applyPlugin(__FUNCTION__, $args);
+ }
+
function dumpTable() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);