CSV export

git-svn-id: https://adminer.svn.sourceforge.net/svnroot/adminer/trunk@445 7c3ca157-0c34-0410-bff1-cbf682f78f5c
This commit is contained in:
jakubvrana 2008-08-16 12:28:31 +00:00
parent 7d09bd7e34
commit 7afa763715
4 changed files with 137 additions and 96 deletions

View file

@ -1,84 +1,44 @@
<?php <?php
include "./export.inc.php";
function dump_table($table, $style) { function dump_table($table, $style) {
global $mysql, $max_packet, $types; global $mysql, $max_packet, $types;
if ($style) { if ($style) {
$result = $mysql->query("SHOW CREATE TABLE " . idf_escape($table)); if ($_POST["format"] == "csv") {
if ($result) { dump_csv(array_keys(fields($table)));
if ($style == "DROP, CREATE") { } else {
echo "DROP TABLE " . idf_escape($table) . ";\n"; $result = $mysql->query("SHOW CREATE TABLE " . idf_escape($table));
} if ($result) {
$create = $mysql->result($result, 1); if ($style == "DROP, CREATE") {
echo ($style == "CREATE, ALTER" ? preg_replace('~^CREATE TABLE ~', '\\0IF NOT EXISTS ', $create) : $create) . ";\n\n"; echo "DROP TABLE " . idf_escape($table) . ";\n";
if ($max_packet < 1073741824) { // protocol limit
$row_size = 21 + strlen(idf_escape($table));
foreach (fields($table) as $field) {
$type = $types[$field["type"]];
$row_size += 5 + ($field["length"] ? $field["length"] : $type) * (preg_match('~char|text|enum~', $field["type"]) ? 3 : 1); // UTF-8 in MySQL uses up to 3 bytes
} }
if ($row_size > $max_packet) { $create = $mysql->result($result, 1);
$max_packet = 1024 * ceil($row_size / 1024); echo ($style == "CREATE, ALTER" ? preg_replace('~^CREATE TABLE ~', '\\0IF NOT EXISTS ', $create) : $create) . ";\n\n";
echo "SET max_allowed_packet = $max_packet, GLOBAL max_allowed_packet = $max_packet;\n"; if ($max_packet < 1073741824) { // protocol limit
} $row_size = 21 + strlen(idf_escape($table));
} foreach (fields($table) as $field) {
$result->free(); $type = $types[$field["type"]];
} $row_size += 5 + ($field["length"] ? $field["length"] : $type) * (preg_match('~char|text|enum~', $field["type"]) ? 3 : 1); // UTF-8 in MySQL uses up to 3 bytes
if ($mysql->server_info >= 5) {
$result = $mysql->query("SHOW TRIGGERS LIKE '" . $mysql->escape_string(addcslashes($table, "%_")) . "'");
if ($result->num_rows) {
echo "DELIMITER ;;\n\n";
while ($row = $result->fetch_assoc()) {
echo "CREATE TRIGGER " . idf_escape($row["Trigger"]) . " $row[Timing] $row[Event] ON " . idf_escape($row["Table"]) . " FOR EACH ROW $row[Statement];;\n\n";
}
echo "DELIMITER ;\n\n";
}
$result->free();
}
}
}
function dump_data($table, $style) {
global $mysql, $max_packet;
if ($style) {
if ($style == "TRUNCATE, INSERT") {
echo "TRUNCATE " . idf_escape($table) . ";\n";
}
$result = $mysql->query("SELECT * FROM " . idf_escape($table)); //! enum and set as numbers, binary as _binary, microtime
if ($result) {
if ($style == "UPDATE") {
while ($row = $result->fetch_assoc()) {
$set = array();
foreach ($row as $key => $val) {
$row[$key] = (isset($val) ? "'" . $mysql->escape_string($val) . "'" : "NULL");
$set[] = idf_escape($key) . " = " . (isset($val) ? "'" . $mysql->escape_string($val) . "'" : "NULL");
} }
echo "INSERT INTO " . idf_escape($table) . " (" . implode(", ", array_map('idf_escape', array_keys($row))) . ") VALUES (" . implode(", ", $row) . ") ON DUPLICATE KEY UPDATE " . implode(", ", $set) . ";\n"; if ($row_size > $max_packet) {
} $max_packet = 1024 * ceil($row_size / 1024);
} elseif ($result->num_rows) { echo "SET max_allowed_packet = $max_packet, GLOBAL max_allowed_packet = $max_packet;\n";
$insert = "INSERT INTO " . idf_escape($table) . " VALUES ";
$length = 0;
while ($row = $result->fetch_row()) {
foreach ($row as $key => $val) {
$row[$key] = (isset($val) ? "'" . $mysql->escape_string($val) . "'" : "NULL");
}
$s = "(" . implode(", ", $row) . ")";
if (!$length) {
echo $insert, $s;
$length = strlen($insert) + strlen($s);
} else {
$length += 2 + strlen($s);
if ($length < $max_packet) {
echo ", ", $s;
} else {
echo ";\n", $insert, $s;
$length = strlen($insert) + strlen($s);
}
} }
} }
echo ";\n"; $result->free();
}
if ($mysql->server_info >= 5) {
$result = $mysql->query("SHOW TRIGGERS LIKE '" . $mysql->escape_string(addcslashes($table, "%_")) . "'");
if ($result->num_rows) {
echo "DELIMITER ;;\n\n";
while ($row = $result->fetch_assoc()) {
echo "CREATE TRIGGER " . idf_escape($row["Trigger"]) . " $row[Timing] $row[Event] ON " . idf_escape($row["Table"]) . " FOR EACH ROW $row[Statement];;\n\n";
}
echo "DELIMITER ;\n\n";
}
$result->free();
} }
$result->free();
} }
echo "\n";
} }
} }
@ -103,7 +63,7 @@ function dump_routines($db) {
function dump($db, $style) { function dump($db, $style) {
global $mysql; global $mysql;
if (in_array($style, array("DROP, CREATE", "CREATE", "CREATE, ALTER")) && ($result = $mysql->query("SHOW CREATE DATABASE " . idf_escape($db)))) { if ($_POST["format"] != "csv" && in_array($style, array("DROP, CREATE", "CREATE", "CREATE, ALTER")) && ($result = $mysql->query("SHOW CREATE DATABASE " . idf_escape($db)))) {
if ($style == "DROP, CREATE") { if ($style == "DROP, CREATE") {
echo "DROP DATABASE IF EXISTS " . idf_escape($db) . ";\n"; echo "DROP DATABASE IF EXISTS " . idf_escape($db) . ";\n";
} }
@ -112,26 +72,33 @@ function dump($db, $style) {
$result->free(); $result->free();
} }
if ($style) { if ($style) {
echo "USE " . idf_escape($db) . ";\n"; echo ($_POST["format"] != "csv" ? "USE " . idf_escape($db) . ";\n" : "");
if (!strlen($_GET["db"])) { if (!strlen($_GET["db"])) {
$views = array(); $views = array();
$result = $mysql->query("SHOW TABLE STATUS"); $result = $mysql->query("SHOW TABLE STATUS");
while ($row = $result->fetch_assoc()) { while ($row = $result->fetch_assoc()) {
if (isset($row["Engine"])) { if (isset($row["Engine"])) {
if ($_POST["format"] == "csv") {
ob_start();
}
dump_table($row["Name"], $_POST["tables"][0]); dump_table($row["Name"], $_POST["tables"][0]);
dump_data($row["Name"], $_POST["data"][0]); dump_data($row["Name"], $_POST["data"][0]);
if ($_POST["format"] == "csv") {
echo tar_file("$db/$row[Name].csv", ob_get_clean());
}
} else { } else {
$views[] = $row["Name"]; $views[] = $row["Name"];
} }
} }
$result->free(); $result->free();
foreach ($views as $view) { if ($_POST["format"] != "csv") {
dump_table($view, $_POST["tables"][0]); foreach ($views as $view) {
dump_table($view, $_POST["tables"][0]);
}
dump_routines($db);
} }
dump_routines($db);
} }
} }
echo "\n\n";
} }
function tar_file($filename, $contents) { function tar_file($filename, $contents) {
@ -141,26 +108,22 @@ function tar_file($filename, $contents) {
$checksum += ord($return{$i}); $checksum += ord($return{$i});
} }
$return .= sprintf("%06o", $checksum) . "\0 "; $return .= sprintf("%06o", $checksum) . "\0 ";
$return .= str_repeat("\0", 512 - strlen($return)); return $return . str_repeat("\0", 512 - strlen($return)) . $contents . str_repeat("\0", 511 - (strlen($contents) + 511) % 512);
$return .= $contents;
if (strlen($contents) % 512) {
$return .= str_repeat("\0", 512 - strlen($contents) % 512);
}
return $return;
} }
if ($_POST) { if ($_POST) {
header("Content-Type: text/plain; charset=utf-8");
$filename = (strlen($_GET["db"]) ? preg_replace('~[^a-z0-9_]~i', '-', (strlen($_GET["dump"]) ? $_GET["dump"] : $_GET["db"])) : "dump"); $filename = (strlen($_GET["db"]) ? preg_replace('~[^a-z0-9_]~i', '-', (strlen($_GET["dump"]) ? $_GET["dump"] : $_GET["db"])) : "dump");
$filename .= ($_POST["format"] == "sql" ? ".sql" : (!strlen($_GET["db"]) || count(array_filter($_POST["data"])) >= 1 ? ".tar" : ".csv")); $ext = ($_POST["format"] == "sql" ? "sql" : (!strlen($_GET["db"]) || count(array_filter($_POST["tables"]) + array_filter($_POST["data"])) > 1 ? "tar" : "csv"));
header("Content-Disposition: " . ($_POST["output"] == "file" ? "attachment" : "inline") . "; filename=$filename"); header("Content-Type: " . ($ext == "tar" ? "application/x-tar" : ($ext == "sql" || $_POST["output"] != "file" ? "text/plain" : "text/csv")) . "; charset=utf-8");
header("Content-Disposition: " . ($_POST["output"] == "file" ? "attachment" : "inline") . "; filename=$filename.$ext");
$max_packet = 16777216; if ($_POST["format"] != "csv") {
echo "SET NAMES utf8;\n"; $max_packet = 16777216;
echo "SET foreign_key_checks = 0;\n"; echo "SET NAMES utf8;\n";
echo "SET time_zone = '" . $mysql->escape_string($mysql->result($mysql->query("SELECT @@time_zone"))) . "';\n"; echo "SET foreign_key_checks = 0;\n";
echo "SET max_allowed_packet = $max_packet, GLOBAL max_allowed_packet = $max_packet;\n"; echo "SET time_zone = '" . $mysql->escape_string($mysql->result($mysql->query("SELECT @@time_zone"))) . "';\n";
echo "\n"; echo "SET max_allowed_packet = $max_packet, GLOBAL max_allowed_packet = $max_packet;\n";
echo "\n";
}
foreach ($_POST["databases"] as $db => $style) { foreach ($_POST["databases"] as $db => $style) {
$db = bracket_escape($db, "back"); $db = bracket_escape($db, "back");
@ -171,8 +134,14 @@ if ($_POST) {
if (strlen($_GET["db"])) { if (strlen($_GET["db"])) {
foreach ($_POST["tables"] as $key => $style) { foreach ($_POST["tables"] as $key => $style) {
$table = bracket_escape($key, "back"); $table = bracket_escape($key, "back");
if ($ext == "tar") {
ob_start();
}
dump_table($table, $style); dump_table($table, $style);
dump_data($table, $_POST["data"][$key]); dump_data($table, $_POST["data"][$key]);
if ($ext == "tar") {
echo tar_file("$table.csv", ob_get_clean());
}
} }
dump_routines($_GET["db"]); dump_routines($_GET["db"]);
} }
@ -195,7 +164,7 @@ function check(td, name, value) {
<form action="" method="post"> <form action="" method="post">
<p> <p>
<?php echo lang('Output'); ?>: <select name="output"><option value="text"><?php echo lang('text'); ?></option><option value="file"><?php echo lang('file'); ?></option></select> <?php echo lang('Output'); ?>: <select name="output"><option value="text"><?php echo lang('open'); ?></option><option value="file"><?php echo lang('save'); ?></option></select>
<?php echo lang('Format'); ?>: <select name="format"><option value="sql"><?php echo lang('SQL'); ?></option><option value="csv"><?php echo lang('CSV'); ?></option></select> <?php echo lang('Format'); ?>: <select name="format"><option value="sql"><?php echo lang('SQL'); ?></option><option value="csv"><?php echo lang('CSV'); ?></option></select>
</p> </p>

57
export.inc.php Normal file
View file

@ -0,0 +1,57 @@
<?php
function dump_csv($row) {
foreach ($row as $key => $val) {
if (preg_match("~[\"\n,]~", $val)) {
$row[$key] = '"' . str_replace('"', '""', $val) . '"';
}
}
echo implode(",", $row) . "\n";
}
function dump_data($table, $style) {
global $mysql, $max_packet;
if ($style) {
if ($_POST["format"] != "csv" && $style == "TRUNCATE, INSERT") {
echo "TRUNCATE " . idf_escape($table) . ";\n";
}
$result = $mysql->query("SELECT * FROM " . idf_escape($table)); //! enum and set as numbers, binary as _binary, microtime
if ($result) {
$insert = "INSERT INTO " . idf_escape($table) . " VALUES ";
$length = 0;
while ($row = $result->fetch_assoc()) {
if ($_POST["format"] == "csv") {
dump_csv($row);
} elseif ($style == "UPDATE") {
$set = array();
foreach ($row as $key => $val) {
$row[$key] = (isset($val) ? "'" . $mysql->escape_string($val) . "'" : "NULL");
$set[] = idf_escape($key) . " = " . (isset($val) ? "'" . $mysql->escape_string($val) . "'" : "NULL");
}
echo "INSERT INTO " . idf_escape($table) . " (" . implode(", ", array_map('idf_escape', array_keys($row))) . ") VALUES (" . implode(", ", $row) . ") ON DUPLICATE KEY UPDATE " . implode(", ", $set) . ";\n";
} else {
foreach ($row as $key => $val) {
$row[$key] = (isset($val) ? "'" . $mysql->escape_string($val) . "'" : "NULL");
}
$s = "(" . implode(", ", $row) . ")";
if (!$length) {
echo $insert, $s;
$length = strlen($insert) + strlen($s);
} else {
$length += 2 + strlen($s);
if ($length < $max_packet) {
echo ", ", $s;
} else {
echo ";\n", $insert, $s;
$length = strlen($insert) + strlen($s);
}
}
}
}
if ($_POST["format"] != "csv" && $style != "UPDATE" && $result->num_rows) {
echo ";\n";
}
$result->free();
}
echo "\n";
}
}

View file

@ -159,4 +159,17 @@ $translations = array(
'Logged as: %s' => 'Přihlášen jako: %s', 'Logged as: %s' => 'Přihlášen jako: %s',
'Move up' => 'Přesunout nahoru', 'Move up' => 'Přesunout nahoru',
'Move down' => 'Přesunout dolů', 'Move down' => 'Přesunout dolů',
'Functions' => 'Funkce',
'Aggregation' => 'Agregace',
'Export' => 'Export',
'Output' => 'Výstup',
'open' => 'otevřít',
'save' => 'uložit',
'Format' => 'Formát',
'SQL' => 'SQL',
'CSV' => 'CSV',
'skip' => 'přeskočit',
'Tables' => 'Tabulky',
'Structure' => 'Struktura',
'Data' => 'Data',
); );

View file

@ -6,8 +6,10 @@ Rename table to other database
Clone row Clone row
Execution time in sql.inc.php Execution time in sql.inc.php
Input function results in edit Input function results in edit
Choose tables and data to export Bulk update - leave original, set to value, set to NULL
? CSV export Save uploaded files after error to session variable instead of hidden field
Export transactions
Export compress
? Query print ? Query print
? Access without login - accept $_GET ? Access without login - accept $_GET
? Save token also to cookie - for session expiration and login in other window ? Save token also to cookie - for session expiration and login in other window