From: jakubvrana Date: Sat, 13 Jun 2009 20:55:19 +0000 (+0000) Subject: Change directory structure X-Git-Tag: v3.0.0~843 X-Git-Url: https://git.joonet.de/?a=commitdiff_plain;h=e1bc7af8f3f145e40067f1a04ae2a832e5d4da6e;p=adminer.git Change directory structure git-svn-id: https://adminer.svn.sourceforge.net/svnroot/adminer/trunk@682 7c3ca157-0c34-0410-bff1-cbf682f78f5c --- diff --git a/_compile.php b/_compile.php deleted file mode 100644 index ad77f440..00000000 --- a/_compile.php +++ /dev/null @@ -1,208 +0,0 @@ - "'", "\\\\" => "\\")); - $s = ($translations[$idf] ? $translations[$idf] : $idf); - if ($match[3] == ",") { - return "$match[1]" . (is_array($s) ? "lang(array('" . implode("', '", array_map('add_apo_slashes', $s)) . "')," : "sprintf('" . add_apo_slashes($s) . "',"); - } - return ($match[1] && $match[4] ? $s : "$match[1]'" . add_apo_slashes($s) . "'$match[4]"); -} - -$lang_ids = array(); -function lang_ids($match) { - global $lang_ids; - return 'lang(' . $lang_ids[stripslashes($match[1])] . $match[2]; -} - -function put_file($match) { - global $lang_ids; - if ($match[2] == './lang/$LANG.inc.php') { - if ($_COOKIE["lang"]) { - return ""; - } - $return = ""; - foreach (glob(dirname(__FILE__) . "/lang/*.inc.php") as $filename) { - include $filename; - foreach ($translations as $key => $val) { - if (!isset($lang_ids[$key])) { - $lang_ids[$key] = count($lang_ids); - } - } - } - foreach (glob(dirname(__FILE__) . "/lang/*.inc.php") as $filename) { - include $filename; - $translation_ids = array_flip($lang_ids); - foreach ($translations as $key => $val) { - $translation_ids[$lang_ids[$key]] = $val; - } - $return .= 'case "' . basename($filename, '.inc.php') . '": $translations = array('; - foreach ($translation_ids as $val) { - $return .= (is_array($val) ? "array('" . implode("', '", array_map('add_apo_slashes', $val)) . "')" : "'" . add_apo_slashes($val) . "'") . ", "; - } - $return = substr($return, 0, -2) . "); break;\n"; - } - return "switch (\$LANG) {\n$return}\n"; - } - $return = file_get_contents(dirname(__FILE__) . "/$match[2]"); - if ($match[2] != "./include/lang.inc.php" || !$_COOKIE["lang"]) { - $tokens = token_get_all($return); - return "?>\n$return" . (in_array($tokens[count($tokens) - 1][0], array(T_CLOSE_TAG, T_INLINE_HTML), true) ? "= 0) { - $return .= $chars{$number % strlen($chars)}; - $number = floor($number / strlen($chars)) - 1; - } - return $return; -} - -// based on Dgx's PHP shrinker -function php_shrink($input) { - $special_variables = array_flip(array('$this', '$GLOBALS', '$_GET', '$_POST', '$_FILES', '$_COOKIE', '$_SESSION', '$_SERVER')); - static $short_variables = array(); - $shortening = true; - $special_functions = array_flip(array('Min_DB', 'Min_Result', '__construct')); - $defined_functions = array(); - static $short_functions = array(); - $tokens = token_get_all($input); - - foreach ($tokens as $i => $token) { - if ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) { - $short_variables[$token[1]]++; - } elseif ($token[0] === T_STRING && $tokens[$i+1] === '(' && !isset($special_functions[$token[1]])) { - $short_functions[$token[1]]++; - if ($tokens[$i-2][0] === T_FUNCTION) { - $defined_functions[$token[1]] = true; - } - } - } - - arsort($short_variables); - foreach (array_keys($short_variables) as $number => $key) { - $short_variables[$key] = short_identifier($number, implode("", range('a', 'z')) . '_' . implode("", range('A', 'Z'))); // could use also numbers and \x7f-\xff - } - arsort($short_functions); - $number = 0; - foreach ($short_functions as $key => $val) { - if (isset($defined_functions[$key])) { - do { - $short_functions[$key] = short_identifier($number, implode("", range('a', 'z'))); - $number++; - } while (isset($short_functions[$short_functions[$key]])); - } - } - - $set = array_flip(preg_split('//', '!"#$&\'()*+,-./:;<=>?@[\]^`{|}')); - $space = ''; - $output = ''; - $in_echo = false; - for (reset($tokens); list($i, $token) = each($tokens); ) { - if (!is_array($token)) { - $token = array(0, $token); - } - if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE) { - $space = "\n"; - } else { - if ($token[0] == T_VAR) { - $shortening = false; - } elseif (!$shortening) { - if ($token[1] == ';') { - $shortening = true; - } - } elseif ($token[0] == T_ECHO) { - $in_echo = true; - } elseif ($token[1] == ';' && $in_echo) { - $in_echo = false; - if ($tokens[$i+1][0] === T_WHITESPACE && $tokens[$i+2][0] === T_ECHO) { - next($tokens); - next($tokens); - $token[1] = '.'; //! join ''.'' and ""."" - } - } elseif ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) { - $token[1] = '$' . $short_variables[$token[1]]; - } elseif ($token[0] === T_STRING && $tokens[$i+1] === '(' && isset($defined_functions[$token[1]]) - && $tokens[$i-1][0] !== T_DOUBLE_COLON && $tokens[$i-2][0] !== T_NEW && $tokens[$i-2][1] !== '_result' - ) { - $token[1] = $short_functions[$token[1]]; - } elseif ($token[0] == T_CONSTANT_ENCAPSED_STRING && (($tokens[$i-1] === '(' && in_array($tokens[$i-2][1], array('array_map', 'set_exception_handler'), true)) || $token[1] == "'normalize_enum'") && isset($defined_functions[substr($token[1], 1, -1)])) { - $token[1] = "'" . $short_functions[substr($token[1], 1, -1)] . "'"; - } - if (isset($set[substr($output, -1)]) || isset($set[$token[1]{0}])) { - $space = ''; - } - $output .= $space . $token[1]; - $space = ''; - } - } - return $output; -} - -error_reporting(E_ALL & ~E_NOTICE); -if ($_SERVER["argc"] > 1) { - $_COOKIE["lang"] = $_SERVER["argv"][1]; - include dirname(__FILE__) . "/include/lang.inc.php"; - if ($_SERVER["argc"] != 2 || !isset($langs[$_COOKIE["lang"]])) { - echo "Usage: php _compile.php [lang]\nPurpose: Compile adminer[-lang].php from index.php.\n"; - exit(1); - } - include dirname(__FILE__) . "/lang/$_COOKIE[lang].inc.php"; -} - -$filename = "adminer" . ($_COOKIE["lang"] ? "-$_COOKIE[lang]" : "") . ".php"; -$file = file_get_contents(dirname(__FILE__) . "/index.php"); -$file = preg_replace_callback('~\\b(include|require) "([^"]*)";~', 'put_file', $file); -$file = preg_replace("~if \\(isset\\(\\\$_SESSION\\[\"coverage.*\n}\n| && !isset\\(\\\$_SESSION\\[\"coverage\"\\]\\)~sU", '', $file); -if ($_COOKIE["lang"]) { - $file = preg_replace_callback("~(<\\?php\\s*echo )?lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])(;\\s*\\?>)?~s", 'remove_lang', $file); - $file = str_replace("\n", "", $file); - $file = str_replace('', $_COOKIE["lang"], $file); -} else { - $file = preg_replace_callback("~lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])~s", 'lang_ids', $file); -} -$replace = 'htmlspecialchars(preg_replace("~\\\\\\\\?.*~", "", $_SERVER["REQUEST_URI"])) . "?file=\\0&version=' . $VERSION; -$file = preg_replace('~default\\.css|functions\\.js|favicon\\.ico~', '', $file); -$file = preg_replace('~(plus|cross|up|down|arrow)\\.gif~', '" . ' . $replace, $file); -$file = str_replace('error_reporting(E_ALL & ~E_NOTICE);', 'error_reporting(E_ALL & ~E_NOTICE); -if (isset($_GET["file"])) { - header("Expires: " . gmdate("D, d M Y H:i:s", time() + 365*24*60*60) . " GMT"); - if ($_GET["file"] == "favicon.ico") { - header("Content-Type: image/x-icon"); - echo base64_decode("' . base64_encode(file_get_contents(dirname(__FILE__) . "/favicon.ico")) . '"); - } elseif ($_GET["file"] == "default.css") { - header("Content-Type: text/css"); - ?>' . preg_replace('~\\s*([:;{},])\\s*~', '\\1', file_get_contents(dirname(__FILE__) . "/default.css")) . '' . JSMin::minify(file_get_contents(dirname(__FILE__) . "/functions.js")) . '\n?|\\?>\n?<\\?php~", '', $file); -$file = php_shrink($file); -fwrite(fopen($filename, "w"), $file); -echo "$filename created.\n"; diff --git a/_coverage.php b/_coverage.php deleted file mode 100644 index 8363ca46..00000000 --- a/_coverage.php +++ /dev/null @@ -1,77 +0,0 @@ -]+)~', $s, $matches); - foreach ($matches[1] as $val) { - if ($val{0} == "/") { - array_pop($return); - } elseif (substr($val, -1) != "/") { - $return[] = $val; - } - } - return $return; -} - -if (!extension_loaded("xdebug")) { - echo "

