Comments
git-svn-id: https://adminer.svn.sourceforge.net/svnroot/adminer/trunk@729 7c3ca157-0c34-0410-bff1-cbf682f78f5c
This commit is contained in:
parent
5d311ef2d9
commit
64ba92421b
|
@ -10,6 +10,7 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
|
|||
query_redirect("DROP TABLE " . idf_escape($_GET["create"]), substr($SELF, 0, -1), lang('Table has been dropped.'));
|
||||
} else {
|
||||
$auto_increment_index = " PRIMARY KEY";
|
||||
// don't overwrite primary key by auto_increment
|
||||
if (strlen($_GET["create"]) && strlen($_POST["fields"][$_POST["auto_increment_col"]]["orig"])) {
|
||||
foreach (indexes($_GET["create"]) as $index) {
|
||||
foreach ($index["columns"] as $column) {
|
||||
|
|
|
@ -24,7 +24,7 @@ if ($_POST) {
|
|||
<p><textarea name="select" rows="10" cols="80" style="width: 98%;"><?php echo htmlspecialchars($row["select"]); ?></textarea></p>
|
||||
<p>
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>" />
|
||||
<?php if ($dropped) { ?><input type="hidden" name="dropped" value="1" /><?php } ?>
|
||||
<?php if ($dropped) { // old view was dropped but new wasn't created ?><input type="hidden" name="dropped" value="1" /><?php } ?>
|
||||
<?php echo lang('Name'); ?>: <input name="name" value="<?php echo htmlspecialchars($row["name"]); ?>" maxlength="64" />
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>" />
|
||||
<?php if (strlen($_GET["createv"])) { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo $confirm; ?> /><?php } ?>
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
<?php
|
||||
if ($_POST && !$error && !$_POST["add_x"]) {
|
||||
if ($_POST && !$error && !isset($_POST["add_x"])) { // add is an image and PHP changes add.x to add_x
|
||||
if ($_POST["drop"]) {
|
||||
unset($_SESSION["databases"][$_GET["server"]]);
|
||||
query_redirect("DROP DATABASE " . idf_escape($_GET["db"]), substr(preg_replace('~db=[^&]*&~', '', $SELF), 0, -1), lang('Database has been dropped.'));
|
||||
} elseif ($_GET["db"] !== $_POST["name"]) {
|
||||
unset($_SESSION["databases"][$_GET["server"]]);
|
||||
// create or rename database
|
||||
unset($_SESSION["databases"][$_GET["server"]]); // clear cache
|
||||
$dbs = explode("\n", str_replace("\r", "", $_POST["name"]));
|
||||
$failed = false;
|
||||
foreach ($dbs as $db) {
|
||||
if (count($dbs) == 1 || strlen($db)) {
|
||||
if (count($dbs) == 1 || strlen($db)) { // ignore empty lines but always try to create single database
|
||||
if (!queries("CREATE DATABASE " . idf_escape($db) . ($_POST["collation"] ? " COLLATE '" . $dbh->escape_string($_POST["collation"]) . "'" : ""))) {
|
||||
$failed = true;
|
||||
}
|
||||
|
@ -29,6 +30,7 @@ if ($_POST && !$error && !$_POST["add_x"]) {
|
|||
query_redirect(queries(), preg_replace('~db=[^&]*&~', '', $SELF) . "db=" . urlencode($_POST["name"]), lang('Database has been renamed.'), !$row, false, $row);
|
||||
}
|
||||
} else {
|
||||
// alter database
|
||||
if (!$_POST["collation"]) {
|
||||
redirect(substr($SELF, 0, -1));
|
||||
}
|
||||
|
@ -43,25 +45,25 @@ $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;
|
||||
}
|
||||
} elseif (!strlen($_GET["db"])) {
|
||||
// propose database name with limited privileges
|
||||
$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();
|
||||
}
|
||||
$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)) {
|
||||
// default collation
|
||||
$collate = $collations[$match[1]][0];
|
||||
}
|
||||
$result->free();
|
||||
}
|
||||
?>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ $tables_views = array_merge((array) $_POST["tables"], (array) $_POST["views"]);
|
|||
if ($tables_views && !$error) {
|
||||
$result = true;
|
||||
$message = "";
|
||||
$dbh->query("SET foreign_key_checks = 0");
|
||||
$dbh->query("SET foreign_key_checks = 0"); // allows to truncate or drop several tables at once
|
||||
if (isset($_POST["truncate"])) {
|
||||
if ($_POST["tables"]) {
|
||||
foreach ($_POST["tables"] as $table) {
|
||||
|
|
|
@ -104,6 +104,7 @@ if ($_POST) {
|
|||
}
|
||||
|
||||
if ($style == "CREATE+ALTER" && $_POST["format"] != "csv") {
|
||||
// drop old tables
|
||||
$query = "SELECT TABLE_NAME, ENGINE, TABLE_COLLATION, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()";
|
||||
?>
|
||||
DELIMITER ;;
|
||||
|
|
|
@ -8,7 +8,7 @@ foreach ($fields as $name => $field) {
|
|||
}
|
||||
}
|
||||
if ($_POST && !$error && !isset($_GET["select"])) {
|
||||
$location = ($_POST["insert"] ? $_SERVER["REQUEST_URI"] : $SELF . (isset($_GET["default"]) ? "table=" : "select=") . urlencode($_GET["edit"]));
|
||||
$location = ($_POST["insert"] ? $_SERVER["REQUEST_URI"] : $SELF . (isset($_GET["default"]) ? "table=" : "select=") . urlencode($_GET["edit"])); // "insert" to continue edit or insert
|
||||
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 {
|
||||
|
|
|
@ -4,7 +4,7 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["change"] && !$_POST["change-
|
|||
query_redirect("ALTER TABLE " . idf_escape($_GET["foreign"]) . "\nDROP FOREIGN KEY " . idf_escape($_GET["name"]), $SELF . "table=" . urlencode($_GET["foreign"]), lang('Foreign key has been dropped.'));
|
||||
} else {
|
||||
$source = array_filter($_POST["source"], 'strlen');
|
||||
ksort($source);
|
||||
ksort($source); // enforce input order
|
||||
$target = array();
|
||||
foreach ($source as $key => $val) {
|
||||
$target[$key] = $_POST["target"][$key];
|
||||
|
|
|
@ -6,10 +6,10 @@ if (ini_get("session.use_trans_sid") && isset($_POST[$session_name])) {
|
|||
}
|
||||
if (isset($_POST["server"])) {
|
||||
if (isset($_COOKIE[$session_name]) || isset($_POST[$session_name])) {
|
||||
session_regenerate_id();
|
||||
session_regenerate_id(); // defense against session fixation
|
||||
$_SESSION["usernames"][$_POST["server"]] = $_POST["username"];
|
||||
$_SESSION["passwords"][$_POST["server"]] = $_POST["password"];
|
||||
$_SESSION["tokens"][$_POST["server"]] = rand(1, 1e6);
|
||||
$_SESSION["tokens"][$_POST["server"]] = rand(1, 1e6); // defense against cross-site request forgery
|
||||
if (count($_POST) == count($ignore)) {
|
||||
$location = ((string) $_GET["server"] === $_POST["server"] ? remove_from_uri() : preg_replace('~^[^?]*/([^?]*).*~', '\\1', $_SERVER["REQUEST_URI"]) . (strlen($_POST["server"]) ? '?server=' . urlencode($_POST["server"]) : ''));
|
||||
if (!isset($_COOKIE[$session_name])) {
|
||||
|
@ -66,7 +66,7 @@ function auth_error($exception = null) {
|
|||
|
||||
$username = &$_SESSION["usernames"][$_GET["server"]];
|
||||
if (!isset($username)) {
|
||||
$username = $_GET["username"];
|
||||
$username = $_GET["username"]; // default username can be passed in URL
|
||||
}
|
||||
$dbh = (isset($username) ? connect() : '');
|
||||
unset($username);
|
||||
|
|
|
@ -20,7 +20,7 @@ if (!(strlen($_GET["db"]) ? $dbh->select_db($_GET["db"]) : isset($_GET["sql"]) |
|
|||
if (strlen($_GET["db"])) {
|
||||
unset($_SESSION["databases"][$_GET["server"]]);
|
||||
}
|
||||
connect_error();
|
||||
connect_error(); // separate function to catch SQLite error
|
||||
exit;
|
||||
}
|
||||
$dbh->query("SET CHARACTER SET utf8");
|
||||
|
|
|
@ -47,6 +47,7 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
|
|||
$databases = null;
|
||||
}
|
||||
if (isset($databases) && !isset($_GET["sql"]) && !isset($_SESSION["coverage"])) {
|
||||
// improves concurrency if a user opens several pages at once
|
||||
session_write_close();
|
||||
}
|
||||
if ($error) {
|
||||
|
@ -55,7 +56,7 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
|
|||
}
|
||||
|
||||
function page_footer($missing = false) {
|
||||
global $SELF, $dbh, $VERSION;
|
||||
global $SELF, $VERSION, $dbh;
|
||||
?>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ function input($name, $field, $value, $separator = "</td><td>") { //! pass empty
|
|||
$options = (preg_match('~char~', $field["type"]) ? array("", "md5", "sha1", "password", "uuid") : array("", "now"));
|
||||
}
|
||||
if (!isset($_GET["call"]) && (isset($_GET["select"]) || where($_GET))) {
|
||||
// relative functions
|
||||
if (preg_match('~int|float|double|decimal~', $field["type"])) {
|
||||
$options = array("", "+", "-");
|
||||
}
|
||||
|
@ -55,6 +56,7 @@ function input($name, $field, $value, $separator = "</td><td>") { //! pass empty
|
|||
} elseif (preg_match('~binary|blob~', $field["type"])) {
|
||||
echo (ini_get("file_uploads") ? '<input type="file" name="' . $name . '"' . $onchange . ' />' : lang('File uploads are disabled.') . ' ');
|
||||
} else {
|
||||
// int(3) is only a display hint
|
||||
$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 '<input name="fields[' . $name . ']" value="' . htmlspecialchars($value) . '"' . ($maxlength ? " maxlength='$maxlength'" : "") . $onchange . ' />';
|
||||
}
|
||||
|
@ -87,7 +89,7 @@ function process_input($name, $field) {
|
|||
} 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) . "'") . "";
|
||||
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)) {
|
||||
|
|
|
@ -11,7 +11,7 @@ function dump_csv($row) {
|
|||
function dump_table($table, $style, $is_view = false) {
|
||||
global $dbh;
|
||||
if ($_POST["format"] == "csv") {
|
||||
echo "\xef\xbb\xbf";
|
||||
echo "\xef\xbb\xbf"; // UTF-8 byte order mark
|
||||
if ($style) {
|
||||
dump_csv(array_keys(fields($table)));
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ function dump_table($table, $style, $is_view = false) {
|
|||
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 = '" . $dbh->escape_string($table) . "' ORDER BY ORDINAL_POSITION";
|
||||
?>
|
||||
DELIMITER ;;
|
||||
|
@ -131,7 +132,7 @@ function dump_data($table, $style, $select = "") {
|
|||
} else {
|
||||
$s = "\n(" . implode(", ", $row2) . ")";
|
||||
if (!$length) {
|
||||
echo $insert, $s;
|
||||
echo $insert, $s; // comma used to save memory
|
||||
$length = strlen($insert) + strlen($s);
|
||||
} else {
|
||||
$length += 2 + strlen($s);
|
||||
|
@ -155,7 +156,7 @@ function dump_data($table, $style, $select = "") {
|
|||
|
||||
function dump_headers($identifier, $multi_table = false) {
|
||||
$filename = (strlen($identifier) ? friendly_url($identifier) : "dump");
|
||||
$ext = ($_POST["format"] == "sql" ? "sql" : ($multi_table ? "tar" : "csv"));
|
||||
$ext = ($_POST["format"] == "sql" ? "sql" : ($multi_table ? "tar" : "csv")); // multiple CSV packed to TAR
|
||||
header("Content-Type: " . ($ext == "tar" ? "application/x-tar" : ($ext == "sql" || $_POST["output"] != "file" ? "text/plain" : "text/csv")) . "; charset=utf-8");
|
||||
if ($_POST["output"] == "file") {
|
||||
header("Content-Disposition: attachment; filename=$filename.$ext");
|
||||
|
|
|
@ -8,6 +8,7 @@ function idf_unescape($idf) {
|
|||
}
|
||||
|
||||
function bracket_escape($idf, $back = false) {
|
||||
// escape brackets inside name="x[]"
|
||||
static $trans = array(':' => ':1', ']' => ':2', '[' => ':3');
|
||||
return strtr($idf, ($back ? array_flip($trans) : $trans));
|
||||
}
|
||||
|
@ -46,7 +47,7 @@ function unique_idf($row, $indexes) {
|
|||
if ($index["type"] == "PRIMARY" || $index["type"] == "UNIQUE") {
|
||||
$return = array();
|
||||
foreach ($index["columns"] as $key) {
|
||||
if (!isset($row[$key])) {
|
||||
if (!isset($row[$key])) { // NULL is ambiguous
|
||||
continue 2;
|
||||
}
|
||||
$return[] = urlencode("where[" . bracket_escape($key) . "]") . "=" . urlencode($row[$key]);
|
||||
|
@ -90,6 +91,7 @@ function redirect($location, $message = null) {
|
|||
$_SESSION["messages"][] = $message;
|
||||
}
|
||||
if (strlen(SID)) {
|
||||
// append SID if session cookies are disabled
|
||||
$location .= (strpos($location, "?") === false ? "?" : "&") . SID;
|
||||
}
|
||||
header("Location: " . (strlen($location) ? $location : "."));
|
||||
|
@ -121,6 +123,7 @@ function queries($query = null) {
|
|||
global $dbh;
|
||||
static $queries = array();
|
||||
if (!isset($query)) {
|
||||
// return executed queries without parameter
|
||||
return implode(";\n", $queries);
|
||||
}
|
||||
$queries[] = $query;
|
||||
|
@ -137,7 +140,9 @@ function print_page($page) {
|
|||
}
|
||||
|
||||
function get_file($key) {
|
||||
// returns int for error, string otherwise
|
||||
if (isset($_POST["files"][$key])) {
|
||||
// get the file from hidden field if the user was logged out
|
||||
$length = strlen($_POST["files"][$key]);
|
||||
return ($length && $length < 4 ? intval($_POST["files"][$key]) : base64_decode($_POST["files"][$key]));
|
||||
}
|
||||
|
@ -158,12 +163,12 @@ function select($result, $dbh2 = null) {
|
|||
echo "<p class='message'>" . lang('No rows.') . "</p>\n";
|
||||
} else {
|
||||
echo "<table cellspacing='0' class='nowrap'>\n";
|
||||
$links = array();
|
||||
$indexes = array();
|
||||
$columns = array();
|
||||
$blobs = array();
|
||||
$types = array();
|
||||
odd('');
|
||||
$links = array(); // colno => orgtable - create links from these columns
|
||||
$indexes = array(); // orgtable => array(column => colno) - primary keys
|
||||
$columns = array(); // orgtable => array(column => ) - not selected columns in primary key
|
||||
$blobs = array(); // colno => bool - display bytes for blobs
|
||||
$types = array(); // colno => type - display char in <code>
|
||||
odd(''); // reset odd for each result
|
||||
for ($i=0; $row = $result->fetch_row(); $i++) {
|
||||
if (!$i) {
|
||||
echo "<thead><tr>";
|
||||
|
@ -171,6 +176,7 @@ function select($result, $dbh2 = null) {
|
|||
$field = $result->fetch_field();
|
||||
if (strlen($field->orgtable)) {
|
||||
if (!isset($indexes[$field->orgtable])) {
|
||||
// find primary key in each table
|
||||
$indexes[$field->orgtable] = array();
|
||||
foreach (indexes($field->orgtable, $dbh2) as $index) {
|
||||
if ($index["type"] == "PRIMARY") {
|
||||
|
@ -202,7 +208,7 @@ function select($result, $dbh2 = null) {
|
|||
if ($blobs[$key] && !is_utf8($val)) {
|
||||
$val = "<i>" . lang('%d byte(s)', strlen($val)) . "</i>"; //! link to download
|
||||
} elseif (!strlen(trim($val))) {
|
||||
$val = " ";
|
||||
$val = " "; // some content to print a border
|
||||
} else {
|
||||
$val = nl2br(htmlspecialchars($val));
|
||||
if ($types[$key] == 254) {
|
||||
|
@ -227,6 +233,7 @@ function select($result, $dbh2 = null) {
|
|||
}
|
||||
|
||||
function is_utf8($val) {
|
||||
// don't print control chars except \t\r\n
|
||||
return (preg_match('~~u', $val) && !preg_match('~[\\0-\\x8\\xB\\xC\\xE-\\x1F]~', $val));
|
||||
}
|
||||
|
||||
|
@ -236,6 +243,7 @@ function shorten_utf8($string, $length = 80, $suffix = "") {
|
|||
}
|
||||
|
||||
function friendly_url($val) {
|
||||
// used for blobs and export
|
||||
return preg_replace('~[^a-z0-9_]~i', '-', $val);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<?php
|
||||
// not used in single language version
|
||||
|
||||
$langs = array(
|
||||
'en' => 'English', // Jakub Vrána - http://php.vrana.cz
|
||||
'cs' => 'Čeština', // Jakub Vrána - http://php.vrana.cz
|
||||
|
@ -17,7 +19,7 @@ function lang($idf, $number = null) {
|
|||
global $LANG, $translations;
|
||||
$translation = $translations[$idf];
|
||||
if (is_array($translation) && $translation) {
|
||||
$pos = ($number == 1 ? 0 : ((!$number || $number >= 5) && ereg('cs|sk|ru', $LANG) ? 2 : 1));
|
||||
$pos = ($number == 1 ? 0 : ((!$number || $number >= 5) && ereg('cs|sk|ru', $LANG) ? 2 : 1)); // Slavic languages use different form for 2, 3, 4
|
||||
$translation = $translation[$pos];
|
||||
}
|
||||
$args = func_get_args();
|
||||
|
@ -38,7 +40,7 @@ function switch_lang() {
|
|||
|
||||
if (isset($_GET["lang"])) {
|
||||
$_COOKIE["lang"] = $_GET["lang"];
|
||||
$_SESSION["lang"] = $_GET["lang"];
|
||||
$_SESSION["lang"] = $_GET["lang"]; // cookies may be disabled
|
||||
}
|
||||
|
||||
$LANG = "en";
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
// MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable
|
||||
if (extension_loaded("mysqli")) {
|
||||
class Min_DB extends MySQLi {
|
||||
var $extension = "MySQLi";
|
||||
|
@ -8,7 +9,7 @@ if (extension_loaded("mysqli")) {
|
|||
}
|
||||
|
||||
function connect($server, $username, $password) {
|
||||
list($host, $port) = explode(":", $server, 2);
|
||||
list($host, $port) = explode(":", $server, 2); // part after : is used for port or socket
|
||||
return @$this->real_connect(
|
||||
(strlen($server) ? $host : ini_get("mysqli.default_host")),
|
||||
(strlen("$server$username") ? $username : ini_get("mysqli.default_user")),
|
||||
|
@ -33,6 +34,7 @@ if (extension_loaded("mysqli")) {
|
|||
}
|
||||
|
||||
function query($query) {
|
||||
// result is packed in envelope object to allow minification
|
||||
$result = parent::query($query);
|
||||
return (is_object($result) ? new Min_Result($result) : $result);
|
||||
}
|
||||
|
@ -126,6 +128,7 @@ if (extension_loaded("mysqli")) {
|
|||
}
|
||||
|
||||
function next_result() {
|
||||
// MySQL extension doesn't support multiple results
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -187,6 +190,7 @@ if (extension_loaded("mysqli")) {
|
|||
exit;
|
||||
}
|
||||
|
||||
// value means maximum unsigned length
|
||||
$types = array(
|
||||
"tinyint" => 3, "smallint" => 5, "mediumint" => 8, "int" => 10, "bigint" => 20,
|
||||
"float" => 12, "double" => 21, "decimal" => 66,
|
||||
|
@ -205,6 +209,7 @@ function connect() {
|
|||
}
|
||||
|
||||
function get_databases() {
|
||||
// SHOW DATABASES can take very long so it is cached
|
||||
$return = &$_SESSION["databases"][$_GET["server"]];
|
||||
if (!isset($return)) {
|
||||
flush();
|
||||
|
@ -216,7 +221,7 @@ function get_databases() {
|
|||
function table_status($table) {
|
||||
global $dbh;
|
||||
$result = $dbh->query("SHOW TABLE STATUS LIKE '" . $dbh->escape_string(addcslashes($table, "%_")) . "'");
|
||||
$return = $result->fetch_assoc();
|
||||
$return = $result->fetch_assoc(); // ()-> is not supported in PHP 4
|
||||
$result->free();
|
||||
return $return;
|
||||
}
|
||||
|
@ -250,7 +255,7 @@ function fields($table) {
|
|||
|
||||
function indexes($table, $dbh2 = null) {
|
||||
global $dbh;
|
||||
if (!is_object($dbh2)) {
|
||||
if (!is_object($dbh2)) { // use the main connection if the separate connection is unavailable
|
||||
$dbh2 = $dbh;
|
||||
}
|
||||
$return = array();
|
||||
|
@ -313,6 +318,7 @@ function collations() {
|
|||
|
||||
function table_comment(&$row) {
|
||||
if ($row["Engine"] == "InnoDB") {
|
||||
// ignore internal comment, unnecessary since MySQL 5.1.21
|
||||
$row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\\1', $row["Comment"]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
// PDO can be used in several database drivers
|
||||
if (extension_loaded('pdo')) {
|
||||
class Min_PDO extends PDO {
|
||||
var $_result, $server_info, $affected_rows, $error;
|
||||
|
@ -14,6 +15,7 @@ if (extension_loaded('pdo')) {
|
|||
}
|
||||
|
||||
function select_db($database) {
|
||||
// database selection is separated from the connection so dbname in DSN can't be used
|
||||
return $this->query("USE " . idf_escape($database));
|
||||
}
|
||||
|
||||
|
@ -29,7 +31,7 @@ if (extension_loaded('pdo')) {
|
|||
$this->affected_rows = $result->rowCount();
|
||||
return true;
|
||||
}
|
||||
$result->num_rows = $result->rowCount();
|
||||
$result->num_rows = $result->rowCount(); // is not guaranteed to work with all drivers
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
|
||||
error_reporting(E_ALL & ~E_NOTICE);
|
||||
if (!ini_get("session.auto_start")) {
|
||||
// use specific session name to get own namespace
|
||||
session_name("adminer_sid");
|
||||
session_set_cookie_params(0, preg_replace('~\\?.*~', '', $_SERVER["REQUEST_URI"]));
|
||||
session_start();
|
||||
}
|
||||
if (isset($_SESSION["coverage"])) {
|
||||
// coverage is used in tests and removed in compilation
|
||||
function save_coverage() {
|
||||
foreach (xdebug_get_code_coverage() as $filename => $lines) {
|
||||
foreach ($lines as $l => $val) {
|
||||
|
@ -25,9 +27,11 @@ if (isset($_SESSION["coverage"])) {
|
|||
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
|
||||
register_shutdown_function('save_coverage');
|
||||
if ($_GET["start"]) {
|
||||
// included from ../coverage.php
|
||||
return;
|
||||
}
|
||||
}
|
||||
// disable magic quotes to be able to use database escaping function
|
||||
if (get_magic_quotes_gpc()) {
|
||||
$process = array(&$_GET, &$_POST, &$_COOKIE);
|
||||
while (list($key, $val) = each($process)) {
|
||||
|
@ -83,12 +87,15 @@ if (isset($_GET["download"])) {
|
|||
$error = lang('Invalid CSRF token. Send the form again.');
|
||||
}
|
||||
} elseif ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
// posted form with no data means exceeded post_max_size because Adminer always sends token at least
|
||||
$error = lang('Too big POST data. Reduce the data or increase the "post_max_size" configuration directive.');
|
||||
}
|
||||
if (isset($_GET["default"])) {
|
||||
// edit form is used for default values and distinguished by checking isset($_GET["default"]) in edit.inc.php
|
||||
$_GET["edit"] = $_GET["default"];
|
||||
}
|
||||
if (isset($_GET["select"]) && $_POST && (!$_POST["delete"] && !$_POST["export"] && !$_POST["import"] && !$_POST["save"])) {
|
||||
// POST form on select page is used to edit or clone data
|
||||
$_GET["edit"] = $_GET["select"];
|
||||
}
|
||||
if (isset($_GET["callf"])) {
|
||||
|
@ -131,4 +138,5 @@ if (isset($_GET["download"])) {
|
|||
include "./db.inc.php";
|
||||
}
|
||||
}
|
||||
// each page calls its own page_header(), if the footer should not be called then the page exits
|
||||
page_footer();
|
||||
|
|
|
@ -3,6 +3,7 @@ page_header(lang('Privileges'));
|
|||
echo '<p><a href="' . htmlspecialchars($SELF) . 'user=">' . lang('Create user') . "</a></p>";
|
||||
$result = $dbh->query("SELECT User, Host FROM mysql.user ORDER BY Host, User");
|
||||
if (!$result) {
|
||||
//! utilize information_schema.USER_PRIVILEGES in MySQL 5
|
||||
?>
|
||||
<form action=""><p>
|
||||
<?php if (strlen($_GET["server"])) { ?><input type="hidden" name="server" value="<?php echo htmlspecialchars($_GET["server"]); ?>" /><?php } ?>
|
||||
|
@ -12,12 +13,13 @@ if (!$result) {
|
|||
<input type="submit" value="<?php echo lang('Edit'); ?>" />
|
||||
</p></form>
|
||||
<?php
|
||||
// list logged user
|
||||
$result = $dbh->query("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', 1) AS User, SUBSTRING_INDEX(CURRENT_USER, '@', -1) AS Host");
|
||||
}
|
||||
echo "<table cellspacing='0'>\n";
|
||||
echo "<thead><tr><th> </th><th>" . lang('Username') . "</th><th>" . lang('Server') . "</th></tr></thead>\n";
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
echo '<tr' . odd() . '><td><a href="' . htmlspecialchars($SELF) . 'user=' . urlencode($row["User"]) . '&host=' . urlencode($row["Host"]) . '">' . lang('edit') . '</a></td><td>' . htmlspecialchars($row["User"]) . "</td><td>" . htmlspecialchars($row["Host"]) . "</td></tr>\n";
|
||||
echo '<tr' . odd() . '><td><a href="' . htmlspecialchars($SELF . 'user=' . urlencode($row["User"]) . '&host=' . urlencode($row["Host"])) . '">' . lang('edit') . '</a></td><td>' . htmlspecialchars($row["User"]) . "</td><td>" . htmlspecialchars($row["Host"]) . "</td></tr>\n";
|
||||
}
|
||||
echo "</table>\n";
|
||||
$result->free();
|
||||
|
|
|
@ -9,7 +9,7 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
|
|||
if (!$_POST["drop"]) {
|
||||
$set = array();
|
||||
$fields = array_filter((array) $_POST["fields"], 'strlen');
|
||||
ksort($fields);
|
||||
ksort($fields); // enforce fields order
|
||||
foreach ($fields as $field) {
|
||||
if (strlen($field["field"])) {
|
||||
$set[] = (in_array($field["inout"], $inout) ? "$field[inout] " : "") . idf_escape($field["field"]) . process_type($field, "CHARACTER SET");
|
||||
|
|
|
@ -3,6 +3,7 @@ page_header(lang('Database schema'), "", array(), $_GET["db"]);
|
|||
|
||||
$table_pos = array();
|
||||
$table_pos_js = array();
|
||||
// saved in one cookie because there is a limit of 20 cookies per domain
|
||||
preg_match_all('~([^:]+):([-0-9.]+)x([-0-9.]+)(_|$)~', $_COOKIE["schema"], $matches, PREG_SET_ORDER); //! ':' in table name
|
||||
foreach ($matches as $i => $match) {
|
||||
$table_pos[$match[1]] = array($match[2], $match[3]);
|
||||
|
@ -11,9 +12,9 @@ foreach ($matches as $i => $match) {
|
|||
|
||||
$top = 0;
|
||||
$base_left = -1;
|
||||
$schema = array();
|
||||
$referenced = array();
|
||||
$lefts = array();
|
||||
$schema = array(); // table => array("fields" => array(name => field), "pos" => array(top, left), "references" => array(table => array(left => array(source, target))))
|
||||
$referenced = array(); // target_table => array(table => array(left => target_column))
|
||||
$lefts = array(); // float => bool
|
||||
$result = $dbh->query("SHOW TABLE STATUS");
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
if (!isset($row["Engine"])) { // view
|
||||
|
@ -37,6 +38,7 @@ while ($row = $result->fetch_assoc()) {
|
|||
$base_left -= .1;
|
||||
}
|
||||
while ($lefts[(string) $left]) {
|
||||
// find free $left
|
||||
$left -= .0001;
|
||||
}
|
||||
$schema[$row["Name"]]["references"][$val["table"]][(string) $left] = array($val["source"], $val["target"]);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
$functions = array("char_length", "from_unixtime", "hex", "lower", "round", "sec_to_time", "time_to_sec", "unix_timestamp", "upper");
|
||||
$grouping = array("avg", "count", "distinct", "group_concat", "max", "min", "sum");
|
||||
$grouping = array("avg", "count", "distinct", "group_concat", "max", "min", "sum"); // distinct is short for COUNT(DISTINCT)
|
||||
$table_status = table_status($_GET["select"]);
|
||||
$indexes = indexes($_GET["select"]);
|
||||
$operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "REGEXP", "IN", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL");
|
||||
|
@ -8,8 +8,8 @@ if (eregi('^(MyISAM|Maria)$', $table_status["Engine"])) {
|
|||
$operators[] = "AGAINST";
|
||||
}
|
||||
$fields = fields($_GET["select"]);
|
||||
$rights = array();
|
||||
$columns = array();
|
||||
$rights = array(); // privilege => 0
|
||||
$columns = array(); // selectable columns
|
||||
unset($text_length);
|
||||
foreach ($fields as $key => $field) {
|
||||
if (isset($field["privileges"]["select"])) {
|
||||
|
@ -21,8 +21,8 @@ foreach ($fields as $key => $field) {
|
|||
$rights += $field["privileges"];
|
||||
}
|
||||
|
||||
$select = array();
|
||||
$group = array();
|
||||
$select = array(); // select expressions, empty for *
|
||||
$group = array(); // expressions without aggregation - will be used for GROUP BY if an aggregation function is used
|
||||
foreach ((array) $_GET["columns"] as $key => $val) {
|
||||
if ($val["fun"] == "count" || (in_array($val["col"], $columns, true) && (!$val["fun"] || in_array($val["fun"], $functions) || in_array($val["fun"], $grouping)))) {
|
||||
$select[$key] = (in_array($val["col"], $columns, true) ? (!$val["fun"] ? idf_escape($val["col"]) : ($val["fun"] == "distinct" ? "COUNT(DISTINCT " : strtoupper("$val[fun](")) . idf_escape($val["col"]) . ")") : "COUNT(*)");
|
||||
|
@ -31,7 +31,7 @@ foreach ((array) $_GET["columns"] as $key => $val) {
|
|||
}
|
||||
}
|
||||
}
|
||||
$where = array();
|
||||
$where = array(); // where expressions - will be joined by AND
|
||||
foreach ($indexes as $i => $index) {
|
||||
if ($index["type"] == "FULLTEXT" && strlen($_GET["fulltext"][$i])) {
|
||||
$where[] = "MATCH (" . implode(", ", array_map('idf_escape', $index["columns"])) . ") AGAINST ('" . $dbh->escape_string($_GET["fulltext"][$i]) . "'" . (isset($_GET["boolean"][$i]) ? " IN BOOLEAN MODE" : "") . ")";
|
||||
|
@ -48,6 +48,7 @@ foreach ((array) $_GET["where"] as $val) {
|
|||
if (strlen($val["col"])) {
|
||||
$where[] = idf_escape($val["col"]) . $cond;
|
||||
} else {
|
||||
// find anywhere
|
||||
$cols = array();
|
||||
foreach ($fields as $name => $field) {
|
||||
if (is_numeric($val["val"]) || !ereg('int|float|double|decimal', $field["type"])) {
|
||||
|
@ -59,7 +60,7 @@ foreach ((array) $_GET["where"] as $val) {
|
|||
}
|
||||
}
|
||||
}
|
||||
$order = array();
|
||||
$order = array(); // order expressions - will be joined by comma
|
||||
foreach ((array) $_GET["order"] as $key => $val) {
|
||||
if (in_array($val, $columns, true) || in_array($val, $select, true)) {
|
||||
$order[] = idf_escape($val) . (isset($_GET["desc"][$key]) ? " DESC" : "");
|
||||
|
@ -76,6 +77,7 @@ if ($_POST && !$error) {
|
|||
if (is_array($_POST["check"])) {
|
||||
$union = array();
|
||||
foreach ($_POST["check"] as $val) {
|
||||
// where may not be unique so OR can't be used
|
||||
$union[] = "($query WHERE " . implode(" AND ", where_check($val)) . " LIMIT 1)";
|
||||
}
|
||||
dump_data($_GET["select"], "INSERT", implode(" UNION ALL ", $union));
|
||||
|
@ -108,6 +110,7 @@ if ($_POST && !$error) {
|
|||
} else {
|
||||
foreach ((array) $_POST["check"] as $val) {
|
||||
parse_str($val, $check);
|
||||
// where may not be unique so OR can't be used
|
||||
$result = queries($command . " WHERE " . implode(" AND ", where($check)) . " LIMIT 1");
|
||||
if (!$result) {
|
||||
break;
|
||||
|
@ -126,15 +129,16 @@ if ($_POST && !$error) {
|
|||
$row = array();
|
||||
preg_match_all('~(("[^"]*")+|[^,]*),~', "$val,", $matches2);
|
||||
if (!$key && !array_diff($matches2[1], array_keys($fields))) { //! doesn't work with column names containing ",\n
|
||||
// first row corresponds to column names - use it for table structure
|
||||
$cols = " (" . implode(", ", array_map('idf_escape', $matches2[1])) . ")";
|
||||
} else {
|
||||
foreach ($matches2[1] as $col) {
|
||||
$row[] = (!strlen($col) ? "NULL" : "'" . $dbh->escape_string(str_replace('""', '"', preg_replace('~^".*"$~s', '', $col))) . "'");
|
||||
}
|
||||
$rows[] = "(" . implode(", ", $row) . ")";
|
||||
$rows[] = "\n(" . implode(", ", $row) . ")";
|
||||
}
|
||||
}
|
||||
$result = queries("INSERT INTO " . idf_escape($_GET["select"]) . "$cols VALUES " . implode(", ", $rows));
|
||||
$result = queries("INSERT INTO " . idf_escape($_GET["select"]) . "$cols VALUES" . implode(",", $rows));
|
||||
query_redirect(queries(), remove_from_uri("page"), lang('%d row(s) has been imported.', $dbh->affected_rows), $result, false, !$result);
|
||||
} else {
|
||||
$error = lang('Unable to upload a file.');
|
||||
|
@ -209,7 +213,7 @@ if (!$columns) {
|
|||
echo "<label><input type='checkbox' name='desc[$i]' value='1' />" . lang('descending') . "</label></div>\n";
|
||||
echo "</div></fieldset>\n";
|
||||
|
||||
echo "<fieldset><legend>" . lang('Limit') . "</legend><div>";
|
||||
echo "<fieldset><legend>" . lang('Limit') . "</legend><div>"; // <div> for easy styling
|
||||
echo "<input name='limit' size='3' value=\"" . htmlspecialchars($limit) . "\" />";
|
||||
echo "</div></fieldset>\n";
|
||||
|
||||
|
@ -271,6 +275,7 @@ if (!$columns) {
|
|||
}
|
||||
foreach ((array) $foreign_keys[$key] as $foreign_key) {
|
||||
if (count($foreign_keys[$key]) == 1 || count($foreign_key["source"]) == 1) {
|
||||
// link related items
|
||||
$val = "\">$val</a>";
|
||||
foreach ($foreign_key["source"] as $i => $source) {
|
||||
$val = "&where%5B$i%5D%5Bcol%5D=" . urlencode($foreign_key["target"][$i]) . "&where%5B$i%5D%5Bop%5D=%3D&where%5B$i%5D%5Bval%5D=" . urlencode($row[$source]) . $val;
|
||||
|
@ -287,11 +292,13 @@ if (!$columns) {
|
|||
echo "</table>\n";
|
||||
|
||||
echo "<p>";
|
||||
// use num_rows without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest)
|
||||
$found_rows = (intval($limit) ? $dbh->result($dbh->query(count($group) < count($select)
|
||||
? " SELECT FOUND_ROWS()" // space to allow mysql.trace_mode
|
||||
: "SELECT COUNT(*) FROM " . idf_escape($_GET["select"]) . ($where ? " WHERE " . implode(" AND ", $where) : "")
|
||||
)) : $result->num_rows);
|
||||
if (intval($limit) && $found_rows > $limit) {
|
||||
// display first, previous 3, next 3 and last page
|
||||
$max_page = floor(($found_rows - 1) / $limit);
|
||||
echo lang('Page') . ":";
|
||||
print_page(0);
|
||||
|
|
|
@ -3,11 +3,11 @@ page_header(lang('SQL command'), $error);
|
|||
$history = &$_SESSION["history"][$_GET["server"]][$_GET["db"]];
|
||||
|
||||
if (!$error && $_POST) {
|
||||
if (is_string($query = (isset($_POST["file"]) ? get_file("sql_file") : $_POST["query"]))) {
|
||||
@set_time_limit(0);
|
||||
$query = str_replace("\r", "", $query);
|
||||
if (is_string($query = (isset($_POST["file"]) ? get_file("sql_file") : $_POST["query"]))) { // get_file() returns error as number
|
||||
@set_time_limit(0); // set_time_limit() can be disabled
|
||||
$query = str_replace("\r", "", $query); // parser looks for \n
|
||||
$query = rtrim($query);
|
||||
if (strlen($query) && $history[count($history) - 1] != $query) {
|
||||
if (strlen($query) && $history[count($history)-1] != $query) { // don't add repeated
|
||||
$history[] = $query;
|
||||
}
|
||||
$delimiter = ";";
|
||||
|
@ -24,14 +24,15 @@ if (!$error && $_POST) {
|
|||
$query = substr($query, strlen($match[0]));
|
||||
} elseif (preg_match('(' . preg_quote($delimiter) . '|[\'`"]|/\\*|-- |#|$)', $query, $match, PREG_OFFSET_CAPTURE, $offset)) {
|
||||
if ($match[0][0] && $match[0][0] != $delimiter) {
|
||||
// is not end of a query - find closing part
|
||||
$pattern = ($match[0][0] == "-- " || $match[0][0] == "#" ? '~.*~' : ($match[0][0] == "/*" ? '~.*\\*/~sU' : '~\\G([^\\\\' . $match[0][0] . ']+|\\\\.)*(' . $match[0][0] . '|$)~s'));
|
||||
preg_match($pattern, $query, $match, PREG_OFFSET_CAPTURE, $match[0][1] + 1);
|
||||
$offset = $match[0][1] + strlen($match[0][0]);
|
||||
} else {
|
||||
$empty = false;
|
||||
echo "<pre class='jush-sql'>" . shorten_utf8(trim(substr($query, 0, $match[0][1]))) . "</pre>\n";
|
||||
flush();
|
||||
$start = explode(" ", microtime());
|
||||
flush(); // can take a long time - show the running query
|
||||
$start = explode(" ", microtime()); // microtime(true) is available since PHP 5
|
||||
//! don't allow changing of character_set_results, convert encoding of displayed query
|
||||
if (!$dbh->multi_query(substr($query, 0, $match[0][1]))) {
|
||||
echo "<p class='error'>" . lang('Error in query') . ": " . htmlspecialchars($dbh->error) . "</p>\n";
|
||||
|
@ -47,7 +48,7 @@ if (!$error && $_POST) {
|
|||
select($result, $dbh2);
|
||||
} else {
|
||||
if (preg_match("~^$space*(CREATE|DROP)$space+(DATABASE|SCHEMA)\\b~isU", $query)) {
|
||||
unset($_SESSION["databases"][$_GET["server"]]);
|
||||
unset($_SESSION["databases"][$_GET["server"]]); // clear cache
|
||||
}
|
||||
echo "<p class='message'>" . lang('Query executed OK, %d row(s) affected.', $dbh->affected_rows) . "</p>\n";
|
||||
}
|
||||
|
@ -89,6 +90,7 @@ if (!ini_get("file_uploads")) {
|
|||
if ($history) {
|
||||
echo "<fieldset><legend>" . lang('History') . "</legend>\n";
|
||||
foreach ($history as $key => $val) {
|
||||
//! save and display timestamp
|
||||
echo '<a href="' . htmlspecialchars($SELF . "sql=&history=$key") . '">' . lang('Edit') . '</a> <code class="jush-sql">' . shorten_utf8(str_replace("\n", " ", $val), 80, "</code>") . "<br />\n";
|
||||
}
|
||||
echo "</fieldset>\n";
|
||||
|
|
|
@ -30,7 +30,7 @@ if ($result) {
|
|||
if ($indexes) {
|
||||
echo "<table cellspacing='0'>\n";
|
||||
foreach ($indexes as $index) {
|
||||
ksort($index["columns"]);
|
||||
ksort($index["columns"]); // enforce correct columns order
|
||||
$print = array();
|
||||
foreach ($index["columns"] as $key => $val) {
|
||||
$print[] = "<i>" . htmlspecialchars($val) . "</i>" . ($index["lengths"][$key] ? "(" . $index["lengths"][$key] . ")" : "");
|
||||
|
@ -47,12 +47,12 @@ if ($result) {
|
|||
if ($foreign_keys) {
|
||||
echo "<table cellspacing='0'>\n";
|
||||
foreach ($foreign_keys as $name => $foreign_key) {
|
||||
$link = (strlen($foreign_key["db"]) ? "<strong>" . htmlspecialchars($foreign_key["db"]) . "</strong>." : "") . htmlspecialchars($foreign_key["table"]);
|
||||
echo "<tr>";
|
||||
echo "<td><i>" . implode("</i>, <i>", array_map('htmlspecialchars', $foreign_key["source"])) . "</i></td>";
|
||||
$link = (strlen($foreign_key["db"]) ? "<strong>" . htmlspecialchars($foreign_key["db"]) . "</strong>." : "") . htmlspecialchars($foreign_key["table"]);
|
||||
echo '<td><a href="' . htmlspecialchars(strlen($foreign_key["db"]) ? preg_replace('~db=[^&]*~', "db=" . urlencode($foreign_key["db"]), $SELF) : $SELF) . "table=" . urlencode($foreign_key["table"]) . "\">$link</a>";
|
||||
echo "(<em>" . implode("</em>, <em>", array_map('htmlspecialchars', $foreign_key["target"])) . "</em>)</td>";
|
||||
echo '<td>' . (!strlen($foreign_key["db"]) ? '<a href="' . htmlspecialchars($SELF) . 'foreign=' . urlencode($_GET["table"]) . '&name=' . urlencode($name) . '">' . lang('Alter') . '</a>' : ' ') . '</td>';
|
||||
echo "<td>" . (!strlen($foreign_key["db"]) ? '<a href="' . htmlspecialchars($SELF) . 'foreign=' . urlencode($_GET["table"]) . '&name=' . urlencode($name) . '">' . lang('Alter') . '</a>' : ' ') . "</td>";
|
||||
echo "</tr>\n";
|
||||
}
|
||||
echo "</table>\n";
|
||||
|
|
|
@ -21,6 +21,7 @@ if ($_POST) {
|
|||
} elseif (strlen($_GET["name"])) {
|
||||
$result = $dbh->query("SHOW TRIGGERS LIKE '" . $dbh->escape_string(addcslashes($_GET["trigger"], "%_")) . "'");
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
// LIKE is used to compare the table name
|
||||
if ($row["Trigger"] === $_GET["name"]) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@ while ($row = $result->fetch_assoc()) {
|
|||
}
|
||||
$result->free();
|
||||
$privileges["Server Admin"] += $privileges["File access on server"];
|
||||
$privileges["Databases"]["Create routine"] = $privileges["Procedures"]["Create routine"];
|
||||
$privileges["Databases"]["Create routine"] = $privileges["Procedures"]["Create routine"]; // MySQL bug #30305
|
||||
unset($privileges["Procedures"]["Create routine"]);
|
||||
$privileges["Columns"] = array();
|
||||
foreach (array("Select", "Insert", "Update", "References") as $val) {
|
||||
$privileges["Columns"][$val] = $privileges["Tables"][$val];
|
||||
}
|
||||
unset($privileges["Server Admin"]["Usage"]);
|
||||
unset($privileges["Procedures"]["Create routine"]);
|
||||
foreach ($privileges["Tables"] as $key => $val) {
|
||||
unset($privileges["Databases"][$key]);
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ if ($_POST && !$error) {
|
|||
}
|
||||
$grant = array_keys($grant);
|
||||
if (isset($_GET["grant"])) {
|
||||
// no rights to mysql.user table
|
||||
$revoke = array_diff(array_keys(array_filter($new_grants[$object], 'strlen')), $grant);
|
||||
} elseif ($old_user == $new_user) {
|
||||
$old_grant = array_keys((array) $grants[$object]);
|
||||
|
@ -111,7 +112,7 @@ if ($_POST) {
|
|||
$row = $_POST;
|
||||
$grants = $new_grants;
|
||||
} else {
|
||||
$row = $_GET + array("host" => "localhost");
|
||||
$row = $_GET + array("host" => "localhost"); // create user on localhost by default
|
||||
$row["pass"] = $old_pass;
|
||||
if (strlen($old_pass)) {
|
||||
$row["hashed"] = true;
|
||||
|
@ -134,7 +135,6 @@ echo "<thead><tr><th colspan='2'>" . lang('Privileges') . "</th>";
|
|||
$i = 0;
|
||||
foreach ($grants as $object => $grant) {
|
||||
echo '<th>' . ($object != "*.*" ? '<input name="objects[' . $i . ']" value="' . htmlspecialchars($object) . '" size="10" />' : '<input type="hidden" name="objects[' . $i . ']" value="*.*" size="10" />*.*') . '</th>'; //! separate db, table, columns, PROCEDURE|FUNCTION, routine
|
||||
//! JS checkbox for all
|
||||
$i++;
|
||||
}
|
||||
echo "</tr></thead>\n";
|
||||
|
|
31
compile.php
31
compile.php
|
@ -10,13 +10,13 @@ function remove_lang($match) {
|
|||
global $translations;
|
||||
$idf = strtr($match[2], array("\\'" => "'", "\\\\" => "\\"));
|
||||
$s = ($translations[$idf] ? $translations[$idf] : $idf);
|
||||
if ($match[3] == ",") {
|
||||
if ($match[3] == ",") { // lang() has parameters
|
||||
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();
|
||||
$lang_ids = array(); // global variable simplifies usage in a callback function
|
||||
function lang_ids($match) {
|
||||
global $lang_ids;
|
||||
return 'lang(' . $lang_ids[stripslashes($match[1])] . $match[2];
|
||||
|
@ -30,6 +30,7 @@ function put_file($match) {
|
|||
}
|
||||
$return = "";
|
||||
foreach (glob(dirname(__FILE__) . "/adminer/lang/*.inc.php") as $filename) {
|
||||
// assign translation numbers
|
||||
include $filename;
|
||||
foreach ($translations as $key => $val) {
|
||||
if (!isset($lang_ids[$key])) {
|
||||
|
@ -38,7 +39,7 @@ function put_file($match) {
|
|||
}
|
||||
}
|
||||
foreach (glob(dirname(__FILE__) . "/adminer/lang/*.inc.php") as $filename) {
|
||||
include $filename;
|
||||
include $filename; // reassign $translations
|
||||
$translation_ids = array_flip($lang_ids);
|
||||
foreach ($translations as $key => $val) {
|
||||
$translation_ids[$lang_ids[$key]] = $val;
|
||||
|
@ -53,9 +54,10 @@ function put_file($match) {
|
|||
}
|
||||
$return = file_get_contents(dirname(__FILE__) . "/adminer/$match[2]");
|
||||
if ($match[2] != "./include/lang.inc.php" || !$_COOKIE["lang"]) {
|
||||
$tokens = token_get_all($return);
|
||||
$tokens = token_get_all($return); // to find out the last token
|
||||
return "?>\n$return" . (in_array($tokens[count($tokens) - 1][0], array(T_CLOSE_TAG, T_INLINE_HTML), true) ? "<?php" : "");
|
||||
} elseif (preg_match('~\\s*(\\$pos = .*)~', $return, $match2)) {
|
||||
// single language lang() is used for plural
|
||||
return "function lang(\$translation, \$number) {\n\t" . str_replace('$LANG', "'$_COOKIE[lang]'", $match2[1]) . "\n\treturn sprintf(\$translation[\$pos], \$number);\n}\n";
|
||||
} else {
|
||||
echo "lang() not found\n";
|
||||
|
@ -75,10 +77,10 @@ function short_identifier($number, $chars) {
|
|||
function php_shrink($input) {
|
||||
$special_variables = array_flip(array('$this', '$GLOBALS', '$_GET', '$_POST', '$_FILES', '$_COOKIE', '$_SESSION', '$_SERVER'));
|
||||
static $short_variables = array();
|
||||
static $short_functions = 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) {
|
||||
|
@ -101,9 +103,9 @@ function php_shrink($input) {
|
|||
foreach ($short_functions as $key => $val) {
|
||||
if (isset($defined_functions[$key])) {
|
||||
do {
|
||||
$short_functions[$key] = short_identifier($number, implode("", range('a', 'z')));
|
||||
$short_functions[$key] = short_identifier($number, implode("", range('a', 'z'))); // _ not used to not collide with gettext()
|
||||
$number++;
|
||||
} while (isset($short_functions[$short_functions[$key]]));
|
||||
} while (isset($short_functions[$short_functions[$key]])); // don't overwrite existing functions
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,6 +131,7 @@ function php_shrink($input) {
|
|||
} elseif ($token[1] == ';' && $in_echo) {
|
||||
$in_echo = false;
|
||||
if ($tokens[$i+1][0] === T_WHITESPACE && $tokens[$i+2][0] === T_ECHO) {
|
||||
// join two consecutive echos
|
||||
next($tokens);
|
||||
next($tokens);
|
||||
$token[1] = '.'; //! join ''.'' and "".""
|
||||
|
@ -136,10 +139,13 @@ function php_shrink($input) {
|
|||
} 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'
|
||||
&& $tokens[$i-1][0] !== T_DOUBLE_COLON && $tokens[$i-2][0] !== T_NEW && $tokens[$i-2][1] !== '_result' // don't substitute parent methods - used to link PHP methods only
|
||||
) {
|
||||
$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)])) {
|
||||
} 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)])
|
||||
) { // minify callback functions too
|
||||
$token[1] = "'" . $short_functions[substr($token[1], 1, -1)] . "'";
|
||||
}
|
||||
if (isset($set[substr($output, -1)]) || isset($set[$token[1]{0}])) {
|
||||
|
@ -154,7 +160,7 @@ function php_shrink($input) {
|
|||
|
||||
error_reporting(E_ALL & ~E_NOTICE);
|
||||
if ($_SERVER["argc"] > 1) {
|
||||
$_COOKIE["lang"] = $_SERVER["argv"][1];
|
||||
$_COOKIE["lang"] = $_SERVER["argv"][1]; // Adminer functions read language from cookie
|
||||
include dirname(__FILE__) . "/adminer/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";
|
||||
|
@ -168,6 +174,7 @@ $file = file_get_contents(dirname(__FILE__) . "/adminer/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"]) {
|
||||
// single language version
|
||||
$file = preg_replace_callback("~(<\\?php\\s*echo )?lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])(;\\s*\\?>)?~s", 'remove_lang', $file);
|
||||
$file = str_replace("<?php switch_lang(); ?>\n", "", $file);
|
||||
$file = str_replace('<?php echo $LANG; ?>', $_COOKIE["lang"], $file);
|
||||
|
@ -200,9 +207,9 @@ if (isset($_GET["file"])) {
|
|||
}
|
||||
}
|
||||
exit;
|
||||
}', $file);
|
||||
}', $file); // integrate static files
|
||||
$file = str_replace("../externals/jush/", "http://jush.sourceforge.net/", $file);
|
||||
$file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file);
|
||||
$file = php_shrink($file);
|
||||
fwrite(fopen($filename, "w"), $file);
|
||||
fwrite(fopen($filename, "w"), $file); // file_put_contents() since PHP 5
|
||||
echo "$filename created.\n";
|
||||
|
|
|
@ -7,6 +7,7 @@ if (!ini_get("session.auto_start")) {
|
|||
}
|
||||
|
||||
function xhtml_open_tags($s) {
|
||||
// returns array of opened tags in $s
|
||||
$return = array();
|
||||
preg_match_all('~<([^>]+)~', $s, $matches);
|
||||
foreach ($matches[1] as $val) {
|
||||
|
@ -32,6 +33,7 @@ if ($_GET["start"]) {
|
|||
exit;
|
||||
}
|
||||
if (preg_match('~^(include/)?[-_.a-z0-9]+$~i', $_GET["filename"])) {
|
||||
// highlight single file
|
||||
$filename = "adminer/$_GET[filename]";
|
||||
$cov = $_SESSION["coverage"][realpath($filename)];
|
||||
$file = explode("<br />", highlight_file($filename, true));
|
||||
|
@ -61,6 +63,7 @@ if (preg_match('~^(include/)?[-_.a-z0-9]+$~i', $_GET["filename"])) {
|
|||
$s .= "$line<br />\n";
|
||||
}
|
||||
} else {
|
||||
// display list of files
|
||||
echo "<table border='0' cellspacing='0' cellpadding='1'>\n";
|
||||
foreach (array_merge(glob("adminer/*.php"), glob("adminer/include/*.php")) as $filename) {
|
||||
$cov = $_SESSION["coverage"][realpath($filename)];
|
||||
|
|
11
lang.php
11
lang.php
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
error_reporting(E_ALL & ~E_NOTICE);
|
||||
if ($_SERVER["argc"] > 1) {
|
||||
$_COOKIE["lang"] = $_SERVER["argv"][1];
|
||||
$_COOKIE["lang"] = $_SERVER["argv"][1]; // Adminer functions read language from cookie
|
||||
include dirname(__FILE__) . "/adminer/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";
|
||||
echo "Usage: php lang.php [lang]\nPurpose: Update adminer/lang/*.inc.php from source code messages.\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ if ($_SERVER["argc"] > 1) {
|
|||
$messages_all = array();
|
||||
foreach (array_merge(glob(dirname(__FILE__) . "/adminer/*.php"), glob(dirname(__FILE__) . "/adminer/include/*.php")) as $filename) {
|
||||
$file = file_get_contents($filename);
|
||||
if (preg_match_all("~lang\\(('(?:[^\\\\']+|\\\\.)*')([),])~", $file, $matches)) {
|
||||
if (preg_match_all("~lang\\(('(?:[^\\\\']+|\\\\.)*')([),])~", $file, $matches)) { // lang() always uses apostrophes
|
||||
$messages_all += array_combine($matches[1], $matches[2]);
|
||||
}
|
||||
}
|
||||
|
@ -23,19 +23,22 @@ foreach (glob(dirname(__FILE__) . "/adminer/lang/" . ($_COOKIE["lang"] ? $_COOKI
|
|||
$s = "";
|
||||
foreach ($matches as $match) {
|
||||
if (isset($messages[$match[3]])) {
|
||||
// keep current messages
|
||||
$s .= "$match[1]$match[2],\n";
|
||||
unset($messages[$match[3]]);
|
||||
} else {
|
||||
// comment deprecated messages
|
||||
$s .= "$match[1]// $match[2],\n";
|
||||
}
|
||||
}
|
||||
foreach($messages as $idf => $val) {
|
||||
// add new messages
|
||||
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"), "<?php\n\$translations = array(\n$s);\n");
|
||||
fwrite(fopen($filename, "w"), "<?php\n\$translations = array(\n$s);\n"); // file_put_contents() since PHP 5
|
||||
echo "$filename updated.\n";
|
||||
}
|
||||
|
|
1
todo.txt
1
todo.txt
|
@ -6,7 +6,6 @@ Transactions in export
|
|||
Compress export and import
|
||||
Create view and routine options
|
||||
Function to fix database encoding - http://php.vrana.cz/prevod-kodovani-mysql.php
|
||||
Utilize information_schema.USER_PRIVILEGES in Privileges
|
||||
Highlight SQL textarea - may use external CodePress
|
||||
Mass editation of individual rows
|
||||
IE6 - <label for>
|
||||
|
|
Loading…
Reference in a new issue