Xdebug has to be enabled.

\n"; -} - -if ($_GET["start"]) { - xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); - $_SESSION["coverage"] = array(); - include "./index.php"; - header("Location: ."); - exit; -} -if ($_GET["filename"]) { - $filename = basename($_GET["filename"]); - $cov = $_SESSION["coverage"][realpath($filename)]; - $file = explode("
", highlight_file($filename, true)); - unset($prev_color); - $s = ""; - for ($l=0; $l <= count($file); $l++) { - $line = $file[$l]; - $color = "#C0FFC0"; // tested - switch ($cov[$l+1]) { - case -1: $color = "#FFC0C0"; break; // untested - case -2: $color = "Silver"; break; // dead code - case null: $color = ""; break; // not executable - } - if (!isset($prev_color)) { - $prev_color = $color; - } - if ($prev_color != $color || !isset($line)) { - echo "" . $s; - $open_tags = xhtml_open_tags($s); - foreach (array_reverse($open_tags) as $tag) { - echo ""; - } - echo "\n"; - $s = ($open_tags ? "<" . implode("><", $open_tags) . ">" : ""); - $prev_color = $color; - } - $s .= "$line
\n"; - } -} else { - echo "\n"; - foreach (glob("*.php") as $filename) { - if ($filename{0} != "_") { - $cov = $_SESSION["coverage"][realpath($filename)]; - $ratio = 0; - if (isset($cov)) { - $values = array_count_values($cov); - $ratio = round(100 - 100 * $values[-1] / count($cov)); - } - echo "\n"; - } - } - echo "
$ratio%$filename
\n"; - echo "

Start new coverage (requires Xdebug)

\n"; -} diff --git a/_lang.php b/_lang.php deleted file mode 100644 index 4be0f33d..00000000 --- a/_lang.php +++ /dev/null @@ -1,41 +0,0 @@ - 1) { - $_COOKIE["lang"] = $_SERVER["argv"][1]; - include dirname(__FILE__) . "/include/lang.inc.php"; - if ($_SERVER["argc"] != 2 || !isset($langs[$_COOKIE["lang"]])) { - echo "Usage: php _lang.php [lang]\nPurpose: Update lang/*.inc.php from source code messages.\n"; - exit(1); - } -} - -$messages_all = array(); -foreach (array_merge(glob(dirname(__FILE__) . "/*.php"), glob(dirname(__FILE__) . "/include/*.php")) as $filename) { - $file = file_get_contents($filename); - if (preg_match_all("~lang\\(('(?:[^\\\\']+|\\\\.)*')([),])~", $file, $matches)) { - $messages_all += array_combine($matches[1], $matches[2]); - } -} - -foreach (glob(dirname(__FILE__) . "/lang/" . ($_COOKIE["lang"] ? $_COOKIE["lang"] : "*") . ".inc.php") as $filename) { - $messages = $messages_all; - preg_match_all("~^(\\s*)(?:// )?(('(?:[^\\\\']+|\\\\.)*') => .*[^,\n]),?~m", file_get_contents($filename), $matches, PREG_SET_ORDER); - $s = ""; - foreach ($matches as $match) { - if (isset($messages[$match[3]])) { - $s .= "$match[1]$match[2],\n"; - unset($messages[$match[3]]); - } else { - $s .= "$match[1]// $match[2],\n"; - } - } - foreach($messages as $idf => $val) { - if ($val == "," && strpos($idf, "%d")) { - $s .= "\t$idf => array(),\n"; - } elseif (basename($filename) != "en.inc.php") { - $s .= "\t$idf => null,\n"; - } - } - fwrite(fopen($filename, "w"), " $field) { + if (substr($field["inout"], -3) == "OUT") { + $out[$i] = "@" . idf_escape($field["field"]) . " AS " . idf_escape($field["field"]); + } + if (!$field["inout"] || substr($field["inout"], 0, 2) == "IN") { + $in[] = $i; + } +} + +if (!$error && $_POST) { + $call = array(); + foreach ($routine["fields"] as $key => $field) { + if (in_array($key, $in)) { + $val = process_input($key, $field); + if ($val === false) { + $val = "''"; + } + if (isset($out[$key])) { + $dbh->query("SET @" . idf_escape($field["field"]) . " = " . $val); + } + } + $call[] = (isset($out[$key]) ? "@" . idf_escape($field["field"]) : $val); + } + $result = $dbh->multi_query((isset($_GET["callf"]) ? "SELECT" : "CALL") . " " . idf_escape($_GET["call"]) . "(" . implode(", ", $call) . ")"); + if (!$result) { + echo "

" . htmlspecialchars($dbh->error) . "

\n"; + } else { + do { + $result = $dbh->store_result(); + if (is_object($result)) { + select($result); + } else { + echo "

" . lang('Routine has been called, %d row(s) affected.', $dbh->affected_rows) . "

\n"; + } + } while ($dbh->next_result()); + if ($out) { + select($dbh->query("SELECT " . implode(", ", $out))); + } + } +} +?> + +
+\n"; + foreach ($in as $key) { + $field = $routine["fields"][$key]; + echo "" . htmlspecialchars($field["field"]) . ""; + $value = $_POST["fields"][$key]; + if (strlen($value) && ($field["type"] == "enum" || $field["type"] == "set")) { + $value = intval($value); + } + input($key, $field, $value); // param name can be empty + echo "\n"; + } + echo "\n"; +} +?> +

+ + +

+
diff --git a/adminer/create.inc.php b/adminer/create.inc.php new file mode 100644 index 00000000..cd638f65 --- /dev/null +++ b/adminer/create.inc.php @@ -0,0 +1,162 @@ + $field) { + if (strlen($field["field"]) && isset($types[$field["type"]])) { + $fields[] = (!strlen($_GET["create"]) ? "\n" : (strlen($field["orig"]) ? "\nCHANGE " . idf_escape($field["orig"]) . " " : "\nADD ")) + . idf_escape($field["field"]) . process_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->escape_string($orig_fields[$field["orig"]]["default"]) . "'" : "") //! timestamp + . ($key == $_POST["auto_increment_col"] ? " AUTO_INCREMENT$auto_increment_index" : "") + . " COMMENT '" . $dbh->escape_string($field["comment"]) . "'" + . (strlen($_GET["create"]) ? " $after" : "") + ; + $after = "AFTER " . idf_escape($field["field"]); + } elseif (strlen($field["orig"])) { + $fields[] = "\nDROP " . idf_escape($field["orig"]); + } + } + $status = ($_POST["Engine"] ? "ENGINE='" . $dbh->escape_string($_POST["Engine"]) . "'" : "") + . ($_POST["Collation"] ? " COLLATE '" . $dbh->escape_string($_POST["Collation"]) . "'" : "") + . (strlen($_POST["Auto_increment"]) ? " AUTO_INCREMENT=" . intval($_POST["Auto_increment"]) : "") + . " COMMENT='" . $dbh->escape_string($_POST["Comment"]) . "'" + ; + if (in_array($_POST["partition_by"], $partition_by)) { + $partitions = array(); + if ($_POST["partition_by"] == 'RANGE' || $_POST["partition_by"] == 'LIST') { + foreach (array_filter($_POST["partition_names"]) as $key => $val) { + $value = $_POST["partition_values"][$key]; + $partitions[] = "\nPARTITION $val VALUES " . ($_POST["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . (strlen($value) ? " ($value)" : " MAXVALUE"); //! SQL injection + } + } + $status .= "\nPARTITION BY $_POST[partition_by]($_POST[partition])" . ($partitions ? " (" . implode(",", $partitions) . "\n)" : ($_POST["partitions"] ? " PARTITIONS " . intval($_POST["partitions"]) : "")); + } elseif ($dbh->server_info >= 5.1 && strlen($_GET["create"])) { + $status .= "\nREMOVE PARTITIONING"; + } + $location = $SELF . "table=" . urlencode($_POST["name"]); + if (strlen($_GET["create"])) { + query_redirect("ALTER TABLE " . idf_escape($_GET["create"]) . implode(",", $fields) . ",\nRENAME TO " . idf_escape($_POST["name"]) . ",\n$status", $location, lang('Table has been altered.')); + } else { + query_redirect("CREATE TABLE " . idf_escape($_POST["name"]) . " (" . implode(",", $fields) . "\n) $status", $location, lang('Table has been created.')); + } + } +} +page_header((strlen($_GET["create"]) ? lang('Alter table') : lang('Create table')), $error, array("table" => $_GET["create"]), $_GET["create"]); + +$engines = array(); +$result = $dbh->query("SHOW ENGINES"); +while ($row = $result->fetch_assoc()) { + if ($row["Support"] == "YES" || $row["Support"] == "DEFAULT") { + $engines[] = $row["Engine"]; + } +} +$result->free(); + +if ($_POST) { + $row = $_POST; + if ($row["auto_increment_col"]) { + $row["fields"][$row["auto_increment_col"]]["auto_increment"] = true; + } + process_fields($row["fields"]); +} elseif (strlen($_GET["create"])) { + $row = table_status($_GET["create"]); + table_comment($row); + $row["name"] = $_GET["create"]; + $row["fields"] = array_values($orig_fields); + if ($dbh->server_info >= 5.1) { + $from = "FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = '" . $dbh->escape_string($_GET["db"]) . "' AND TABLE_NAME = '" . $dbh->escape_string($_GET["create"]) . "'"; + $result = $dbh->query("SELECT PARTITION_METHOD, PARTITION_ORDINAL_POSITION, PARTITION_EXPRESSION $from ORDER BY PARTITION_ORDINAL_POSITION DESC LIMIT 1"); + list($row["partition_by"], $row["partitions"], $row["partition"]) = $result->fetch_row(); + $result->free(); + $row["partition_names"] = array(); + $row["partition_values"] = array(); + $result = $dbh->query("SELECT PARTITION_NAME, PARTITION_DESCRIPTION $from AND PARTITION_NAME != '' ORDER BY PARTITION_ORDINAL_POSITION"); + while ($row1 = $result->fetch_assoc()) { + $row["partition_names"][] = $row1["PARTITION_NAME"]; + $row["partition_values"][] = $row1["PARTITION_DESCRIPTION"]; + } + $result->free(); + $row["partition_names"][] = ""; + } +} else { + $row = array("fields" => array(array("field" => "")), "partition_names" => array("")); +} +$collations = collations(); + +$suhosin = floor(extension_loaded("suhosin") ? (min(ini_get("suhosin.request.max_vars"), ini_get("suhosin.post.max_vars")) - 13) / 8 : 0); +if ($suhosin && count($row["fields"]) > $suhosin) { + echo "

" . htmlspecialchars(lang('Maximum number of allowed fields exceeded. Please increase %s and %s.', 'suhosin.post.max_vars', 'suhosin.request.max_vars')) . "

\n"; +} +?> + +
+

+: " /> + + + +

+ + +
+

+: " /> +: " maxlength="60" /> + +

+

+ + + /> +

+server_info >= 5.1) { + $partition_table = ereg('RANGE|LIST', $row["partition_by"]); + ?> +
+

+ +(" />) +: " /> +

+> + + $val) { + echo ''; + echo ''; + echo ''; + echo "\n"; +} +?> + +
+ +
diff --git a/adminer/createv.inc.php b/adminer/createv.inc.php new file mode 100644 index 00000000..4113df84 --- /dev/null +++ b/adminer/createv.inc.php @@ -0,0 +1,32 @@ + $_GET["createv"]), $_GET["createv"]); + +$row = array(); +if ($_POST) { + $row = $_POST; +} elseif (strlen($_GET["createv"])) { + $row = view($_GET["createv"]); + $row["name"] = $_GET["createv"]; +} +?> + +
+

+

+ + +: " maxlength="64" /> + + /> +

+
diff --git a/adminer/cross.gif b/adminer/cross.gif new file mode 100644 index 00000000..05b5061c Binary files /dev/null and b/adminer/cross.gif differ diff --git a/adminer/database.inc.php b/adminer/database.inc.php new file mode 100644 index 00000000..0e901fa1 --- /dev/null +++ b/adminer/database.inc.php @@ -0,0 +1,76 @@ +escape_string($_POST["collation"]) . "'" : ""))) { + $failed = true; + } + $last = $db; + } + } + if (query_redirect(queries(), $SELF . "db=" . urlencode($last), lang('Database has been created.'), !strlen($_GET["db"]), false, $failed)) { + $result = $dbh->query("SHOW TABLES"); + while ($row = $result->fetch_row()) { + if (!queries("RENAME TABLE " . idf_escape($row[0]) . " TO " . idf_escape($_POST["name"]) . "." . idf_escape($row[0]))) { + break; + } + } + $result->free(); + if (!$row) { + queries("DROP DATABASE " . idf_escape($_GET["db"])); + } + query_redirect(queries(), preg_replace('~db=[^&]*&~', '', $SELF) . "db=" . urlencode($_POST["name"]), lang('Database has been renamed.'), !$row, false, $row); + } + } else { + if (!$_POST["collation"]) { + redirect(substr($SELF, 0, -1)); + } + query_redirect("ALTER DATABASE " . idf_escape($_POST["name"]) . " COLLATE '" . $dbh->escape_string($_POST["collation"]) . "'", substr($SELF, 0, -1), lang('Database has been altered.')); + } +} +page_header(strlen($_GET["db"]) ? lang('Alter database') : lang('Create database'), $error, array(), $_GET["db"]); + +$collations = collations(); +$name = $_GET["db"]; +$collate = array(); +if ($_POST) { + $name = $_POST["name"]; + $collate = $_POST["collation"]; +} else { + if (!strlen($_GET["db"])) { + $result = $dbh->query("SHOW GRANTS"); + while ($row = $result->fetch_row()) { + if (preg_match('~ ON (`(([^\\\\`]+|``|\\\\.)*)%`\\.\\*)?~', $row[0], $match) && $match[1]) { + $name = stripcslashes(idf_unescape($match[2])); + break; + } + } + $result->free(); + } elseif (($result = $dbh->query("SHOW CREATE DATABASE " . idf_escape($_GET["db"])))) { + $create = $dbh->result($result, 1); + if (preg_match('~ COLLATE ([^ ]+)~', $create, $match)) { + $collate = $match[1]; + } elseif (preg_match('~ CHARACTER SET ([^ ]+)~', $create, $match)) { + $collate = $collations[$match[1]][0]; + } + $result->free(); + } +} +?> + +
+

+ + + + + /> +

+
diff --git a/adminer/db.inc.php b/adminer/db.inc.php new file mode 100644 index 00000000..818b6ff4 --- /dev/null +++ b/adminer/db.inc.php @@ -0,0 +1,113 @@ +query("SET foreign_key_checks = 0"); + if (isset($_POST["truncate"])) { + if ($_POST["tables"]) { + foreach ($_POST["tables"] as $table) { + if (!queries("TRUNCATE " . idf_escape($table))) { + $result = false; + break; + } + } + $message = lang('Tables have been truncated.'); + } + } elseif (isset($_POST["move"])) { + $rename = array(); + foreach ($tables_views as $table) { + $rename[] = idf_escape($table) . " TO " . idf_escape($_POST["target"]) . "." . idf_escape($table); + } + $result = queries("RENAME TABLE " . implode(", ", $rename)); + $message = lang('Tables have been moved.'); + } elseif ((!isset($_POST["drop"]) || !$_POST["views"] || queries("DROP VIEW " . implode(", ", array_map('idf_escape', $_POST["views"])))) + && (!$_POST["tables"] || ($result = queries((isset($_POST["optimize"]) ? "OPTIMIZE" : (isset($_POST["check"]) ? "CHECK" : (isset($_POST["repair"]) ? "REPAIR" : (isset($_POST["drop"]) ? "DROP" : "ANALYZE")))) . " TABLE " . implode(", ", array_map('idf_escape', $_POST["tables"]))))) + ) { + if (isset($_POST["drop"])) { + $message = lang('Tables have been dropped.'); + } else { + while ($row = $result->fetch_assoc()) { + $message .= htmlspecialchars("$row[Table]: $row[Msg_text]") . "
"; + } + } + } + query_redirect(queries(), substr($SELF, 0, -1), $message, $result, false, !$result); +} + +page_header(lang('Database') . ": " . htmlspecialchars($_GET["db"]), $error, false); +echo '

' . lang('Alter database') . "

\n"; +echo '

' . lang('Database schema') . "

\n"; + +echo "

" . lang('Tables and views') . "

\n"; +$result = $dbh->query("SHOW TABLE STATUS"); +if (!$result->num_rows) { + echo "

" . lang('No tables.') . "

\n"; +} else { + echo "
\n"; + echo "\n"; + echo '\n"; + while ($row = $result->fetch_assoc()) { + $name = $row["Name"]; + table_comment($row); + echo ''; + if (isset($row["Rows"])) { + echo '"; + foreach (array("Data_length" => "create", "Index_length" => "indexes", "Data_free" => "edit", "Auto_increment" => "create", "Rows" => "select") as $key => $link) { + $val = number_format($row[$key], 0, '.', lang(',')); + echo ''; + } + echo ""; + } else { + echo ''; + } + echo "\n"; + } + echo "
' . lang('Table') . '' . lang('Engine') . '' . lang('Collation') . '' . lang('Data Length') . '' . lang('Index Length') . '' . lang('Data Free') . '' . lang('Auto Increment') . '' . lang('Rows') . '' . lang('Comment') . "
' . htmlspecialchars($name) . "$row[Engine]$row[Collation]' . (strlen($row[$key]) ? '' . str_replace(" ", " ", ($key == "Rows" && $row["Engine"] == "InnoDB" && $val ? lang('~ %s', $val) : $val)) . '' : ' ') . '" . (strlen(trim($row["Comment"])) ? htmlspecialchars($row["Comment"]) : " ") . "' . htmlspecialchars($name) . '' . lang('View') . '
\n"; + echo "

\n"; + $dbs = get_databases(); + if (count($dbs) != 1) { + $db = (isset($_POST["target"]) ? $_POST["target"] : $_GET["db"]); + echo "

" . lang('Move to other database') . ($dbs ? ": " : ': ') . "

\n"; + } + echo "
\n"; +} +$result->free(); + +if ($dbh->server_info >= 5) { + echo '

' . lang('Create view') . "

\n"; + echo "

" . lang('Routines') . "

\n"; + $result = $dbh->query("SELECT * FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = '" . $dbh->escape_string($_GET["db"]) . "'"); + if ($result->num_rows) { + echo "\n"; + while ($row = $result->fetch_assoc()) { + echo ""; + echo ""; + echo ''; + echo '"; + echo "\n"; + } + echo "
" . htmlspecialchars($row["ROUTINE_TYPE"]) . "' . htmlspecialchars($row["ROUTINE_NAME"]) . '' . lang('Alter') . "
\n"; + } + $result->free(); + echo '

' . lang('Create procedure') . ' ' . lang('Create function') . "

\n"; +} + +if ($dbh->server_info >= 5.1 && ($result = $dbh->query("SHOW EVENTS"))) { + echo "

" . lang('Events') . "

\n"; + if ($result->num_rows) { + echo "\n"; + echo "\n"; + while ($row = $result->fetch_assoc()) { + echo ""; + echo '"; + echo ""; + echo ""; + echo "\n"; + } + echo "
" . lang('Name') . "" . lang('Schedule') . "" . lang('Start') . "" . lang('End') . "
' . htmlspecialchars($row["Name"]) . "" . ($row["Execute at"] ? lang('At given time') . "" . $row["Execute at"] : lang('Every') . " " . $row["Interval value"] . " " . $row["Interval field"] . "$row[Starts]") . "$row[Ends]
\n"; + } + $result->free(); + echo '

' . lang('Create event') . "

\n"; +} diff --git a/adminer/default.css b/adminer/default.css new file mode 100644 index 00000000..5ea95936 --- /dev/null +++ b/adminer/default.css @@ -0,0 +1,39 @@ +body { color: #000; background: #fff; line-height: 1.25em; font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0; font-size: 90%; } +a { color: blue; } +a:visited { color: navy; } +a:hover { color: red; } +h1 { font-size: 100%; margin: 0; padding: .8em 1em; border-bottom: 1px solid #999; font-weight: normal; color: #777; background: #eee; } +h1 a:link, h1 a:visited { font-size: 150%; color: #777; text-decoration: none; font-style: italic; margin-right: 1ex; } +h2 { font-size: 150%; margin: 0 0 20px -18px; padding: .8em 1em; border-bottom: 1px solid #000; color: #000; font-weight: normal; background: #ddf; } +h3 { font-weight: normal; font-size: 130%; margin: .8em 0; } +table { margin: 0 20px .8em 0; border: 0; border-top: 1px solid #999; border-left: 1px solid #999; font-size: 90%; } +td, th { margin-bottom: 1em; border: 0; border-right: 1px solid #999; border-bottom: 1px solid #999; padding: .2em .3em; } +th { background: #eee; } +fieldset { display: inline; vertical-align: top; padding: .5em .8em; margin: 0 .5em .5em 0; border: 1px solid #999; } +p { margin: 0 20px 1em 0; } +img { vertical-align: middle; border: 0; } +code { background: #eee; } +.js .hidden { display: none; } +.popup { position: absolute; } +.nowrap { white-space: nowrap; } +.wrap { white-space: normal; } +.error { color: red; background: #fee; padding: .5em .8em; } +.message { color: green; background: #efe; padding: .5em .8em; } +.char { color: #007F00; } +.date { color: #7F007F; } +.enum { color: #007F7F; } +.binary { color: red; } +.odd td { background: #F5F5F5; } +.time { color: Silver; font-size: 70%; float: right; margin-top: -3em; } +.function { text-align: right; } +tr:hover td { background: #ddf; } +thead tr:hover td { background: transparent; } +#menu { position: absolute; margin: 10px 0 0; padding: 0 0 30px 0; top: 2em; left: 0; width: 19em; overflow: auto; overflow-y: hidden; white-space: nowrap; } +#menu p { padding: .8em 1em; margin: 0; border-bottom: 1px solid #ccc; } +#menu form { margin: 0; } +#content { margin: 2em 0 0 21em; padding: 10px 20px 20px 0; } +#lang { position: absolute; top: 0; left: 0; line-height: 1.8em; padding: .3em 1em; } +#breadcrumb { white-space: nowrap; position: absolute; top: 0; left: 21em; background: #eee; height: 2em; line-height: 1.8em; padding: 0 1em; margin: 0 0 0 -18px; } +#schema { margin-left: 60px; position: relative; } +#schema .table { border: 1px solid Silver; padding: 0 2px; cursor: move; position: absolute; } +#schema .references { position: absolute; } diff --git a/adminer/down.gif b/adminer/down.gif new file mode 100644 index 00000000..630fc359 Binary files /dev/null and b/adminer/down.gif differ diff --git a/adminer/download.inc.php b/adminer/download.inc.php new file mode 100644 index 00000000..ff1f7862 --- /dev/null +++ b/adminer/download.inc.php @@ -0,0 +1,4 @@ +result($dbh->query("SELECT " . idf_escape($_GET["field"]) . " FROM " . idf_escape($_GET["download"]) . " WHERE " . implode(" AND ", where($_GET)) . " LIMIT 1")); diff --git a/adminer/dump.inc.php b/adminer/dump.inc.php new file mode 100644 index 00000000..fcf319ed --- /dev/null +++ b/adminer/dump.inc.php @@ -0,0 +1,188 @@ + 1)); + if ($_POST["format"] != "csv") { + $max_packet = 1048576; // default, minimum is 1024 + echo "SET NAMES utf8;\n"; + echo "SET foreign_key_checks = 0;\n"; + echo "SET time_zone = '" . $dbh->escape_string($dbh->result($dbh->query("SELECT @@time_zone"))) . "';\n"; + echo "\n"; + } + + $style = $_POST["db_style"]; + foreach ((strlen($_GET["db"]) ? array($_GET["db"]) : (array) $_POST["databases"]) as $db) { + if ($dbh->select_db($db)) { + if ($_POST["format"] != "csv" && ereg('CREATE', $style) && ($result = $dbh->query("SHOW CREATE DATABASE " . idf_escape($db)))) { + if ($style == "DROP+CREATE") { + echo "DROP DATABASE IF EXISTS " . idf_escape($db) . ";\n"; + } + $create = $dbh->result($result, 1); + echo ($style == "CREATE+ALTER" ? preg_replace('~^CREATE DATABASE ~', '\\0IF NOT EXISTS ', $create) : $create) . ";\n"; + $result->free(); + } + if ($style && $_POST["format"] != "csv") { + echo "USE " . idf_escape($db) . ";\n\n"; + $out = ""; + if ($dbh->server_info >= 5) { + foreach (array("FUNCTION", "PROCEDURE") as $routine) { + $result = $dbh->query("SHOW $routine STATUS WHERE Db = '" . $dbh->escape_string($db) . "'"); + while ($row = $result->fetch_assoc()) { + $out .= $dbh->result($dbh->query("SHOW CREATE $routine " . idf_escape($row["Name"])), 2) . ";;\n\n"; + } + $result->free(); + } + } + if ($dbh->server_info >= 5.1) { + $result = $dbh->query("SHOW EVENTS"); + while ($row = $result->fetch_assoc()) { + $out .= $dbh->result($dbh->query("SHOW CREATE EVENT " . idf_escape($row["Name"])), 3) . ";;\n\n"; + } + $result->free(); + } + echo ($out ? "DELIMITER ;;\n\n$out" . "DELIMITER ;\n\n" : ""); + } + + if ($_POST["table_style"] || $_POST["data_style"]) { + $views = array(); + $result = $dbh->query("SHOW TABLE STATUS"); + while ($row = $result->fetch_assoc()) { + $table = (!strlen($_GET["db"]) || in_array($row["Name"], (array) $_POST["tables"])); + $data = (!strlen($_GET["db"]) || in_array($row["Name"], (array) $_POST["data"])); + if ($table || $data) { + if (isset($row["Engine"])) { + if ($ext == "tar") { + ob_start(); + } + dump_table($row["Name"], ($table ? $_POST["table_style"] : "")); + if ($data) { + dump_data($row["Name"], $_POST["data_style"]); + } + if ($ext == "tar") { + echo tar_file((strlen($_GET["db"]) ? "" : "$db/") . "$row[Name].csv", ob_get_clean()); + } elseif ($_POST["format"] != "csv") { + echo "\n"; + } + } elseif ($_POST["format"] != "csv") { + $views[] = $row["Name"]; + } + } + } + $result->free(); + foreach ($views as $view) { + dump_table($view, $_POST["table_style"], true); + } + } + + if ($style == "CREATE+ALTER" && $_POST["format"] != "csv") { + $query = "SELECT TABLE_NAME, ENGINE, TABLE_COLLATION, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()"; +?> +DELIMITER ;; +CREATE PROCEDURE adminer_drop () BEGIN + DECLARE _table_name, _engine, _table_collation varchar(64); + DECLARE _table_comment varchar(64); + DECLARE done bool DEFAULT 0; + DECLARE tables CURSOR FOR ; + 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_namequery($query); +while ($row = $result->fetch_assoc()) { + $comment = $dbh->escape_string($row["ENGINE"] == "InnoDB" ? preg_replace('~(?:(.+); )?InnoDB free: .*~', '\\1', $row["TABLE_COMMENT"]) : $row["TABLE_COMMENT"]); + echo " + WHEN '" . $dbh->escape_string($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") . ";"; +} +$result->free(); +?> + + ELSE + SET @alter_table = CONCAT('DROP TABLE `', REPLACE(_table_name, '`', '``'), '`'); + PREPARE alter_command FROM @alter_table; + EXECUTE alter_command; -- returns "can't return a result set in the given context" with MySQL extension + DROP PREPARE alter_command; + END CASE; + END IF; + UNTIL done END REPEAT; + CLOSE tables; +END;; +DELIMITER ; +CALL adminer_drop; +DROP PROCEDURE adminer_drop; + $_GET["export"]) : array()), $_GET["db"]); +?> + +
+ +server_info >= 5) { + $db_style[] = 'CREATE+ALTER'; + $table_style[] = 'CREATE+ALTER'; +} +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +?> +
" . lang('Output') . "$dump_output
" . lang('Format') . "$dump_format
" . lang('Database') . "
" . lang('Tables') . "
" . lang('Data') . "
+

+ +\n"; + echo "\n"; + foreach (get_databases() as $db) { + if ($db != "information_schema" || $dbh->server_info < 5) { + echo '\n"; + } + } + echo "\n"; +} + +if (strlen($_GET["db"])) { + $checked = (strlen($_GET["dump"]) ? "" : " checked='checked'"); + echo "\n"; + echo ""; + echo ""; + echo ""; + echo "\n"; + $views = ""; + $result = $dbh->query("SHOW TABLE STATUS"); + while ($row = $result->fetch_assoc()) { + $checked = (strlen($_GET["dump"]) && $row["Name"] != $_GET["dump"] ? '' : " checked='checked'"); + $print = '"; + if (!$row["Engine"]) { + $views .= "$print\n"; + } else { + echo "$print\n"; + } + } + echo "$views
\n"; +} +?> +
diff --git a/adminer/edit.inc.php b/adminer/edit.inc.php new file mode 100644 index 00000000..43040bf9 --- /dev/null +++ b/adminer/edit.inc.php @@ -0,0 +1,105 @@ + $field) { + if (isset($_GET["default"]) ? $field["auto_increment"] || preg_match('~text|blob~', $field["type"]) : !isset($field["privileges"][$update ? "update" : "insert"])) { + unset($fields[$name]); + } +} +if ($_POST && !$error && !isset($_GET["select"])) { + $location = ($_POST["insert"] ? $_SERVER["REQUEST_URI"] : $SELF . (isset($_GET["default"]) ? "table=" : "select=") . urlencode($_GET["edit"])); + if (isset($_POST["delete"])) { + query_redirect("DELETE FROM " . idf_escape($_GET["edit"]) . " WHERE " . implode(" AND ", $where) . " LIMIT 1", $location, lang('Item has been deleted.')); + } else { + $set = array(); + foreach ($fields as $name => $field) { + $val = process_input($name, $field); + if (!isset($_GET["default"])) { + if ($val !== false || !$update) { + $set[] = "\n" . idf_escape($name) . " = " . ($val !== false ? $val : "''"); + } + } elseif ($val !== false) { + if ($field["type"] == "timestamp" && $val != "NULL") { //! doesn't allow DEFAULT NULL and no ON UPDATE + $set[] = "\nMODIFY " . idf_escape($name) . " timestamp" . ($field["null"] ? " NULL" : "") . " DEFAULT $val" . ($_POST["on_update"][bracket_escape($name)] ? " ON UPDATE CURRENT_TIMESTAMP" : ""); + } else { + $set[] = "\nALTER " . idf_escape($name) . ($val == "NULL" ? " DROP DEFAULT" : " SET DEFAULT $val"); + } + } + } + if (!$set) { + redirect($location); + } + if (isset($_GET["default"])) { + query_redirect("ALTER TABLE " . idf_escape($_GET["edit"]) . implode(",", $set), $location, lang('Default values has been set.')); + } elseif ($update) { + query_redirect("UPDATE " . idf_escape($_GET["edit"]) . " SET" . implode(",", $set) . "\nWHERE " . implode(" AND ", $where) . " LIMIT 1", $location, lang('Item has been updated.')); + } else { + query_redirect("INSERT INTO " . idf_escape($_GET["edit"]) . " SET" . implode(",", $set), $location, lang('Item has been inserted.')); + } + } +} +page_header((isset($_GET["default"]) ? lang('Default values') : ($_GET["where"] || (isset($_GET["select"]) && !$_POST["clone"]) ? lang('Edit') : lang('Insert'))), $error, array((isset($_GET["default"]) ? "table" : "select") => $_GET["edit"]), $_GET["edit"]); + +unset($row); +if ($_POST["save"]) { + $row = (array) $_POST["fields"]; +} elseif ($where) { + $select = array(); + foreach ($fields as $name => $field) { + if (isset($field["privileges"]["select"])) { + $select[] = ($_POST["clone"] && $field["auto_increment"] ? "'' AS " : ($field["type"] == "enum" || $field["type"] == "set" ? "1*" . idf_escape($name) . " AS " : "")) . idf_escape($name); + } + } + $row = array(); + if ($select) { + $result = $dbh->query("SELECT " . implode(", ", $select) . " FROM " . idf_escape($_GET["edit"]) . " WHERE " . implode(" AND ", $where) . " LIMIT 1"); + $row = $result->fetch_assoc(); + $result->free(); + } +} +?> + +
+\n"; + foreach ($fields as $name => $field) { + echo "" . htmlspecialchars($name) . ""; + $value = (!isset($row) ? ($_POST["clone"] && $field["auto_increment"] ? "" : ($where ? $field["default"] : null)) + : (strlen($row[$name]) && ($field["type"] == "enum" || $field["type"] == "set") ? intval($row[$name]) : $row[$name]) + ); + input($name, $field, $value); + if (isset($_GET["default"]) && $field["type"] == "timestamp") { + if (!isset($create) && !$_POST) { + //! disable sql_mode NO_FIELD_OPTIONS + $create = $dbh->result($dbh->query("SHOW CREATE TABLE " . idf_escape($_GET["edit"])), 1); + } + $checked = ($_POST ? $_POST["on_update"][bracket_escape($name)] : preg_match("~\n\\s*" . preg_quote(idf_escape($name), '~') . " timestamp.* on update CURRENT_TIMESTAMP~i", $create)); + echo ''; + } + echo "\n"; + } + echo "\n"; +} +?> +

+ + + (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"])); +} +if ($fields) { + echo ''; + if (!isset($_GET["default"]) && !isset($_GET["select"])) { + echo ''; + } +} +if ($update) { + echo ' '; +} +?> +

+
diff --git a/adminer/event.inc.php b/adminer/event.inc.php new file mode 100644 index 00000000..4eb53b42 --- /dev/null +++ b/adminer/event.inc.php @@ -0,0 +1,54 @@ + "ENABLE", "DISABLED" => "DISABLE", "SLAVESIDE_DISABLED" => "DISABLE ON SLAVE"); + +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)) { + $schedule = "\nON SCHEDULE " . ($_POST["INTERVAL_VALUE"] + ? "EVERY '" . $dbh->escape_string($_POST["INTERVAL_VALUE"]) . "' $_POST[INTERVAL_FIELD]" + . ($_POST["STARTS"] ? " STARTS '" . $dbh->escape_string($_POST["STARTS"]) . "'" : "") + . ($_POST["ENDS"] ? " ENDS '" . $dbh->escape_string($_POST["ENDS"]) . "'" : "") //! ALTER EVENT doesn't drop ENDS - MySQL bug #39173 + : "AT '" . $dbh->escape_string($_POST["STARTS"]) . "'" + ) . " ON COMPLETION" . ($_POST["ON_COMPLETION"] ? "" : " NOT") . " PRESERVE" + ; + query_redirect((strlen($_GET["event"]) + ? "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->escape_string($_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.'))); + } +} +page_header((strlen($_GET["event"]) ? lang('Alter event') . ": " . htmlspecialchars($_GET["event"]) : lang('Create event')), $error); + +$row = array(); +if ($_POST) { + $row = $_POST; +} elseif (strlen($_GET["event"])) { + $result = $dbh->query("SELECT * FROM information_schema.EVENTS WHERE EVENT_SCHEMA = '" . $dbh->escape_string($_GET["db"]) . "' AND EVENT_NAME = '" . $dbh->escape_string($_GET["event"]) . "'"); + $row = $result->fetch_assoc(); + $row["STATUS"] = $statuses[$row["STATUS"]]; + $result->free(); +} +?> + +
+ + + + + + + + +
" maxlength="64" />
" />
" />
" size="6" />
" maxlength="64" />
 
+

+

+ + + /> +

+
diff --git a/adminer/favicon.ico b/adminer/favicon.ico new file mode 100644 index 00000000..ef958a09 Binary files /dev/null and b/adminer/favicon.ico differ diff --git a/adminer/foreign.inc.php b/adminer/foreign.inc.php new file mode 100644 index 00000000..7d15c64e --- /dev/null +++ b/adminer/foreign.inc.php @@ -0,0 +1,81 @@ + $val) { + $target[$key] = $_POST["target"][$key]; + } + query_redirect("ALTER TABLE " . idf_escape($_GET["foreign"]) + . (strlen($_GET["name"]) ? "\nDROP FOREIGN KEY " . idf_escape($_GET["name"]) . "," : "") + . "\nADD FOREIGN KEY (" . implode(", ", array_map('idf_escape', $source)) . ") REFERENCES " . idf_escape($_POST["table"]) . " (" . implode(", ", array_map('idf_escape', $target)) . ")" + . (in_array($_POST["on_delete"], $on_actions) ? " ON DELETE $_POST[on_delete]" : "") + . (in_array($_POST["on_update"], $on_actions) ? " ON UPDATE $_POST[on_update]" : "") + , $SELF . "table=" . urlencode($_GET["foreign"]), (strlen($_GET["name"]) ? lang('Foreign key has been altered.') : lang('Foreign key has been created.'))); + } +} +page_header(lang('Foreign key'), $error, array("table" => $_GET["foreign"]), $_GET["foreign"]); + +$tables = array(); +$result = $dbh->query("SHOW TABLE STATUS"); +while ($row = $result->fetch_assoc()) { + if ($row["Engine"] == "InnoDB") { + $tables[] = $row["Name"]; + } +} +$result->free(); + +if ($_POST) { + $row = $_POST; + ksort($row["source"]); + if ($_POST["add"]) { + $row["source"][] = ""; + } elseif ($_POST["change"] || $_POST["change-js"]) { + $row["target"] = array(); + } +} elseif (strlen($_GET["name"])) { + $foreign_keys = foreign_keys($_GET["foreign"]); + $row = $foreign_keys[$_GET["name"]]; + $row["source"][] = ""; +} else { + $row = array("table" => $_GET["foreign"], "source" => array("")); +} + +$source = get_vals("SHOW COLUMNS FROM " . idf_escape($_GET["foreign"])); //! no text and blob +$target = ($_GET["foreign"] === $row["table"] ? $source : get_vals("SHOW COLUMNS FROM " . idf_escape($row["table"]))); +?> + +
+

+: + + +

+ + + + $val) { + echo ""; + echo ""; + echo ""; + echo "\n"; + $j++; +} +?> +
+

+: +: +

+

+ + + /> +

+ +
diff --git a/adminer/functions.js b/adminer/functions.js new file mode 100644 index 00000000..825c938b --- /dev/null +++ b/adminer/functions.js @@ -0,0 +1,268 @@ +document.body.className = 'js'; + +function toggle(id) { + var el = document.getElementById(id); + el.className = (el.className == 'hidden' ? '' : 'hidden'); + return true; +} + +function popup(el) { + el.getElementsByTagName('span')[0].className = 'popup'; +} + +function popdown(el) { + el.getElementsByTagName('span')[0].className = 'hidden'; +} + +function verify_version(version) { + document.cookie = 'adminer_version=0'; + var script = document.createElement('script'); + script.src = 'http://www.adminer.org/version.php?version=' + version; + document.body.appendChild(script); +} + +function load_jush() { + var script = document.createElement('script'); + script.src = '../externals/jush/jush.js'; + script.onload = function () { + jush.style('../externals/jush/jush.css'); + jush.highlight_tag('pre'); + jush.highlight_tag('code'); + } + script.onreadystatechange = function () { + if (script.readyState == 'loaded' || script.readyState == 'complete') { + script.onload(); + } + } + document.body.appendChild(script); +} + +function form_check(el, name) { + var elems = el.form.elements; + for (var i=0; i < elems.length; i++) { + if (name.test(elems[i].name)) { + elems[i].checked = el.checked; + } + } +} + +function form_uncheck(id) { + document.getElementById(id).checked = false; +} + + + +function where_change(op) { + for (var i=0; i < op.form.elements.length; i++) { + var el = op.form.elements[i]; + if (el.name == op.name.substr(0, op.name.length - 4) + '[val]') { + el.className = (/NULL$/.test(op.options[op.selectedIndex].text) ? 'hidden' : ''); + } + } +} + +function select_add_row(field) { + var row = field.parentNode.cloneNode(true); + var selects = row.getElementsByTagName('select'); + for (var i=0; i < selects.length; i++) { + selects[i].name = selects[i].name.replace(/[a-z]\[[0-9]+/, '$&1'); + selects[i].selectedIndex = 0; + } + var inputs = row.getElementsByTagName('input'); + if (inputs.length) { + inputs[0].name = inputs[0].name.replace(/[a-z]\[[0-9]+/, '$&1'); + inputs[0].value = ''; + inputs[0].className = ''; + } + field.parentNode.parentNode.appendChild(row); + field.onchange = function () { }; +} + + + +var added = '.', row_count; + +function editing_add_row(button, allowed) { + if (allowed && row_count >= allowed) { + return false; + } + var match = /([0-9]+)(\.[0-9]+)?/.exec(button.name); + var x = match[0] + (match[2] ? added.substr(match[2].length) : added) + '1'; + var row = button.parentNode.parentNode; + var row2 = row.cloneNode(true); + var tags = row.getElementsByTagName('select'); + var tags2 = row2.getElementsByTagName('select'); + for (var i=0; i < tags.length; i++) { + tags[i].name = tags[i].name.replace(/([0-9.]+)/, x); + tags2[i].selectedIndex = tags[i].selectedIndex; + } + tags = row.getElementsByTagName('input'); + tags2 = row2.getElementsByTagName('input'); + for (var i=0; i < tags.length; i++) { + if (tags[i].name == 'auto_increment_col') { + tags[i].value = x; + tags2[i].checked = tags[i].checked; + tags[i].checked = false; + } + tags[i].name = tags[i].name.replace(/([0-9.]+)/, x); + if (/\[(orig|field|comment)/.test(tags[i].name)) { + tags[i].value = ''; + } + } + row.parentNode.insertBefore(row2, row); + tags[0].focus(); + added += '0'; + row_count++; + return true; +} + +function editing_remove_row(button) { + var field = button.form[button.name.replace(/drop_col(.+)/, 'fields$1[field]')]; + field.parentNode.removeChild(field); + button.parentNode.parentNode.style.display = 'none'; + return true; +} + +function editing_type_change(type) { + var name = type.name.substr(0, type.name.length - 6); + for (var i=0; i < type.form.elements.length; i++) { + var el = type.form.elements[i]; + if (el.name == name + '[collation]') { + el.className = (/char|text|enum|set/.test(type.options[type.selectedIndex].text) ? '' : 'hidden'); + } + if (el.name == name + '[unsigned]') { + el.className = (/int|float|double|decimal/.test(type.options[type.selectedIndex].text) ? '' : 'hidden'); + } + } +} + +function column_comments_click(checked) { + var trs = document.getElementById('edit-fields').getElementsByTagName('tr'); + for (var i=0; i < trs.length; i++) { + trs[i].getElementsByTagName('td')[5].className = (checked ? '' : 'hidden'); + } +} + +function partition_by_change(el) { + var partition_table = /RANGE|LIST/.test(el.options[el.selectedIndex].text); + el.form['partitions'].className = (partition_table || !el.selectedIndex ? 'hidden' : ''); + document.getElementById('partition-table').className = (partition_table ? '' : 'hidden'); +} + +function partition_name_change(el) { + var row = el.parentNode.parentNode.cloneNode(true); + row.firstChild.firstChild.value = ''; + el.parentNode.parentNode.parentNode.appendChild(row); + el.onchange = function () {}; +} + + + +function foreign_add_row(field) { + var row = field.parentNode.parentNode.cloneNode(true); + var selects = row.getElementsByTagName('select'); + for (var i=0; i < selects.length; i++) { + selects[i].name = selects[i].name.replace(/\]/, '1$&'); + selects[i].selectedIndex = 0; + } + field.parentNode.parentNode.parentNode.appendChild(row); + field.onchange = function () { }; +} + + + +function indexes_add_row(field) { + var row = field.parentNode.parentNode.cloneNode(true); + var spans = row.getElementsByTagName('span'); + row.getElementsByTagName('td')[1].innerHTML = '' + spans[spans.length - 1].innerHTML + ''; + var selects = row.getElementsByTagName('select'); + for (var i=0; i < selects.length; i++) { + selects[i].name = selects[i].name.replace(/indexes\[[0-9]+/, '$&1'); + selects[i].selectedIndex = 0; + } + var input = row.getElementsByTagName('input')[0]; + input.name = input.name.replace(/indexes\[[0-9]+/, '$&1'); + input.value = ''; + field.parentNode.parentNode.parentNode.appendChild(row); + field.onchange = function () { }; +} + +function indexes_add_column(field) { + var column = field.parentNode.cloneNode(true); + var select = column.getElementsByTagName('select')[0]; + select.name = select.name.replace(/\]\[[0-9]+/, '$&1'); + select.selectedIndex = 0; + var input = column.getElementsByTagName('input')[0]; + input.name = input.name.replace(/\]\[[0-9]+/, '$&1'); + input.value = ''; + field.parentNode.parentNode.appendChild(column); + field.onchange = function () { }; +} + + + +var that, x, y, em, table_pos; + +function schema_mousedown(el, event) { + that = el; + x = event.clientX - el.offsetLeft; + y = event.clientY - el.offsetTop; +} + +function schema_mousemove(ev) { + if (that !== undefined) { + ev = ev || event; + var left = (ev.clientX - x) / em; + var top = (ev.clientY - y) / em; + var divs = that.getElementsByTagName('div'); + var line_set = { }; + for (var i=0; i < divs.length; i++) { + if (divs[i].className == 'references') { + var div2 = document.getElementById((divs[i].id.substr(0, 4) == 'refs' ? 'refd' : 'refs') + divs[i].id.substr(4)); + var ref = (table_pos[divs[i].title] ? table_pos[divs[i].title] : [ div2.parentNode.offsetTop / em, 0 ]); + var left1 = -1; + var is_top = true; + var id = divs[i].id.replace(/^ref.(.+)-.+/, '$1'); + if (divs[i].parentNode != div2.parentNode) { + left1 = Math.min(0, ref[1] - left) - 1; + divs[i].style.left = left1 + 'em'; + divs[i].getElementsByTagName('div')[0].style.width = -left1 + 'em'; + var left2 = Math.min(0, left - ref[1]) - 1; + div2.style.left = left2 + 'em'; + div2.getElementsByTagName('div')[0].style.width = -left2 + 'em'; + is_top = (div2.offsetTop + ref[0] * em > divs[i].offsetTop + top * em); + } + if (!line_set[id]) { + var line = document.getElementById(divs[i].id.replace(/^....(.+)-[0-9]+$/, 'refl$1')); + var shift = ev.clientY - y - that.offsetTop; + line.style.left = (left + left1) + 'em'; + if (is_top) { + line.style.top = (line.offsetTop + shift) / em + 'em'; + } + if (divs[i].parentNode != div2.parentNode) { + line = line.getElementsByTagName('div')[0]; + line.style.height = (line.offsetHeight + (is_top ? -1 : 1) * shift) / em + 'em'; + } + line_set[id] = true; + } + } + } + that.style.left = left + 'em'; + that.style.top = top + 'em'; + } +} + +function schema_mouseup(ev) { + if (that !== undefined) { + ev = ev || event; + table_pos[that.firstChild.firstChild.firstChild.data] = [ (ev.clientY - y) / em, (ev.clientX - x) / em ]; + that = undefined; + var date = new Date(); + date.setMonth(date.getMonth() + 1); + var s = ''; + for (var key in table_pos) { + s += '_' + key + ':' + Math.round(table_pos[key][0] * 10000) / 10000 + 'x' + Math.round(table_pos[key][1] * 10000) / 10000; + } + document.cookie = 'schema=' + encodeURIComponent(s.substr(1)) + '; expires=' + date + '; path=' + location.pathname + location.search; + } +} diff --git a/adminer/include/auth.inc.php b/adminer/include/auth.inc.php new file mode 100644 index 00000000..85f70d5b --- /dev/null +++ b/adminer/include/auth.inc.php @@ -0,0 +1,76 @@ +getMessage() : ($dbh ? $dbh : lang('Invalid credentials.'))) : (isset($_POST["server"]) ? lang('Sessions must be enabled.') : ($_POST ? lang('Session expired, please login again.') : ""))), null); + ?> +
+ + + + +
" />
+

+ $val) { + echo ''; + } + ?> + +

+
+' . lang('Create new database') . "

\n"; + echo '

' . lang('Privileges') . "

\n"; + echo '

' . lang('Process list') . "

\n"; + echo "

" . lang('MySQL version: %s through PHP extension %s', "server_info < 4.1 ? " class='binary'" : "") . ">$dbh->server_info", "$dbh->extension") . "

\n"; + echo "

" . lang('Logged as: %s', "" . htmlspecialchars($dbh->result($dbh->query("SELECT USER()"))) . "") . "

\n"; + } + page_footer("db"); +} + +$dbh->query("SET SQL_QUOTE_SHOW_CREATE=1"); +if (!(strlen($_GET["db"]) ? $dbh->select_db($_GET["db"]) : isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]))) { + if (strlen($_GET["db"])) { + unset($_SESSION["databases"][$_GET["server"]]); + } + connect_error(); + exit; +} +$dbh->query("SET CHARACTER SET utf8"); diff --git a/adminer/include/design.inc.php b/adminer/include/design.inc.php new file mode 100644 index 00000000..f3046352 --- /dev/null +++ b/adminer/include/design.inc.php @@ -0,0 +1,113 @@ + + + + + + + +<?php echo $title . (strlen($title2) ? ": " . htmlspecialchars($title2) : "") . " - " . lang('Adminer'); ?> + + + + + + + +"> + + +
+' . (isset($_GET["server"]) ? htmlspecialchars($_GET["server"]) : lang('Server')) . ' » '; + if (is_array($breadcrumb)) { + if (strlen($_GET["db"])) { + echo '' . htmlspecialchars($_GET["db"]) . ' » '; + } + foreach ($breadcrumb as $key => $val) { + if (strlen($val)) { + echo '' . htmlspecialchars($val) . ' » '; + } + } + } + echo "$title

\n"; + } + echo "

$title" . (strlen($title2) ? ": " . htmlspecialchars($title2) : "") . "

\n"; + if ($_SESSION["messages"]) { + echo "

" . implode("

\n

", $_SESSION["messages"]) . "

\n"; + $_SESSION["messages"] = array(); + } + $databases = &$_SESSION["databases"][$_GET["server"]]; + if (strlen($_GET["db"]) && $databases && !in_array($_GET["db"], $databases, true)) { + $databases = null; + } + if (isset($databases) && !isset($_GET["sql"]) && !isset($_SESSION["coverage"])) { + session_write_close(); + } + if ($error) { + echo "

$error

\n"; + } +} + +function page_footer($missing = false) { + global $SELF, $dbh, $VERSION; + ?> +
+ + + + + + +") { //! pass empty separator if there are no functions in the whole table + global $types; + $name = htmlspecialchars(bracket_escape($name)); + echo ""; + if ($field["type"] == "enum") { + echo ($separator ? " $separator" : "") . (isset($_GET["select"]) ? ' ' : ""); + if ($field["null"] || isset($_GET["default"])) { + echo ' '; + } + if (!isset($_GET["default"])) { + echo ''; + } + preg_match_all("~'((?:[^']+|'')*)'~", $field["length"], $matches); + foreach ($matches[1] as $i => $val) { + $val = stripcslashes(str_replace("''", "'", $val)); + $checked = (is_int($value) ? $value == $i+1 : $value === $val); + echo ' '; + } + } else { + $first = ($field["null"] || isset($_GET["default"])) + isset($_GET["select"]); + $onchange = ($first ? ' onchange="var f = this.form[\'function[' . addcslashes($name, "\r\n'\\") . ']\']; if (' . $first . ' > f.selectedIndex) f.selectedIndex = ' . $first . ';"' : ''); + $options = array(""); + if (!isset($_GET["default"])) { + if (preg_match('~char|date|time~', $field["type"])) { + $options = (preg_match('~char~', $field["type"]) ? array("", "md5", "sha1", "password", "uuid") : array("", "now")); + } + if (!isset($_GET["call"]) && (isset($_GET["select"]) || where($_GET))) { + if (preg_match('~int|float|double|decimal~', $field["type"])) { + $options = array("", "+", "-"); + } + if (preg_match('~date~', $field["type"])) { + $options[] = "+ interval"; + $options[] = "- interval"; + } + if (preg_match('~time~', $field["type"])) { + $options[] = "addtime"; + $options[] = "subtime"; + } + } + } + if ($field["null"] || isset($_GET["default"])) { + array_unshift($options, "NULL"); + } + echo (count($options) > 1 || isset($_GET["select"]) ? '' : ($separator ? " " : "")) . $separator; + if ($field["type"] == "set") { //! 64 bits + preg_match_all("~'((?:[^']+|'')*)'~", $field["length"], $matches); + foreach ($matches[1] as $i => $val) { + $val = stripcslashes(str_replace("''", "'", $val)); + $checked = (is_int($value) ? ($value >> $i) & 1 : in_array($val, explode(",", $value), true)); + echo ' '; + } + } elseif (strpos($field["type"], "text") !== false) { + echo ''; + } elseif (preg_match('~binary|blob~', $field["type"])) { + echo (ini_get("file_uploads") ? '' : lang('File uploads are disabled.') . ' '); + } else { + $maxlength = (!ereg('int', $field["type"]) && preg_match('~^([0-9]+)(,([0-9]+))?$~', $field["length"], $match) ? ($match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0)) : ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0)); + echo ''; + } + } +} + +function process_input($name, $field) { + global $dbh; + $idf = bracket_escape($name); + $function = $_POST["function"][$idf]; + $value = $_POST["fields"][$idf]; + if ($field["type"] == "enum" ? $value == -1 : $function == "orig") { + return false; + } elseif ($field["type"] == "enum" || $field["auto_increment"] ? !strlen($value) : $function == "NULL") { + return "NULL"; + } elseif ($field["type"] == "enum") { + return (isset($_GET["default"]) ? "'" . $dbh->escape_string($value) . "'" : intval($value)); + } elseif ($field["type"] == "set") { + return (isset($_GET["default"]) ? "'" . implode(",", array_map(array($dbh, 'escape_string'), (array) $value)) . "'" : array_sum((array) $value)); + } elseif (preg_match('~binary|blob~', $field["type"])) { + $file = get_file($idf); + if (!is_string($file)) { + return false; //! report errors + } + return "_binary'" . (is_string($file) ? $dbh->escape_string($file) : "") . "'"; + } elseif ($field["type"] == "timestamp" && $value == "CURRENT_TIMESTAMP") { + return $value; + } elseif (preg_match('~^(now|uuid)$~', $function)) { + return "$function()"; + } elseif (preg_match('~^[+-]$~', $function)) { + return idf_escape($name) . " $function '" . $dbh->escape_string($value) . "'"; + } elseif (preg_match('~^[+-] interval$~', $function)) { + return idf_escape($name) . " $function " . (preg_match("~^([0-9]+|'[0-9.: -]') [A-Z_]+$~i", $value) ? $value : "'" . $dbh->escape_string($value) . "'") . ""; + } elseif (preg_match('~^(addtime|subtime)$~', $function)) { + return "$function(" . idf_escape($name) . ", '" . $dbh->escape_string($value) . "')"; + } elseif (preg_match('~^(md5|sha1|password)$~', $function)) { + return "$function('" . $dbh->escape_string($value) . "')"; + } else { + return "'" . $dbh->escape_string($value) . "'"; + } +} + +function edit_type($key, $field, $collations) { + global $types, $unsigned, $inout; + ?> + +" size="3" /> +' . optionlist($collations, $field["collation"]) . '' . ($unsigned ? " ' : ''); ?> +escape_string($field["collation"]) . "'" : "") + ; +} + +function edit_fields($fields, $collations, $type = "TABLE", $allowed = 0) { + global $inout; + $column_comments = false; + foreach ($fields as $field) { + if (strlen($field["comment"])) { + $column_comments = true; + } + } + ?> + + + + + + + + + +