1
0
mirror of https://github.com/vrana/adminer.git synced 2025-09-03 19:32:36 +02:00

Compare commits

...

95 Commits

Author SHA1 Message Date
Jakub Vrana
63872de0f9 Release 3.6.0 2012-09-16 06:22:20 -07:00
Jakub Vrana
360218be0c Print compile errors to STDERR 2012-09-16 06:13:48 -07:00
Jakub Vrana
57d0c4c6f5 Fix switching language in compiled version 2012-09-16 06:09:36 -07:00
Jakub Vrana
ebbb35a0c3 Cache static files more 2012-09-11 09:16:51 -07:00
Jakub Vrana
9bfab6a3e3 Convert fields in inline edit 2012-09-09 16:25:25 -07:00
Jakub Vrana
312075d01f Search non-ASCII data only in text columns (bug #3564415) 2012-09-09 11:03:02 -07:00
Jakub Vrana
66d537c150 Apply text length on geometry data 2012-09-09 10:19:07 -07:00
Jakub Vrana
944f141bf4 MySQL: Don't remove partitioning on non-partitioned tables 2012-09-09 00:00:59 -07:00
Jakub Vrana
d5400234f0 MySQL: Support geometry data types 2012-09-08 23:43:22 -07:00
Jakub Vrana
31a608e398 MySQL: Unsupport hex function 2012-09-08 22:39:52 -07:00
Jakub Vrana
aff4d7de91 SQLite: Select primary key column on correct position 2012-09-08 22:13:28 -07:00
Jakub Vrana
dd49dfb4cd Save bytes 2012-09-08 21:54:35 -07:00
Jakub Vrana
d2d104b3b9 Update translation 2012-09-08 21:30:39 -07:00
Jakub Vrana
a0d00cf732 Store database to permanent login 2012-09-08 21:30:30 -07:00
Jakub Vrana
741c073c95 Unset wrong login from permanent logins 2012-09-08 20:54:02 -07:00
Jakub Vrana
de451010b1 Fix SQL query history 2012-09-07 11:54:02 -07:00
Jakub Vrana
8d3afc0eb5 Fix test 2012-09-07 11:36:46 -07:00
Jakub Vrana
63c9873c30 Fix JUSH compilation 2012-09-07 08:38:11 -07:00
Jakub Vrana
dd86e1892d Simplify compile_file() 2012-09-07 08:38:11 -07:00
Jakub Vrana
e767663f65 Compress JS 2012-09-07 08:38:11 -07:00
Jakub Vrana
caa9f490af Compress CSS 2012-09-07 08:38:10 -07:00
Jakub Vrana
415f500f10 Don't use \r\n in compiled strings 2012-09-07 08:37:52 -07:00
Jakub Vrana
0317638e80 Compress each translation separately 2012-09-07 08:31:25 -07:00
Jakub Vrana
ccd1246666 Save translations version 2012-09-07 08:30:32 -07:00
Jakub Vrana
85d985a319 Don't encode binary files 2012-09-07 08:30:31 -07:00
Jakub Vrana
5d257861e1 Compress translations 2012-09-07 08:30:31 -07:00
Jakub Vrana
09d81ffee9 Simplify load more data buffering 2012-09-07 08:21:35 -07:00
Jakub Vrana
b7f1d56fe0 Switch language by POST 2012-09-07 08:21:21 -07:00
Jakub Vrana
195a811466 Simplify switch lang form 2012-09-06 23:15:02 -07:00
Jakub Vrana
4cb14deac1 Open form to a new window on Ctrl+click or Shift+click 2012-09-04 15:40:57 -07:00
Jakub Vrana
541561be4d Minimize space around % 2012-09-03 15:03:55 -07:00
Jakub Vrana
8db73ad7ea Fix typo in translation 2012-09-01 08:47:29 -07:00
Jakub Vrana
d8006df483 Add new methods to plugin 2012-09-01 08:47:16 -07:00
Jakub Vrana
b9eb811e66 Hide import in information_schema 2012-08-29 10:08:18 -07:00
Nikola Radovanović
eb9bd30621 Serbian translation 2012-08-29 10:07:55 -07:00
Jakub Vrana
47e52b6761 Treat performance_schema as information_schema 2012-08-23 22:21:53 -07:00
Jakub Vrana
700a78b377 selectQueryBuild() method 2012-08-23 22:17:44 -07:00
Jakub Vrana
5d337fe04c Reveal menu items only if mouse is over wide links 2012-08-20 22:20:22 -07:00
Jakub Vrana
beafccb8c3 Separate printing databases in customization 2012-08-20 22:03:39 -07:00
Jakub Vrana
364dcfe632 Comment 2012-08-20 20:53:19 -07:00
Jakub Vrana
68211ac42b Don't display Load more data on last page 2012-08-20 08:25:20 -07:00
Jakub Vrana
ef0cb38aa1 Support Editor 2012-08-19 23:31:46 -07:00
Jakub Vrana
ea6d6e0d44 Simplify slow queries 2012-08-19 21:55:00 -07:00
Jakub Vrana
72b801513b Load more data in select 2012-08-19 20:32:53 -07:00
Jakub Vrana
fc689f5953 Fix last page link 2012-08-19 19:55:57 -07:00
Jakub Vrana
6a7021db28 Time out long running select count 2012-08-19 19:42:37 -07:00
Jakub Vrana
1f53cd3386 Time out long running database list 2012-08-19 19:35:11 -07:00
Jakub Vrana
5e0038b62d Improve session management 2012-08-19 13:42:13 -07:00
Jakub Vrana
c9da3ccb51 Display navigation links prior to waiting on DB list 2012-08-19 12:40:49 -07:00
Jakub Vrana
37013522a1 Save bytes 2012-08-19 09:43:31 -07:00
Jakub Vrana
b7af79e745 Display link to refresh with no databases 2012-08-19 09:37:29 -07:00
Jakub Vrana
0da02c5505 Backwards compatible designs 2012-08-15 09:04:08 -07:00
Jakub Vrana
7674576dcb Indicate NULL values in XML export (thanks to Karel Seidl) 2012-08-14 09:12:43 -07:00
Jakub Vrana
2a97e02cdd Update designs 2012-08-12 16:35:53 -07:00
Jan Kosco
bcf7e7e04b Fix haeckel theme for 3.5 adminer 2012-08-12 15:45:51 -07:00
Jakub Vrana
65a8c7dde4 Style logout button as link in Editor 2012-08-11 23:02:56 -07:00
Jakub Vrana
3a381564e5 Use VALUES() in INSERT+UPDATE export 2012-08-11 22:59:20 -07:00
Jakub Vrana
f9cbf50bd7 Export data settings only with data 2012-08-11 22:37:30 -07:00
Jakub Vrana
f0d97a7c7f Edit strings with \n in textarea 2012-08-11 21:45:09 -07:00
Jakub Vrana
98bc4fc4d2 Style logout button as link 2012-08-10 07:06:01 -07:00
Jakub Vrana
2d18afaf7f Release 3.5.1 2012-08-09 22:47:12 -07:00
Jakub Vrana
9a3b3db4f6 Comment 2012-08-09 12:18:31 -07:00
Jakub Vrana
a4e38a266d Remove definer from routine and event 2012-08-09 09:39:12 -07:00
Jakub Vrana
ca32e71e42 Ignore bit type when searching strings 2012-08-09 09:37:51 -07:00
Jakub Vrana
4b4fa16a37 Autodisplay long table names in tables filter plugin 2012-08-09 09:11:55 -07:00
Jakub Vrana
69d49e30c5 Support same name fields in CSV export 2012-08-09 08:57:45 -07:00
Jakub Vrana
7fcfb0d16a Don't include trailing space to delimiter 2012-08-09 08:39:54 -07:00
Jakub Vrana
1501d60f14 Descending order after second click on column caption 2012-08-08 22:40:38 -07:00
Jakub Vrana
e5b1c99d87 Support Shift+click in export 2012-08-08 09:23:46 -07:00
Jakub Vrana
b49061b863 Add JS function for getting parent tag 2012-08-08 09:22:23 -07:00
Jakub Vrana
5fd21e122a Set source checkbox only in click without Shift 2012-08-08 08:54:15 -07:00
Jakub Vrana
b783b9487d Don't display tables list on server pages 2012-08-08 08:41:52 -07:00
Jakub Vrana
99343701ab Autodisplay long logins in saved logins list 2012-08-08 08:27:50 -07:00
Jakub Vrana
c09a147b2e Develop 2012-08-05 09:15:05 -07:00
Jakub Vrana
a0af3eec5c Release 3.5.0 2012-08-04 22:53:20 -07:00
Jakub Vrana
1dd6dbcce2 Support one click search in Editor 2012-08-04 22:52:50 -07:00
Jakub Vrana
95f0a5f0f0 Fix test 2012-08-04 22:34:38 -07:00
Jakub Vrana
335ab7eab2 Done 2012-07-30 00:57:24 -07:00
Jakub Vrana
6a486181dd Autodisplay long table names in tables list 2012-07-29 16:05:37 -07:00
Jakub Vrana
57e5896b55 Autohide column context menu in select 2012-07-29 13:55:39 -07:00
Jakub Vrana
ac668d1331 Treat queries with no limit as full table scans 2012-07-29 13:28:04 -07:00
Jakub Vrana
55831095b6 Warn about grouping data without index 2012-07-29 13:25:59 -07:00
Jakub Vrana
07e2c3b2a4 Save bytes 2012-07-29 11:29:21 -07:00
Jakub Vrana
e2dbb9c7bd Links for column search in select 2012-07-29 11:29:00 -07:00
Jakub Vrana
e8b95f127f SQLite: Display number of rows in database overview 2012-07-29 10:45:38 -07:00
Jakub Vrana
f1153aa35a Display assigned auto_increment after clone 2012-07-27 17:37:20 -07:00
Jakub Vrana
5e4b815893 Highlight also killed queries 2012-07-27 16:08:09 -07:00
Jakub Vrana
a227ec1c97 Don't treat enum in PostgreSQL as special (bug #3545899) 2012-07-21 09:50:50 -07:00
Jakub Vrana
98483e101d SQLite: Better editing in tables without a primary key 2012-07-15 14:55:46 -07:00
Jakub Vrana
c2f95e0054 SQLite: Full alter table 2012-07-15 14:38:45 -07:00
Jakub Vrana
5fb2368b66 Ignore SQLite autoindexes 2012-07-15 12:24:20 -07:00
Jakub Vrana
385fdd45b8 Document trigger type 2012-07-15 12:04:04 -07:00
Jakub Vrana
56cd77f0d1 Save bytes 2012-07-15 10:05:13 -07:00
Jakub Vrana
7291ae608d Reset error before using in SQL query 2012-07-15 09:21:22 -07:00
Jakub Vrana
6a3cf71db5 Develop 2012-06-30 05:26:22 -07:00
46 changed files with 1329 additions and 320 deletions

View File

@@ -23,10 +23,12 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
query_redirect("DROP TABLE " . table($TABLE), substr(ME, 0, -1), lang('Table has been dropped.'));
} else {
$fields = array();
$all_fields = array();
$use_all_fields = false;
$foreign = array();
ksort($_POST["fields"]);
$orig_field = reset($orig_fields);
$after = "FIRST";
$after = " FIRST";
foreach ($_POST["fields"] as $key => $field) {
$foreign_key = $foreign_keys[$field["type"]];
$type_field = ($foreign_key !== null ? $referencable_primary[$foreign_key] : $field); //! can collide with user defined type
@@ -43,18 +45,26 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
$field["auto_increment"] = true;
}
$process_field = process_field($field, $type_field);
$all_fields[] = array($field["orig"], $process_field, $after);
if ($process_field != process_field($orig_field, $orig_field)) {
$fields[] = array($field["orig"], $process_field, $after);
if ($field["orig"] != "" || $after) {
$use_all_fields = true;
}
}
if ($foreign_key !== null) {
$foreign[idf_escape($field["field"])] = ($TABLE != "" ? "ADD" : " ") . " FOREIGN KEY (" . idf_escape($field["field"]) . ") REFERENCES " . table($foreign_keys[$field["type"]]) . " (" . idf_escape($type_field["field"]) . ")" . (ereg("^($on_actions)\$", $field["on_delete"]) ? " ON DELETE $field[on_delete]" : "");
$foreign[idf_escape($field["field"])] = ($TABLE != "" && $jush != "sqlite" ? "ADD" : " ") . " FOREIGN KEY (" . idf_escape($field["field"]) . ") REFERENCES " . table($foreign_keys[$field["type"]]) . " (" . idf_escape($type_field["field"]) . ")" . (ereg("^($on_actions)\$", $field["on_delete"]) ? " ON DELETE $field[on_delete]" : "");
}
$after = "AFTER " . idf_escape($field["field"]);
$after = " AFTER " . idf_escape($field["field"]);
} elseif ($field["orig"] != "") {
$use_all_fields = true;
$fields[] = array($field["orig"]);
}
if ($field["orig"] != "") {
$orig_field = next($orig_fields);
if (!$orig_field) {
$after = "";
}
}
}
$partitioning = "";
@@ -70,7 +80,7 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
? " (" . implode(",", $partitions) . "\n)"
: ($_POST["partitions"] ? " PARTITIONS " . (+$_POST["partitions"]) : "")
);
} elseif ($TABLE != "" && support("partitioning")) {
} elseif (support("partitioning") && ereg("partitioned", $orig_status["Create_options"])) {
$partitioning .= "\nREMOVE PARTITIONING";
}
$message = lang('Table has been altered.');
@@ -82,7 +92,7 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"] && !$_POST["up"]
queries_redirect(ME . "table=" . urlencode($name), $message, alter_table(
$TABLE,
$name,
$fields,
($jush == "sqlite" && ($use_all_fields || $foreign) ? $all_fields : $fields),
$foreign,
$_POST["Comment"],
($_POST["Engine"] && $_POST["Engine"] != $orig_status["Engine"] ? $_POST["Engine"] : ""),

View File

@@ -43,6 +43,7 @@ if (isset($_GET["mssql"])) {
function query($query, $unbuffered = false) {
$result = sqlsrv_query($this->_link, $query); //! , array(), ($unbuffered ? array() : array("Scrollable" => "keyset"))
$this->error = "";
if (!$result) {
$this->_get_error();
return false;
@@ -52,6 +53,7 @@ if (isset($_GET["mssql"])) {
function multi_query($query) {
$this->_result = sqlsrv_query($this->_link, $query);
$this->error = "";
if (!$this->_result) {
$this->_get_error();
return false;
@@ -159,6 +161,7 @@ if (isset($_GET["mssql"])) {
function query($query, $unbuffered = false) {
$result = mssql_query($query, $this->_link); //! $unbuffered
$this->error = "";
if (!$result) {
$this->error = mssql_get_last_message();
return false;
@@ -588,6 +591,13 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)
return array();
}
function convert_field($field) {
}
function unconvert_field($field, $return) {
return $return;
}
function support($feature) {
return ereg('^(scheme|trigger|view|drop_col)$', $feature); //! routine|
}

View File

@@ -108,6 +108,7 @@ if (!defined("DRIVER")) {
*/
function query($query, $unbuffered = false) {
$result = @($unbuffered ? mysql_unbuffered_query($query, $this->_link) : mysql_query($query, $this->_link)); // @ - mute mysql.trace_mode
$this->error = "";
if (!$result) {
$this->error = mysql_error($this->_link);
return false;
@@ -264,17 +265,19 @@ if (!defined("DRIVER")) {
* @param bool
* @return array
*/
function get_databases($flush = true) {
function get_databases($flush) {
global $connection;
// SHOW DATABASES can take a very long time so it is cached
$return = &get_session("dbs");
$return = get_session("dbs");
if ($return === null) {
if ($flush) {
restart_session();
ob_flush();
flush();
}
$return = get_vals($connection->server_info >= 5 ? "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA" : "SHOW DATABASES"); // SHOW DATABASES can be disabled by skip_show_database
$query = ($connection->server_info >= 5
? "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA"
: "SHOW DATABASES"
); // SHOW DATABASES can be disabled by skip_show_database
$return = ($flush ? slow_query($query) : get_vals($query));
restart_session();
set_session("dbs", $return);
stop_session();
}
return $return;
}
@@ -499,7 +502,8 @@ if (!defined("DRIVER")) {
*/
function information_schema($db) {
global $connection;
return ($connection->server_info >= 5 && $db == "information_schema");
return ($connection->server_info >= 5 && $db == "information_schema")
|| ($connection->server_info >= 5.5 && $db == "performance_schema");
}
/** Get escaped error message
@@ -602,7 +606,7 @@ if (!defined("DRIVER")) {
$alter = array();
foreach ($fields as $field) {
$alter[] = ($field[1]
? ($table != "" ? ($field[0] != "" ? "CHANGE " . idf_escape($field[0]) : "ADD") : " ") . " " . implode($field[1]) . ($table != "" ? " $field[2]" : "")
? ($table != "" ? ($field[0] != "" ? "CHANGE " . idf_escape($field[0]) : "ADD") : " ") . " " . implode($field[1]) . ($table != "" ? $field[2] : "")
: "DROP " . idf_escape($field[0])
);
}
@@ -708,7 +712,7 @@ if (!defined("DRIVER")) {
/** Get information about trigger
* @param string trigger name
* @return array array("Trigger" => , "Timing" => , "Event" => , "Statement" => )
* @return array array("Trigger" => , "Timing" => , "Event" => , "Type" => , "Statement" => )
*/
function trigger($name) {
if ($name == "") {
@@ -942,6 +946,34 @@ if (!defined("DRIVER")) {
return get_key_vals("SHOW STATUS");
}
/** Convert field in select and edit
* @param array one element from fields()
* @return string
*/
function convert_field($field) {
if (ereg("binary", $field["type"])) {
return "HEX(" . idf_escape($field["field"]) . ")";
}
if (ereg("geometry|point|linestring|polygon", $field["type"])) {
return "AsWKT(" . idf_escape($field["field"]) . ")";
}
}
/** Convert value in edit after applying functions back
* @param array one element from fields()
* @param string
* @return string
*/
function unconvert_field($field, $return) {
if (ereg("binary", $field["type"])) {
$return = "unhex($return)";
}
if (ereg("geometry|point|linestring|polygon", $field["type"])) {
$return = "GeomFromText($return)";
}
return $return;
}
/** Check whether a feature is supported
* @param string "comment", "copy", "drop_col", "dump", "event", "kill", "partitioning", "privileges", "procedure", "processlist", "routine", "scheme", "sequence", "status", "trigger", "type", "variables", "view"
* @return bool
@@ -958,23 +990,24 @@ if (!defined("DRIVER")) {
lang('Numbers') => array("tinyint" => 3, "smallint" => 5, "mediumint" => 8, "int" => 10, "bigint" => 20, "decimal" => 66, "float" => 12, "double" => 21),
lang('Date and time') => array("date" => 10, "datetime" => 19, "timestamp" => 19, "time" => 10, "year" => 4),
lang('Strings') => array("char" => 255, "varchar" => 65535, "tinytext" => 255, "text" => 65535, "mediumtext" => 16777215, "longtext" => 4294967295),
lang('Binary') => array("bit" => 20, "binary" => 255, "varbinary" => 65535, "tinyblob" => 255, "blob" => 65535, "mediumblob" => 16777215, "longblob" => 4294967295),
lang('Lists') => array("enum" => 65535, "set" => 64),
lang('Binary') => array("bit" => 20, "binary" => 255, "varbinary" => 65535, "tinyblob" => 255, "blob" => 65535, "mediumblob" => 16777215, "longblob" => 4294967295),
lang('Geometry') => array("geometry" => 0, "point" => 0, "linestring" => 0, "polygon" => 0, "multipoint" => 0, "multilinestring" => 0, "multipolygon" => 0, "geometrycollection" => 0),
) as $key => $val) {
$types += $val;
$structured_types[$key] = array_keys($val);
}
$unsigned = array("unsigned", "zerofill", "unsigned zerofill"); ///< @var array number variants
$operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", ""); ///< @var array operators used in select
$functions = array("char_length", "date", "from_unixtime", "hex", "lower", "round", "sec_to_time", "time_to_sec", "upper"); ///< @var array functions used in select
$functions = array("char_length", "date", "from_unixtime", "lower", "round", "sec_to_time", "time_to_sec", "upper"); ///< @var array functions used in select
$grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"); ///< @var array grouping functions used in select
$edit_functions = array( ///< @var array of array("$type|$type2" => "$function/$function2") functions used in editing, [0] - edit and insert, [1] - edit only
array(
"char" => "md5/sha1/password/encrypt/uuid", //! JavaScript for disabling maxlength
"binary" => "md5/sha1/hex",
"binary" => "md5/sha1",
"date|time" => "now",
), array(
"int|float|double|decimal" => "+/-",
"(^|[^o])int|float|double|decimal" => "+/-", // not point
"date" => "+ interval/- interval",
"time" => "addtime/subtime",
"char|text" => "concat",

View File

@@ -37,6 +37,7 @@ if (isset($_GET["oracle"])) {
function query($query, $unbuffered = false) {
$result = oci_parse($this->_link, $query);
$this->error = "";
if (!$result) {
$error = oci_error($this->_link);
$this->error = $error["message"];
@@ -360,6 +361,13 @@ ORDER BY PROCESS
return reset($rows);
}
function convert_field($field) {
}
function unconvert_field($field, $return) {
return $return;
}
function support($feature) {
return ereg("view|scheme|processlist|drop_col|variables|status", $feature); //!
}

View File

@@ -58,6 +58,7 @@ if (isset($_GET["pgsql"])) {
function query($query, $unbuffered = false) {
$result = @pg_query($this->_link, $query);
$this->error = "";
if (!$result) {
$this->error = pg_last_error($this->_link);
return false;
@@ -579,6 +580,13 @@ AND typelem = 0"
function show_status() {
}
function convert_field($field) {
}
function unconvert_field($field, $return) {
return $return;
}
function support($feature) {
return ereg('^(comment|view|scheme|processlist|sequence|trigger|type|variables|drop_col)$', $feature); //! routine|
}

View File

@@ -19,6 +19,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
function query($query) {
$result = @$this->_link->query($query);
$this->error = "";
if (!$result) {
$this->error = $this->_link->lastErrorMsg();
return false;
@@ -93,6 +94,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
function query($query, $unbuffered = false) {
$method = ($unbuffered ? "unbufferedQuery" : "query");
$result = @$this->_link->$method($query, SQLITE_BOTH, $error);
$this->error = "";
if (!$result) {
$this->error = $error;
return false;
@@ -248,9 +250,12 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
}
function table_status($name = "") {
global $connection;
$return = array();
foreach (get_rows("SELECT name AS Name, type AS Engine FROM sqlite_master WHERE type IN ('table', 'view')" . ($name != "" ? " AND name = " . q($name) : "")) as $row) {
$row["Oid"] = "t";
$row["Auto_increment"] = "";
$row["Rows"] = $connection->result("SELECT COUNT(*) FROM " . idf_escape($row["Name"]));
$return[$row["Name"]] = $row;
}
foreach (get_rows("SELECT * FROM sqlite_sequence", null, "") as $row) {
@@ -265,7 +270,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
function fk_support($table_status) {
global $connection;
return $_GET["create"] == "" && !$connection->result("SELECT sqlite_compileoption_used('OMIT_FOREIGN_KEY')");
return !$connection->result("SELECT sqlite_compileoption_used('OMIT_FOREIGN_KEY')");
}
function fields($table) {
@@ -299,10 +304,12 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
$return[""] = array("type" => "PRIMARY", "columns" => $primary, "lengths" => array());
}
foreach (get_rows("PRAGMA index_list(" . table($table) . ")") as $row) {
$return[$row["name"]]["type"] = ($row["unique"] ? "UNIQUE" : "INDEX");
$return[$row["name"]]["lengths"] = array();
foreach (get_rows("PRAGMA index_info(" . idf_escape($row["name"]) . ")") as $row1) {
$return[$row["name"]]["columns"][] = $row1["name"];
if (!ereg("^sqlite_", $row["name"])) {
$return[$row["name"]]["type"] = ($row["unique"] ? "UNIQUE" : "INDEX");
$return[$row["name"]]["lengths"] = array();
foreach (get_rows("PRAGMA index_info(" . idf_escape($row["name"]) . ")") as $row1) {
$return[$row["name"]]["columns"][] = $row1["name"];
}
}
}
return $return;
@@ -398,14 +405,90 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
}
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
$alter = array();
$use_all_fields = ($table == "" || $foreign);
foreach ($fields as $field) {
if ($field[1]) {
$alter[] = ($table != "" && $field[0] == "" ? "ADD " : " ") . implode($field[1]);
if ($field[0] != "" || !$field[1] || $field[2]) {
$use_all_fields = true;
break;
}
}
$alter = array_merge($alter, $foreign);
if ($table != "") {
$alter = array();
$originals = array();
$primary_key = false;
foreach ($fields as $field) {
if ($field[1]) {
if ($field[1][6]) {
$primary_key = true;
}
$alter[] = ($use_all_fields ? " " : "ADD ") . implode($field[1]);
if ($field[0] != "") {
$originals[$field[0]] = $field[1][0];
}
}
}
if ($use_all_fields) {
if ($table != "") {
queries("BEGIN");
foreach (foreign_keys($table) as $foreign_key) {
$columns = array();
foreach ($foreign_key["source"] as $column) {
if (!$originals[$column]) {
continue 2;
}
$columns[] = $originals[$column];
}
$foreign[] = " FOREIGN KEY (" . implode(", ", $columns) . ") REFERENCES "
. table($foreign_key["table"])
. " (" . implode(", ", array_map('idf_escape', $foreign_key["target"]))
. ") ON DELETE $foreign_key[on_delete] ON UPDATE $foreign_key[on_update]"
;
}
$indexes = array();
foreach (indexes($table) as $key_name => $index) {
$columns = array();
foreach ($index["columns"] as $column) {
if (!$originals[$column]) {
continue 2;
}
$columns[] = $originals[$column];
}
$columns = "(" . implode(", ", $columns) . ")";
if ($index["type"] != "PRIMARY") {
$indexes[] = array($index["type"], $key_name, $columns);
} elseif (!$primary_key) {
$foreign[] = " PRIMARY KEY $columns";
}
}
}
$alter = array_merge($alter, $foreign);
if (!queries("CREATE TABLE " . table($table != "" ? "adminer_$name" : $name) . " (\n" . implode(",\n", $alter) . "\n)")) {
// implicit ROLLBACK to not overwrite $connection->error
return false;
}
if ($table != "") {
if ($originals && !queries("INSERT INTO " . table("adminer_$name") . " (" . implode(", ", $originals) . ") SELECT " . implode(", ", array_map('idf_escape', array_keys($originals))) . " FROM " . table($table))) {
return false;
}
$triggers = array();
foreach (triggers($table) as $trigger_name => $timing_event) {
$trigger = trigger($trigger_name);
$triggers[] = "CREATE TRIGGER " . idf_escape($trigger_name) . " " . implode(" ", $timing_event) . " ON " . table($name) . "\n$trigger[Statement]";
}
if (!queries("DROP TABLE " . table($table))) { // drop before creating indexes and triggers to allow using old names
return false;
}
queries("ALTER TABLE " . table("adminer_$name") . " RENAME TO " . table($name));
if (!alter_indexes($name, $indexes)) {
return false;
}
foreach ($triggers as $trigger) {
if (!queries($trigger)) {
return false;
}
}
queries("COMMIT");
}
} else {
foreach ($alter as $val) {
if (!queries("ALTER TABLE " . table($table) . " $val")) {
return false;
@@ -414,8 +497,6 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
if ($table != $name && !queries("ALTER TABLE " . table($table) . " RENAME TO " . table($name))) {
return false;
}
} elseif (!queries("CREATE TABLE " . table($name) . " (\n" . implode(",\n", $alter) . "\n)")) {
return false;
}
if ($auto_increment) {
queries("UPDATE sqlite_sequence SET seq = $auto_increment WHERE name = " . q($name)); // ignores error
@@ -562,8 +643,15 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return $return;
}
function convert_field($field) {
}
function unconvert_field($field, $return) {
return $return;
}
function support($feature) {
return ereg('^(view|trigger|variables|status|dump)$', $feature);
return ereg('^(view|trigger|variables|status|dump|move_col|drop_col)$', $feature);
}
$jush = "sqlite";

View File

@@ -13,10 +13,10 @@ if ($_POST) {
echo "-- Adminer $VERSION " . $drivers[DRIVER] . " dump
" . ($jush != "sql" ? "" : "SET NAMES utf8;
SET foreign_key_checks = 0;
" . ($_POST["data_style"] ? "SET foreign_key_checks = 0;
SET time_zone = " . q($connection->result("SELECT @@time_zone")) . ";
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
" : "") . "
");
}
@@ -48,14 +48,14 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
foreach (array("FUNCTION", "PROCEDURE") as $routine) {
foreach (get_rows("SHOW $routine STATUS WHERE Db = " . q($db), null, "-- ") as $row) {
$out .= ($style != 'DROP+CREATE' ? "DROP $routine IF EXISTS " . idf_escape($row["Name"]) . ";;\n" : "")
. $connection->result("SHOW CREATE $routine " . idf_escape($row["Name"]), 2) . ";;\n\n";
. remove_definer($connection->result("SHOW CREATE $routine " . idf_escape($row["Name"]), 2)) . ";;\n\n";
}
}
}
if ($_POST["events"]) {
foreach (get_rows("SHOW EVENTS", null, "-- ") as $row) {
$out .= ($style != 'DROP+CREATE' ? "DROP EVENT IF EXISTS " . idf_escape($row["Name"]) . ";;\n" : "")
. $connection->result("SHOW CREATE EVENT " . idf_escape($row["Name"]), 3) . ";;\n\n";
. remove_definer($connection->result("SHOW CREATE EVENT " . idf_escape($row["Name"]), 3)) . ";;\n\n";
}
}
if ($out) {
@@ -197,11 +197,11 @@ if (DB != "") {
$name = $table_status["Name"];
$prefix = ereg_replace("_.*", "", $name);
$checked = ($TABLE == "" || $TABLE == (substr($TABLE, -1) == "%" ? "$prefix%" : $name)); //! % may be part of table name
$print = "<tr><td>" . checkbox("tables[]", $name, $checked, $name, "formUncheck('check-tables');");
$print = "<tr><td>" . checkbox("tables[]", $name, $checked, $name, "checkboxClick(event, this); formUncheck('check-tables');");
if (is_view($table_status)) {
$views .= "$print\n";
} else {
echo "$print<td align='right'><label>" . ($table_status["Engine"] == "InnoDB" && $table_status["Rows"] ? "~ " : "") . $table_status["Rows"] . checkbox("data[]", $name, $checked, "", "formUncheck('check-data');") . "</label>\n";
echo "$print<td align='right'><label>" . ($table_status["Engine"] == "InnoDB" && $table_status["Rows"] ? "~ " : "") . $table_status["Rows"] . checkbox("data[]", $name, $checked, "", "checkboxClick(event, this); formUncheck('check-data');") . "</label>\n";
}
$prefixes[$prefix]++;
}

View File

@@ -53,7 +53,14 @@ if ($_POST["save"]) {
$select = array();
foreach ($fields as $name => $field) {
if (isset($field["privileges"]["select"])) {
$select[] = ($_POST["clone"] && $field["auto_increment"] ? "'' AS " : (ereg("enum|set", $field["type"]) ? "1*" . idf_escape($name) . " AS " : "")) . idf_escape($name);
$as = convert_field($field);
if ($_POST["clone"] && $field["auto_increment"]) {
$as = "''";
}
if ($jush == "sql" && ereg("enum|set", $field["type"])) {
$as = "1*" . idf_escape($name);
}
$select[] = ($as ? "$as AS " : "") . idf_escape($name);
}
}
$row = array();
@@ -76,7 +83,7 @@ if ($fields) {
echo "<tr><th>" . $adminer->fieldName($field);
$default = $_GET["set"][bracket_escape($name)];
$value = ($row !== null
? ($row[$name] != "" && ereg("enum|set", $field["type"]) ? (is_array($row[$name]) ? array_sum($row[$name]) : +$row[$name]) : $row[$name])
? ($row[$name] != "" && $jush == "sql" && ereg("enum|set", $field["type"]) ? (is_array($row[$name]) ? array_sum($row[$name]) : +$row[$name]) : $row[$name])
: (!$update && $field["auto_increment"] ? "" : (isset($_GET["select"]) ? false : ($default !== null ? $default : $field["default"])))
);
if (!$_POST["save"] && is_string($value)) {

View File

@@ -1,23 +1,29 @@
<?php
if ($_SERVER["HTTP_IF_MODIFIED_SINCE"]) {
header("HTTP/1.1 304 Not Modified");
exit;
}
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 365*24*60*60) . " GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
if ($_GET["file"] == "favicon.ico") {
header("Content-Type: image/x-icon");
echo base64_decode("compile_file('../adminer/static/favicon.ico', 'base64_encode');");
echo compile_file('../adminer/static/favicon.ico');
} elseif ($_GET["file"] == "default.css") {
header("Content-Type: text/css; charset=utf-8");
?>compile_file('../adminer/static/default.css', 'minify_css');<?php
echo lzw_decompress(compile_file('../adminer/static/default.css', 'minify_css'));
} elseif ($_GET["file"] == "functions.js") {
header("Content-Type: text/javascript; charset=utf-8");
?>compile_file('../adminer/static/functions.js', 'jsShrink');compile_file('static/editing.js', 'jsShrink');<?php
echo lzw_decompress(compile_file('../adminer/static/functions.js;static/editing.js', 'minify_js'));
} else {
header("Content-Type: image/gif");
switch ($_GET["file"]) {
case "plus.gif": echo base64_decode("compile_file('../adminer/static/plus.gif', 'base64_encode');"); break;
case "cross.gif": echo base64_decode("compile_file('../adminer/static/cross.gif', 'base64_encode');"); break;
case "up.gif": echo base64_decode("compile_file('../adminer/static/up.gif', 'base64_encode');"); break;
case "down.gif": echo base64_decode("compile_file('../adminer/static/down.gif', 'base64_encode');"); break;
case "arrow.gif": echo base64_decode("compile_file('../adminer/static/arrow.gif', 'base64_encode');"); break;
case "plus.gif": echo compile_file('../adminer/static/plus.gif'); break;
case "cross.gif": echo compile_file('../adminer/static/cross.gif'); break;
case "up.gif": echo compile_file('../adminer/static/up.gif'); break;
case "down.gif": echo compile_file('../adminer/static/down.gif'); break;
case "arrow.gif": echo compile_file('../adminer/static/arrow.gif'); break;
}
}
exit;

View File

@@ -42,6 +42,13 @@ class Adminer {
return get_databases($flush);
}
/** Specify limit for waiting on some slow queries like DB list
* @return float number of seconds
*/
function queryTimeout() {
return 5;
}
/** Headers to send before HTML output
* @return bool true to send security headers
*/
@@ -198,7 +205,7 @@ username.form['auth[driver]'].onchange();
* @return string
*/
function editVal($val, $field) {
return (ereg("binary", $field["type"]) ? reset(unpack("H*", $val)) : $val);
return $val;
}
/** Print columns box in select
@@ -214,7 +221,7 @@ username.form['auth[driver]'].onchange();
foreach ($select as $key => $val) {
$val = $_GET["columns"][$key];
echo "<div>" . html_select("columns[$i][fun]", array(-1 => "") + $fun_group, $val["fun"]);
echo "(<select name='columns[$i][col]'><option>" . optionlist($columns, $val["col"], true) . "</select>)</div>\n";
echo "(<select name='columns[$i][col]' onchange='selectFieldChange(this.form);'><option>" . optionlist($columns, $val["col"], true) . "</select>)</div>\n";
$i++;
}
echo "<div>" . html_select("columns[$i][fun]", array(-1 => "") + $fun_group, "", "this.nextSibling.nextSibling.onchange();");
@@ -279,7 +286,7 @@ username.form['auth[driver]'].onchange();
*/
function selectLimitPrint($limit) {
echo "<fieldset><legend>" . lang('Limit') . "</legend><div>"; // <div> for easy styling
echo "<input name='limit' size='3' value='" . h($limit) . "'>";
echo "<input name='limit' size='3' value='" . h($limit) . "' onchange='selectFieldChange(this.form);'>";
echo "</div></fieldset>\n";
}
@@ -332,7 +339,7 @@ username.form['auth[driver]'].onchange();
* @return bool whether to print default import
*/
function selectImportPrint() {
return true;
return !information_schema(DB);
}
/** Print extra text in the end of a select form
@@ -395,9 +402,12 @@ username.form['auth[driver]'].onchange();
// find anywhere
$cols = array();
foreach ($fields as $name => $field) {
if (is_numeric($val["val"]) || !ereg('int|float|double|decimal', $field["type"])) {
$is_text = ereg('char|text|enum|set', $field["type"]);
if ((is_numeric($val["val"]) || !ereg('int|float|double|decimal|bit', $field["type"]))
&& (!ereg("[\x80-\xFF]", $val["val"]) || $is_text)
) {
$name = idf_escape($name);
$cols[] = ($jush == "sql" && ereg('char|text|enum|set', $field["type"]) && !ereg('^utf8', $field["collation"]) ? "CONVERT($name USING utf8)" : $name);
$cols[] = ($jush == "sql" && $is_text && !ereg('^utf8', $field["collation"]) ? "CONVERT($name USING utf8)" : $name);
}
}
$return[] = ($cols ? "(" . implode("$cond OR ", $cols) . "$cond)" : "0");
@@ -445,6 +455,19 @@ username.form['auth[driver]'].onchange();
return false;
}
/** Build SQL query used in select
* @param array result of selectColumnsProcess()[0]
* @param array result of selectSearchProcess()
* @param array result of selectColumnsProcess()[1]
* @param array result of selectOrderProcess()
* @param int result of selectLimitProcess()
* @param int index of page starting at zero
* @return string empty string to use default query
*/
function selectQueryBuild($select, $where, $group, $order, $limit, $page) {
return "";
}
/** Query printed after execution in the message
* @param string executed query
* @return string
@@ -523,13 +546,10 @@ username.form['auth[driver]'].onchange();
$return = idf_escape($name) . " $function " . (preg_match("~^(\\d+|'[0-9.: -]') [A-Z_]+$~i", $value) ? $value : $return);
} elseif (ereg('^(addtime|subtime|concat)$', $function)) {
$return = "$function(" . idf_escape($name) . ", $return)";
} elseif (ereg('^(md5|sha1|password|encrypt|hex)$', $function)) {
} elseif (ereg('^(md5|sha1|password|encrypt)$', $function)) {
$return = "$function($return)";
}
if (ereg("binary", $field["type"])) {
$return = "unhex($return)";
}
return $return;
return unconvert_field($field, $return);
}
/** Returns export output options
@@ -573,8 +593,7 @@ username.form['auth[driver]'].onchange();
echo "DROP " . ($is_view ? "VIEW" : "TABLE") . " IF EXISTS " . table($table) . ";\n";
}
if ($is_view) {
// remove DEFINER with current user
$create = preg_replace('~^([A-Z =]+) DEFINER=`' . preg_replace('~@(.*)~', '`@`(%|\\1)', logged_user()) . '`~', '\\1', $create); //! proper escaping of user
$create = remove_definer($create);
}
echo ($style != "CREATE+ALTER" ? $create : ($is_view ? substr_replace($create, " OR REPLACE", 6, 0) : substr_replace($create, " IF NOT EXISTS", 12, 0))) . ";\n\n";
}
@@ -672,43 +691,45 @@ DROP PROCEDURE adminer_alter;
if ($result) {
$insert = "";
$buffer = "";
while ($row = $result->fetch_assoc()) {
$keys = array();
$suffix = "";
while ($row = $result->fetch_row()) {
if (!$keys) {
$values = array();
foreach ($row as $val) {
$field = $result->fetch_field();
$keys[] = $field->name;
$key = idf_escape($field->name);
$values[] = "$key = VALUES($key)";
}
$suffix = ($style == "INSERT+UPDATE" ? "\nON DUPLICATE KEY UPDATE " . implode(", ", $values) : "") . ";\n";
}
if ($_POST["format"] != "sql") {
if ($style == "table") {
dump_csv(array_keys($row));
dump_csv($keys);
$style = "INSERT";
}
dump_csv($row);
} else {
if (!$insert) {
$insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('idf_escape', array_keys($row))) . ") VALUES";
$insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('idf_escape', $keys)) . ") VALUES";
}
foreach ($row as $key => $val) {
$row[$key] = ($val !== null ? (ereg('int|float|double|decimal|bit', $fields[$key]["type"]) ? $val : q($val)) : "NULL"); //! columns looking like functions
$row[$key] = ($val !== null ? (ereg('int|float|double|decimal|bit', $fields[$keys[$key]]["type"]) ? $val : q($val)) : "NULL"); //! columns looking like functions
}
$s = implode(",\t", $row);
if ($style == "INSERT+UPDATE") {
$set = array();
foreach ($row as $key => $val) {
$set[] = idf_escape($key) . " = $val";
}
echo "$insert ($s) ON DUPLICATE KEY UPDATE " . implode(", ", $set) . ";\n";
$s = ($max_packet ? "\n" : " ") . "(" . implode(",\t", $row) . ")";
if (!$buffer) {
$buffer = $insert . $s;
} elseif (strlen($buffer) + 4 + strlen($s) + strlen($suffix) < $max_packet) { // 4 - length specification
$buffer .= ",$s";
} else {
$s = ($max_packet ? "\n" : " ") . "($s)";
if (!$buffer) {
$buffer = $insert . $s;
} elseif (strlen($buffer) + 4 + strlen($s) < $max_packet) { // 4 - length specification
$buffer .= ",$s";
} else {
echo "$buffer;\n";
$buffer = $insert . $s;
}
echo $buffer . $suffix;
$buffer = $insert . $s;
}
}
}
if ($_POST["format"] == "sql" && $style != "INSERT+UPDATE" && $buffer) {
$buffer .= ";\n";
echo $buffer;
if ($buffer) {
echo $buffer . $suffix;
}
} elseif ($_POST["format"] == "sql") {
echo "-- " . str_replace("\n", " ", $connection->error) . "\n";
@@ -763,7 +784,7 @@ DROP PROCEDURE adminer_alter;
* @return null
*/
function navigation($missing) {
global $VERSION, $connection, $token, $jush, $drivers;
global $VERSION, $token, $jush, $drivers;
?>
<h1>
<?php echo $this->name(); ?> <span class="version"><?php echo $VERSION; ?></span>
@@ -777,16 +798,18 @@ DROP PROCEDURE adminer_alter;
foreach ($usernames as $username => $password) {
if ($password !== null) {
if ($first) {
echo "<p>\n";
echo "<p id='logins' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
$first = false;
}
echo "<a href='" . h(auth_url($driver, $server, $username)) . "'>($drivers[$driver]) " . h($username . ($server != "" ? "@$server" : "")) . "</a><br>\n";
$dbs = $_SESSION["db"][$driver][$server][$username];
foreach (($dbs ? array_keys($dbs) : array("")) as $db) {
echo "<a href='" . h(auth_url($driver, $server, $username, $db)) . "'>($drivers[$driver]) " . h($username . ($server != "" ? "@$server" : "") . ($db != "" ? " - $db" : "")) . "</a><br>\n";
}
}
}
}
}
} else {
$databases = $this->databases();
?>
<form action="" method="post">
<p class="logout">
@@ -798,49 +821,61 @@ DROP PROCEDURE adminer_alter;
}
}
?>
<input type="submit" name="logout" value="<?php echo lang('Logout'); ?>">
<input type="submit" name="logout" value="<?php echo lang('Logout'); ?>" id="logout">
<input type="hidden" name="token" value="<?php echo $token; ?>">
</p>
</form>
<?php
$this->databasesPrint($missing);
if ($_GET["ns"] !== "" && !$missing && DB != "") {
echo '<p><a href="' . h(ME) . 'create="' . bold($_GET["create"] === "") . ">" . lang('Create new table') . "</a>\n";
$tables = tables_list();
if (!$tables) {
echo "<p class='message'>" . lang('No tables.') . "\n";
} else {
$this->tablesPrint($tables);
$links = array();
foreach ($tables as $table => $type) {
$links[] = preg_quote($table, '/');
}
echo "<script type='text/javascript'>\n";
echo "var jushLinks = { $jush: [ '" . js_escape(ME) . "table=\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n";
foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) {
echo "jushLinks.$val = jushLinks.$jush;\n";
}
echo "</script>\n";
}
}
}
}
/** Prints databases list in menu
* @param string
* @return null
*/
function databasesPrint($missing) {
global $connection;
$databases = $this->databases();
?>
<form action="">
<p>
<p id="dbs">
<?php hidden_fields_get(); ?>
<?php echo ($databases ? html_select("db", array("" => "(" . lang('database') . ")") + $databases, DB, "this.form.submit();") : '<input name="db" value="' . h(DB) . '">'); ?>
<input type="submit" value="<?php echo lang('Use'); ?>"<?php echo ($databases ? " class='hidden'" : ""); ?>>
<?php
if ($missing != "db" && DB != "" && $connection->select_db(DB)) {
if (support("scheme")) {
echo "<br>" . html_select("ns", array("" => "(" . lang('schema') . ")") + schemas(), $_GET["ns"], "this.form.submit();");
if ($_GET["ns"] != "") {
set_schema($_GET["ns"]);
}
}
if ($_GET["ns"] !== "" && !$missing) {
echo '<p><a href="' . h(ME) . 'create="' . bold($_GET["create"] === "") . ">" . lang('Create new table') . "</a>\n";
$tables = tables_list();
if (!$tables) {
echo "<p class='message'>" . lang('No tables.') . "\n";
} else {
$this->tablesPrint($tables);
$links = array();
foreach ($tables as $table => $type) {
$links[] = preg_quote($table, '/');
}
echo "<script type='text/javascript'>\n";
echo "var jushLinks = { $jush: [ '" . js_escape(ME) . "table=\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n";
foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) {
echo "jushLinks.$val = jushLinks.$jush;\n";
}
echo "</script>\n";
}
if ($missing != "db" && DB != "" && $connection->select_db(DB)) {
if (support("scheme")) {
echo "<br>" . html_select("ns", array("" => "(" . lang('schema') . ")") + schemas(), $_GET["ns"], "this.form.submit();");
if ($_GET["ns"] != "") {
set_schema($_GET["ns"]);
}
}
echo (isset($_GET["sql"]) ? '<input type="hidden" name="sql" value="">'
: (isset($_GET["schema"]) ? '<input type="hidden" name="schema" value="">'
: (isset($_GET["dump"]) ? '<input type="hidden" name="dump" value="">'
: "")));
echo "</p></form>\n";
}
echo (isset($_GET["sql"]) ? '<input type="hidden" name="sql" value="">'
: (isset($_GET["schema"]) ? '<input type="hidden" name="schema" value="">'
: (isset($_GET["dump"]) ? '<input type="hidden" name="dump" value="">'
: "")));
echo "</p></form>\n";
}
/** Prints table list in menu
@@ -848,7 +883,7 @@ DROP PROCEDURE adminer_alter;
* @return null
*/
function tablesPrint($tables) {
echo "<p id='tables'>\n";
echo "<p id='tables' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
foreach ($tables as $table => $type) {
echo '<a href="' . h(ME) . 'select=' . urlencode($table) . '"' . bold($_GET["select"] == $table) . ">" . lang('select') . "</a> ";
echo '<a href="' . h(ME) . 'table=' . urlencode($table) . '"' . bold($_GET["table"] == $table) . " title='" . lang('Show structure') . "'>" . $this->tableName(array("Name" => $table)) . "</a><br>\n"; //! Adminer::tableName may work with full table status

View File

@@ -18,8 +18,9 @@ $auth = $_POST["auth"];
if ($auth) {
session_regenerate_id(); // defense against session fixation
$_SESSION["pwds"][$auth["driver"]][$auth["server"]][$auth["username"]] = $auth["password"];
$_SESSION["db"][$auth["driver"]][$auth["server"]][$auth["username"]][$auth["db"]] = true;
if ($auth["permanent"]) {
$key = base64_encode($auth["driver"]) . "-" . base64_encode($auth["server"]) . "-" . base64_encode($auth["username"]);
$key = base64_encode($auth["driver"]) . "-" . base64_encode($auth["server"]) . "-" . base64_encode($auth["username"]) . "-" . base64_encode($auth["db"]);
$private = $adminer->permanentLogin();
$permanent[$key] = "$key:" . base64_encode($private ? encrypt_string($auth["password"], $private) : "");
cookie("adminer_permanent", implode(" ", $permanent));
@@ -38,14 +39,10 @@ if ($auth) {
page_footer("db");
exit;
} else {
foreach (array("pwds", "dbs", "queries") as $key) {
foreach (array("pwds", "db", "dbs", "queries") as $key) {
set_session($key, null);
}
$key = base64_encode(DRIVER) . "-" . base64_encode(SERVER) . "-" . base64_encode($_GET["username"]);
if ($permanent[$key]) {
unset($permanent[$key]);
cookie("adminer_permanent", implode(" ", $permanent));
}
unset_permanent();
redirect(substr(preg_replace('~(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.'));
}
} elseif ($permanent && !$_SESSION["pwds"]) {
@@ -53,11 +50,23 @@ if ($auth) {
$private = $adminer->permanentLogin(); // try to decode even if not set
foreach ($permanent as $key => $val) {
list(, $cipher) = explode(":", $val);
list($driver, $server, $username) = array_map('base64_decode', explode("-", $key));
list($driver, $server, $username, $db) = array_map('base64_decode', explode("-", $key));
$_SESSION["pwds"][$driver][$server][$username] = decrypt_string(base64_decode($cipher), $private);
$_SESSION["db"][$driver][$server][$username][$db] = true;
}
}
function unset_permanent() {
global $permanent;
foreach ($permanent as $key => $val) {
list($driver, $server, $username) = array_map('base64_decode', explode("-", $key));
if ($driver == DRIVER && $server == SERVER && $db == $_GET["username"]) {
unset($permanent[$key]);
}
}
cookie("adminer_permanent", implode(" ", $permanent));
}
function auth_error($exception = null) {
global $connection, $adminer, $token;
$session_name = session_name();
@@ -73,6 +82,7 @@ function auth_error($exception = null) {
$error = h($exception ? $exception->getMessage() : (is_string($connection) ? $connection : lang('Invalid credentials.')));
$password = null;
}
unset_permanent();
}
}
page_header(lang('Login'), $error, null);
@@ -87,7 +97,8 @@ function auth_error($exception = null) {
if (isset($_GET["username"])) {
if (!class_exists("Min_DB")) {
unset($_SESSION["pwds"][DRIVER]); //! remove also from adminer_permanent
unset($_SESSION["pwds"][DRIVER]);
unset_permanent();
page_header(lang('No extension'), lang('None of the supported PHP extensions (%s) are available.', implode(", ", $possible_drivers)), false);
page_footer("auth");
exit;

View File

@@ -21,7 +21,8 @@ if (isset($_GET["file"])) {
include "../adminer/include/functions.inc.php";
global $adminer, $connection, $drivers, $edit_functions, $enum_length, $error, $functions, $grouping, $HTTPS, $inout, $jush, $LANG, $langs, $on_actions, $structured_types, $token, $translations, $types, $unsigned, $VERSION; // allows including Adminer inside a function
global $adminer, $connection, $drivers, $edit_functions, $enum_length, $error, $functions, $grouping, $HTTPS, $inout, $jush, $LANG, $langs, $on_actions, $permanent, $structured_types, $token, $translations, $types, $unsigned, $VERSION; // allows including Adminer inside a function
if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility
$_SERVER["REQUEST_URI"] = $_SERVER["ORIG_PATH_INFO"];
}
@@ -73,12 +74,13 @@ include "./include/adminer.inc.php";
include "../adminer/include/design.inc.php";
include "../adminer/include/xxtea.inc.php";
include "../adminer/include/auth.inc.php";
include "./include/connect.inc.php";
include "./include/editing.inc.php";
session_cache_limiter(""); // to allow restarting session
if (!ini_bool("session.use_cookies") || @ini_set("session.use_cookies", false) !== false) { // @ - may be disabled
session_cache_limiter(""); // to allow restarting session
session_write_close(); // improves concurrency if a user opens several pages at once, may be restarted later
}
include "./include/connect.inc.php";
include "./include/editing.inc.php";
$on_actions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; ///< @var string used in foreign_keys()

View File

@@ -23,9 +23,7 @@ function connect_error() {
}
echo "<p>" . lang('%s version: %s through PHP extension %s', $drivers[DRIVER], "<b>$connection->server_info</b>", "<b>$connection->extension</b>") . "\n";
echo "<p>" . lang('Logged as: %s', "<b>" . h(logged_user()) . "</b>") . "\n";
if ($_GET["refresh"]) {
set_session("dbs", null);
}
$refresh = "<a href='" . h(ME) . "refresh=1'>" . lang('Refresh') . "</a>\n";
$databases = $adminer->databases();
if ($databases) {
$scheme = support("scheme");
@@ -45,8 +43,10 @@ function connect_error() {
echo "<script type='text/javascript'>tableCheck();</script>\n";
echo "<p><input type='submit' name='drop' value='" . lang('Drop') . "'" . confirm("formChecked(this, /db/)") . ">\n";
echo "<input type='hidden' name='token' value='$token'>\n";
echo "<a href='" . h(ME) . "refresh=1'>" . lang('Refresh') . "</a>\n";
echo $refresh;
echo "</form>\n";
} else {
echo "<p>$refresh";
}
}
page_footer("db");
@@ -58,8 +58,9 @@ function connect_error() {
if (isset($_GET["status"])) {
$_GET["variables"] = $_GET["status"];
}
if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]) || isset($_GET["variables"]) || $_GET["script"] == "connect")) {
if (DB != "") {
if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]) || isset($_GET["variables"]) || $_GET["script"] == "connect" || $_GET["script"] == "kill")) {
if (DB != "" || $_GET["refresh"]) {
restart_session();
set_session("dbs", null);
}
connect_error(); // separate function to catch SQLite error

View File

@@ -32,7 +32,7 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
<?php } ?>
<?php } ?>
<body class="<?php echo lang('ltr'); ?> nojs" onkeydown="bodyKeydown(event);" onload="bodyLoad('<?php echo (is_object($connection) ? substr($connection->server_info, 0, 3) : ""); ?>');<?php echo (isset($_COOKIE["adminer_version"]) ? "" : " verifyVersion();"); ?>">
<body class="<?php echo lang('ltr'); ?> nojs" onkeydown="bodyKeydown(event);" onclick="bodyClick(event);" onload="bodyLoad('<?php echo (is_object($connection) ? substr($connection->server_info, 0, 3) : ""); ?>');<?php echo (isset($_COOKIE["adminer_version"]) ? "" : " verifyVersion();"); ?>">
<script type="text/javascript">
document.body.className = document.body.className.replace(/ nojs/, ' js');
</script>
@@ -77,6 +77,7 @@ document.body.className = document.body.className.replace(/ nojs/, ' js');
if (DB != "" && $databases && !in_array(DB, $databases, true)) {
$databases = null;
}
stop_session();
if ($error) {
echo "<div class='error'>$error</div>\n";
}

View File

@@ -357,6 +357,14 @@ function drop_create($drop, $create, $location, $message_drop, $message_alter, $
return $dropped;
}
/** Remove current user definer from SQL command
* @param string
* @return string
*/
function remove_definer($query) {
return preg_replace('~^([A-Z =]+) DEFINER=`' . preg_replace('~@(.*)~', '`@`(%|\\1)', logged_user()) . '`~', '\\1', $query); //! proper escaping of user
}
/** Get string to add a file in TAR
* @param string
* @param string

View File

@@ -396,6 +396,15 @@ function restart_session() {
}
}
/** Stop session if it would be possible to restart it later
* @return null
*/
function stop_session() {
if (!ini_bool("session.use_cookies")) {
session_write_close();
}
}
/** Get session variable for current server
* @param string
* @return mixed
@@ -719,8 +728,14 @@ function input($field, $value, $function) {
}
} elseif (ereg('blob|bytea|raw|file', $field["type"]) && ini_bool("file_uploads")) {
echo "<input type='file' name='fields-$name'$onchange>";
} elseif (ereg('text|lob', $field["type"])) {
echo "<textarea " . ($jush != "sqlite" || ereg("\n", $value) ? "cols='50' rows='12'" : "cols='30' rows='1' style='height: 1.2em;'") . "$attrs>" . h($value) . '</textarea>'; // 1.2em - line-height
} elseif (($text = ereg('text|lob', $field["type"])) || ereg("\n", $value)) {
if ($text && $jush != "sqlite") {
$attrs .= " cols='50' rows='12'";
} else {
$rows = min(12, substr_count($value, "\n") + 1);
$attrs .= " cols='30' rows='$rows'" . ($rows == 1 ? " style='height: 1.2em;'" : ""); // 1.2em - line-height
}
echo "<textarea$attrs>" . h($value) . '</textarea>';
} else {
// int(3) is only a display hint
$maxlength = (!ereg('int', $field["type"]) && preg_match('~^(\\d+)(,(\\d+))?$~', $field["length"], $match) ? ((ereg("binary", $field["type"]) ? 2 : 1) * $match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0)) : ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0));
@@ -783,12 +798,14 @@ function search_tables() {
$name = $adminer->tableName($table_status);
if (isset($table_status["Engine"]) && $name != "" && (!$_POST["tables"] || in_array($table, $_POST["tables"]))) {
$result = $connection->query("SELECT" . limit("1 FROM " . table($table), " WHERE " . implode(" AND ", $adminer->selectSearchProcess(fields($table), array())), 1));
if ($result->fetch_row()) {
if (!$result || $result->fetch_row()) {
if (!$found) {
echo "<ul>\n";
$found = true;
}
echo "<li><a href='" . h(ME . "select=" . urlencode($table) . "&where[0][op]=" . urlencode($_GET["where"][0]["op"]) . "&where[0][val]=" . urlencode($_GET["where"][0]["val"])) . "'>$name</a>\n";
echo "<li>" . ($result
? "<a href='" . h(ME . "select=" . urlencode($table) . "&where[0][op]=" . urlencode($_GET["where"][0]["op"]) . "&where[0][val]=" . urlencode($_GET["where"][0]["val"])) . "'>$name</a>\n"
: "$name: <span class='error'>" . error() . "</span>\n");
}
}
}
@@ -883,3 +900,72 @@ function is_url($string) {
$domain = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])'; // one domain component //! IDN
return (preg_match("~^(https?)://($domain?\\.)+$domain(:\\d+)?(/.*)?(\\?.*)?(#.*)?\$~i", $string, $match) ? strtolower($match[1]) : ""); //! restrict path, query and fragment characters
}
/** Run query which can be killed by AJAX call after timing out
* @param string
* @return Min_Result
*/
function slow_query($query) {
global $adminer, $token;
$db = $adminer->database();
if (support("kill") && is_object($connection2 = connect()) && ($db == "" || $connection2->select_db($db))) {
$kill = $connection2->result("SELECT CONNECTION_ID()"); // MySQL and MySQLi can use thread_id but it's not in PDO_MySQL
?>
<script type="text/javascript">
var timeout = setTimeout(function () {
ajax('<?php echo js_escape(ME); ?>script=kill', function () {
}, 'token=<?php echo $token; ?>&kill=<?php echo $kill; ?>');
}, <?php echo 1000 * $adminer->queryTimeout(); ?>);
</script>
<?php
} else {
$connection2 = null;
}
ob_flush();
flush();
$return = @get_key_vals($query, $connection2); // @ - may be killed
if ($connection2) {
echo "<script type='text/javascript'>clearTimeout(timeout);</script>\n";
ob_flush();
flush();
}
return array_keys($return);
}
// used in compiled version
function lzw_decompress($binary) {
// convert binary string to codes
$dictionary_count = 256;
$bits = 8; // ceil(log($dictionary_count, 2))
$codes = array();
$rest = 0;
$rest_length = 0;
for ($i=0; $i < strlen($binary); $i++) {
$rest = ($rest << 8) + ord($binary[$i]);
$rest_length += 8;
if ($rest_length >= $bits) {
$rest_length -= $bits;
$codes[] = $rest >> $rest_length;
$rest &= (1 << $rest_length) - 1;
$dictionary_count++;
if ($dictionary_count >> $bits) {
$bits++;
}
}
}
// decompression
$dictionary = range("\0", "\xFF");
$return = "";
foreach ($codes as $i => $code) {
$element = $dictionary[$code];
if (!isset($element)) {
$element = $word . $word[0];
}
$return .= $element;
if ($i) {
$dictionary[] = $word . $element[0];
}
$word = $element;
}
return $return;
}

View File

@@ -22,6 +22,7 @@ $langs = array(
'id' => 'Bahasa Indonesia', // Ivan Lanin - http://ivan.lanin.org
'ru' => 'Русский язык', // Maksim Izmaylov
'uk' => 'Українська', // Valerii Kryzhov
'sr' => 'Српски', // Nikola Radovanović - cobisimo@gmail.com
'zh' => '简体中文', // Mr. Lodar
'zh-tw' => '繁體中文', // http://tzangms.com
'ja' => '日本語', // Hitoshi Ozawa - http://sourceforge.jp/projects/oss-ja-jpn/releases/
@@ -46,7 +47,7 @@ function get_lang() {
*/
function lang($idf, $number = null) {
global $LANG, $translations;
$translation = (isset($translations[$idf]) ? $translations[$idf] : $idf);
$translation = ($translations[$idf] ? $translations[$idf] : $idf);
if (is_array($translation)) {
$pos = ($number == 1 ? 0
: ($LANG == 'cs' || $LANG == 'sk' ? ($number && $number < 5 ? 1 : 2) // different forms for 1, 2-4, other
@@ -54,7 +55,7 @@ function lang($idf, $number = null) {
: ($LANG == 'pl' ? ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2) // different forms for 1, 2-4, other
: ($LANG == 'sl' ? ($number % 100 == 1 ? 0 : ($number % 100 == 2 ? 1 : ($number % 100 == 3 || $number % 100 == 4 ? 2 : 3))) // different forms for 1, 2, 3-4, other
: ($LANG == 'lt' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1, 12-19, other
: ($LANG == 'ru' || $LANG == 'uk' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1, 2-4, other
: ($LANG == 'ru' || $LANG == 'sr' || $LANG == 'uk' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1, 2-4, other
: 1
))))))); // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
$translation = $translation[$pos];
@@ -69,17 +70,19 @@ function lang($idf, $number = null) {
}
function switch_lang() {
global $LANG, $langs;
echo "<form action=''>\n<div id='lang'>";
hidden_fields($_GET, array('lang'));
echo lang('Language') . ": " . html_select("lang", $langs, $LANG, "var loc = location.search.replace(/[?&]lang=[^&]*/, ''); location.search = loc + (loc ? '&' : '') + 'lang=' + this.value;");
global $LANG, $langs, $token;
echo "<form action='' method='post'>\n<div id='lang'>";
echo lang('Language') . ": " . html_select("lang", $langs, $LANG, "this.form.submit();");
echo " <input type='submit' value='" . lang('Use') . "' class='hidden'>\n";
echo "<input type='hidden' name='token' value='$token'>\n";
echo "</div>\n</form>\n";
}
if (isset($_GET["lang"])) {
$_COOKIE["adminer_lang"] = $_GET["lang"];
$_SESSION["lang"] = $_GET["lang"]; // cookies may be disabled
if (isset($_POST["lang"]) && $_SESSION["token"] == $_POST["token"]) { // $token and $error not yet available
cookie("adminer_lang", $_POST["lang"]);
$_SESSION["lang"] = $_POST["lang"]; // cookies may be disabled
$_SESSION["translations"] = array(); // used in compiled version
redirect(remove_from_uri());
}
$LANG = "en";

View File

@@ -24,6 +24,7 @@ if (extension_loaded('pdo')) {
function query($query, $unbuffered = false) {
$result = parent::query($query);
$this->error = "";
if (!$result) {
$errorInfo = $this->errorInfo();
$this->error = $errorInfo[2];

View File

@@ -1,2 +1,2 @@
<?php
$VERSION = "3.4.0";
$VERSION = "3.6.0";

View File

@@ -234,6 +234,8 @@ $translations = array(
'Page' => 'Stránka',
'last' => 'poslední',
'Last page' => 'Poslední stránka',
'Load more data' => 'Nahrát další data',
'Loading' => 'Nahrává se',
'whole result' => 'celý výsledek',
'%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtů'),

323
adminer/lang/sr.inc.php Normal file
View File

@@ -0,0 +1,323 @@
<?php
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Систем',
'Server' => 'Сервер',
'Username' => 'Корисничко име',
'Password' => 'Лозинка',
'Permanent login' => 'Трајна пријава',
'Login' => 'Пријава',
'Logout' => 'Одјава',
'Logged as: %s' => 'Пријави се као: %s',
'Logout successful.' => 'Успешна одјава.',
'Invalid credentials.' => 'Неважеће дозволе.',
'Language' => 'Језик',
'Invalid CSRF token. Send the form again.' => 'Неважећи CSRF код. Проследите поново форму.',
'No extension' => 'Без додатака',
'None of the supported PHP extensions (%s) are available.' => 'Ниједан од подржаних PHP додатака није доступан.',
'Session support must be enabled.' => 'Морате омогућити подршку за сесије.',
'Session expired, please login again.' => 'Ваша сесија је истекла, пријавите се поново.',
'%s version: %s through PHP extension %s' => '%s верзија: %s помоћу PHP додатка је %s',
'Refresh' => 'Освежи',
// text direction - 'ltr' or 'rtl'
'ltr' => 'ltr',
'Privileges' => 'Дозволе',
'Create user' => 'Направи корисника',
'User has been dropped.' => 'Корисник је избрисан.',
'User has been altered.' => 'Корисник је измењен.',
'User has been created.' => 'корисник је креиран.',
'Hashed' => 'Хеширано',
'Column' => 'Колона',
'Routine' => 'Рутина',
'Grant' => 'Дозволи',
'Revoke' => 'Опозови',
'Process list' => 'Списак процеса',
'%d process(es) have been killed.' => array('%d процес је убијен.', '%d процеса су убијена.', '%d процеса је убијено.'),
'Kill' => 'Убиј',
'Variables' => 'Променљиве',
'Status' => 'Статус',
'SQL command' => 'SQL команда',
'%d query(s) executed OK.' => array('%d упит је успешно извршен.', '%d упита су успешно извршена.', '%d упита је успешно извршено.'),
'Query executed OK, %d row(s) affected.' => array('Упит је успешно извршен, %d ред је погођен.', 'Упит је успешно извршен, %d реда су погођена.', 'Упит је успешно извршен, %d редова је погођено.'),
'No commands to execute.' => 'Без команди за извршавање.',
'Error in query' => 'Грешка у упиту',
'Execute' => 'Изврши',
'Stop on error' => 'Заустави приликом грешке',
'Show only errors' => 'Приказуј само грешке',
// sprintf() format for time of the command
'%.3f s' => '%.3f s',
'History' => 'Историјат',
'Clear' => 'Очисти',
'Edit all' => 'Измени све',
'File upload' => 'Слање датотека',
'From server' => 'Са сервера',
'Webserver file %s' => 'Датотека %s са веб сервера',
'Run file' => 'Покрени датотеку',
'File does not exist.' => 'Датотека не постоји.',
'File uploads are disabled.' => 'Онемогућено је слање датотека.',
'Unable to upload a file.' => 'Слање датотеке није успело.',
'Maximum allowed file size is %sB.' => 'Највећа дозвољена величина датотеке је %sB.',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Превелики POST податак. Морате да смањите податак или повећајте вредност конфигурационе директиве %s.',
'Export' => 'Извоз',
'Dump' => 'Истовар',
'Output' => 'Испис',
'open' => 'отвори',
'save' => 'сачувај',
'Format' => 'Формат',
'Data' => 'Податци',
'Database' => 'База података',
'database' => 'база података',
'Use' => 'Користи',
'Select database' => 'Изаберите базу',
'Invalid database.' => 'Неисправна база података.',
'Create new database' => 'Направи нову базу података',
'Database has been dropped.' => 'База података је избрисана.',
'Databases have been dropped.' => 'Базњ података су избрисане.',
'Database has been created.' => 'База података је креирана.',
'Database has been renamed.' => 'База података је преименована.',
'Database has been altered.' => 'База података је измењена.',
'Alter database' => 'Уреди базу података',
'Create database' => 'Формирај базу података',
'Database schema' => 'Шема базе података',
// link to current database schema layout
'Permanent link' => 'Трајна веза',
// thousands separator - must contain single byte
',' => ',',
'Engine' => 'Механизам',
'Collation' => 'Сравњивање',
'Data Length' => 'Дужина података',
'Index Length' => 'Дужина индекса',
'Data Free' => 'Слободно података',
'Rows' => 'Редова',
'%d in total' => 'укупно %d',
'Analyze' => 'Анализирај',
'Optimize' => 'Оптимизуј',
'Check' => 'Провери',
'Repair' => 'Поправи',
'Truncate' => 'Испразни',
'Tables have been truncated.' => 'Табеле су испражњене.',
'Move to other database' => 'Премести у другу базу података',
'Move' => 'Премести',
'Tables have been moved.' => 'Табеле су премешћене.',
'Copy' => 'Умножи',
'Tables have been copied.' => 'Табеле су умножене.',
'Routines' => 'Рутине',
'Routine has been called, %d row(s) affected.' => array('Позвана је рутина, %d ред је погођен.', 'Позвана је рутина, %d реда су погођена.', 'Позвана је рутина, %d редова је погођено.'),
'Call' => 'Позови',
'Parameter name' => 'Назив параметра',
'Create procedure' => 'Формирај процедуру',
'Create function' => 'Формирај функцију',
'Routine has been dropped.' => 'Рутина је избрисана.',
'Routine has been altered.' => 'Рутина је измењена.',
'Routine has been created.' => 'Рутина је креирана.',
'Alter function' => 'Уреди функцију',
'Alter procedure' => 'Уреди процедуру',
'Return type' => 'Повратни тип',
'Events' => 'Догађаји',
'Event has been dropped.' => 'Догађај је избрисан.',
'Event has been altered.' => 'Догађај је измењен.',
'Event has been created.' => 'Догађај је креиран.',
'Alter event' => 'Уреди догађај',
'Create event' => 'Направи догађај',
'At given time' => 'У задато време',
'Every' => 'Сваки',
'Schedule' => 'Распоред',
'Start' => 'Почетак',
'End' => 'Крај',
'On completion preserve' => 'Задржи по завршетку',
'Tables' => 'Табеле',
'Tables and views' => 'Табеле и погледи',
'Table' => 'Табела',
'No tables.' => 'Без табела.',
'Alter table' => 'Уреди табелу',
'Create table' => 'Направи табелу',
'Create new table' => 'направи нову табелу',
'Table has been dropped.' => 'Табела је избрисана.',
'Tables have been dropped.' => 'Табеле су избрисане.',
'Tables have been optimized.' => 'Табеле су оптимизоване.',
'Table has been altered.' => 'Табела је измењена.',
'Table has been created.' => 'Табела је креирана.',
'Table name' => 'Назив табеле',
'Show structure' => 'Прикажи структуру',
'engine' => 'механизам',
'collation' => 'Сравњивање',
'Column name' => 'Назив колоне',
'Type' => 'Тип',
'Length' => 'Дужина',
'Auto Increment' => 'Ауто-прираштај',
'Options' => 'Опције',
'Comment' => 'Коментар',
'Default values' => 'Подразумеване вредности',
'Drop' => 'Избриши',
'Are you sure?' => 'Да ли сте сигурни?',
'Move up' => 'Помери на горе',
'Move down' => 'Помери на доле',
'Remove' => 'Уклони',
'Maximum number of allowed fields exceeded. Please increase %s and %s.' => 'Премашен је максимални број дозвољених поља. Молим увећајте %s и %s.',
'Partition by' => 'Подели по',
'Partitions' => 'Поделе',
'Partition name' => 'Име поделе',
'Values' => 'Вредности',
'View' => 'Поглед',
'View has been dropped.' => 'Поглед је избрисан.',
'View has been altered.' => 'Поглед је измењен.',
'View has been created.' => 'Поглед је креиран.',
'Alter view' => 'Уреди поглед',
'Create view' => 'Направи поглед',
'Indexes' => 'Индекси',
'Indexes have been altered.' => 'Индекси су измењени.',
'Alter indexes' => 'Уреди индексе',
'Add next' => 'Додај следећи',
'Index Type' => 'Тип индекса',
'Column (length)' => 'Колона (дужина)',
'Foreign keys' => 'Страни кључеви',
'Foreign key' => 'Страни кључ',
'Foreign key has been dropped.' => 'Страни кључ је избрисан.',
'Foreign key has been altered.' => 'Страни кључ је измењен.',
'Foreign key has been created.' => 'Страни кључ је креиран.',
'Target table' => 'Циљна табела',
'Change' => 'Измени',
'Source' => 'Извор',
'Target' => 'Циљ',
'Add column' => 'Додај колону',
'Alter' => 'Уреди',
'Add foreign key' => 'Додај страни кључ',
'ON DELETE' => 'ON DELETE (приликом брисања)',
'ON UPDATE' => 'ON UPDATE (приликом освежавања)',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'Изворне и циљне колоне морају бити истог типа, циљна колона мора бити индексирана и изворна табела мора садржати податке из циљне.',
'Triggers' => 'Окидачи',
'Add trigger' => 'Додај окидач',
'Trigger has been dropped.' => 'Окидач је избрисан.',
'Trigger has been altered.' => 'Окидач је измењен.',
'Trigger has been created.' => 'Окидач је креиран.',
'Alter trigger' => 'Уреди окидач',
'Create trigger' => 'Формирај окидач',
'Time' => 'Време',
'Event' => 'Догађај',
'Name' => 'Име',
'select' => 'изабери',
'Select' => 'Изабери',
'Select data' => 'Изабери податке',
'Functions' => 'Функције',
'Aggregation' => 'Сакупљање',
'Search' => 'Претрага',
'anywhere' => 'било где',
'Search data in tables' => 'Претражи податке у табелама',
'Sort' => 'Поређај',
'descending' => 'опадајуће',
'Limit' => 'Граница',
'Text length' => 'Дужина текста',
'Action' => 'Акција',
'Full table scan' => 'Скренирање комплетне табеле',
'Unable to select the table' => 'Не могу да изаберем табелу',
'No rows.' => 'Без редова.',
'%d row(s)' => array('%d ред', '%d реда', '%d редова'),
'Page' => 'Страна',
'last' => 'последња',
'Last page' => 'Последња страна',
'Loading' => 'Учитавам',
'Load more data' => 'Учитавам још података',
'whole result' => 'цео резултат',
'%d byte(s)' => array('%d бајт', '%d бајта', '%d бајтова'),
'Import' => 'Увоз',
'%d row(s) have been imported.' => array('%d ред је увежен.', '%d реда су увежена.', '%d редова је увежено.'),
// in-place editing in select
'Double click on a value to modify it.' => 'Дупли клик на вредност за измену.',
'Use edit link to modify this value.' => 'Користи везу за измену ове вредности.',
// %s can contain auto-increment value
'Item%s has been inserted.' => 'Ставка%s је додата.',
'Item has been deleted.' => 'Ставка је избрисана.',
'Item has been updated.' => 'Ставка је измењена.',
'%d item(s) have been affected.' => array('%d ставка је погођена.', '%d ставке су погођене.', '%d ставки је погођено.'),
'New item' => 'Нова ставка',
'original' => 'оригинал',
// label for value '' in enum data type
'empty' => 'празно',
'edit' => 'измени',
'Edit' => 'Измени',
'Insert' => 'Уметни',
'Save' => 'Сачувај',
'Save and continue edit' => 'Сачувај и настави уређење',
'Save and insert next' => 'Сачувај и уметни следеће',
'Clone' => 'Дуплирај',
'Delete' => 'Избриши',
'E-mail' => 'Ел. пошта',
'From' => 'Од',
'Subject' => 'Наслов',
'Attachments' => 'Прилози',
'Send' => 'Пошаљи',
'%d e-mail(s) have been sent.' => array('%d порука ел. поште је послата.', '%d поруке ел. поште су послате.', '%d порука ел. поште је послато.'),
// data type descriptions
'Numbers' => 'Број',
'Date and time' => 'Датум и време',
'Strings' => 'Текст',
'Binary' => 'Бинарно',
'Lists' => 'Листе',
'Network' => 'Мрежа',
'Geometry' => 'Геометрија',
'Relations' => 'Односи',
'Editor' => 'Уређивач',
// date format in Editor: $1 yyyy, $2 yy, $3 mm, $4 m, $5 dd, $6 d
'$1-$3-$5' => '$5.$3.$1.',
// hint for date format - use language equivalents for day, month and year shortcuts
'[yyyy]-mm-dd' => 'dd.mm.[yyyy].',
// hint for time format - use language equivalents for hour, minute and second shortcuts
'HH:MM:SS' => 'HH:MM:SS',
'now' => 'сад',
'yes' => 'да',
'no' => 'не',
// general SQLite error in create, drop or rename database
'File exists.' => 'Датотека већ постоји.',
'Please use one of the extensions %s.' => 'Молим користите један од наставака %s.',
// PostgreSQL and MS SQL schema support
'Alter schema' => 'Уреди шему',
'Create schema' => 'Формирај шему',
'Schema has been dropped.' => 'Шема је избрисана.',
'Schema has been created.' => 'Шема је креирана.',
'Schema has been altered.' => 'Шема је измењена.',
'schema' => 'шема',
'Schema' => 'Шема',
'Invalid schema.' => 'Шема није исправна.',
// PostgreSQL sequences support
'Sequences' => 'Низови',
'Create sequence' => 'Направи низ',
'Sequence has been dropped.' => 'Низ је избрисан.',
'Sequence has been created.' => 'Низ је формиран.',
'Sequence has been altered.' => 'Низ је измењен.',
'Alter sequence' => 'Уреди низ',
// PostgreSQL user types support
'User types' => 'Кориснички типови',
'Create type' => 'Дефиниши тип',
'Type has been dropped.' => 'Тип је избрисан.',
'Type has been created.' => 'тип је креиран.',
'Alter type' => 'Уреди тип',
);

View File

@@ -24,7 +24,7 @@ foreach (process_list() as $i => $row) {
echo "<tr" . odd() . ">" . (support("kill") ? "<td>" . checkbox("kill[]", $row["Id"], 0) : "");
foreach ($row as $key => $val) {
echo "<td>" . (
($jush == "sql" && $key == "Info" && $row["Command"] == "Query" && $val != "") ||
($jush == "sql" && $key == "Info" && ereg("Query|Killed", $row["Command"]) && $val != "") ||
($jush == "pgsql" && $key == "current_query" && $val != "<IDLE>") ||
($jush == "oracle" && $key == "sql_text" && $val != "")
? "<code class='jush-$jush'>" . shorten_utf8($val, 100, "</code>") . ' <a href="' . h(ME . ($row["db"] != "" ? "db=" . urlencode($row["db"]) . "&" : "") . "sql=" . urlencode($val)) . '">' . lang('Edit') . '</a>'

View File

@@ -13,10 +13,10 @@ if ($_GET["script"] == "db") {
foreach ($sums + array("Auto_increment" => 0, "Rows" => 0) as $key => $val) {
if ($table_status[$key] != "") {
$val = number_format($table_status[$key], 0, '.', lang(','));
json_row("$key-$id", ($key == "Rows" && $val && (
$table_status["Engine"] == "InnoDB" || // MySQL InnoDB
$table_status["Engine"] == "table" // PostgreSQL table reltype
) ? "~ $val" : $val));
json_row("$key-$id", ($key == "Rows" && $val && $table_status["Engine"] == ($sql == "pgsql" ? "table" : "InnoDB")
? "~ $val"
: $val
));
if (isset($sums[$key])) {
// ignore innodb_file_per_table because it is not active for tables created before it was enabled
$sums[$key] += ($table_status["Engine"] != "InnoDB" || $key != "Data_free" ? $table_status[$key] : 0);
@@ -31,6 +31,10 @@ if ($_GET["script"] == "db") {
json_row("sum-$key", number_format($val, 0, '.', lang(',')));
}
json_row("");
} elseif ($_GET["script"] == "kill") {
$connection->query("KILL " . (+$_POST["kill"]));
} else { // connect
foreach (count_tables($adminer->databases()) as $db => $val) {
json_row("tables-" . js_escape($db), $val);

View File

@@ -4,8 +4,10 @@ $table_status = table_status($TABLE);
$indexes = indexes($TABLE);
$fields = fields($TABLE);
$foreign_keys = column_foreign_keys($TABLE);
$oid = "";
if ($table_status["Oid"] == "t") {
$indexes[] = array("type" => "PRIMARY", "columns" => array("oid"));
$oid = ($jush == "sqlite" ? "rowid" : "oid");
$indexes[] = array("type" => "PRIMARY", "columns" => array($oid));
}
parse_str($_COOKIE["adminer_import"], $adminer_import);
@@ -16,7 +18,7 @@ foreach ($fields as $key => $field) {
$name = $adminer->fieldName($field);
if (isset($field["privileges"]["select"]) && $name != "") {
$columns[$key] = html_entity_decode(strip_tags($name));
if (ereg('text|lob', $field["type"])) {
if (ereg('text|lob|geometry|point|linestring|polygon', $field["type"])) {
$text_length = $adminer->selectLengthProcess();
}
}
@@ -24,16 +26,27 @@ foreach ($fields as $key => $field) {
}
list($select, $group) = $adminer->selectColumnsProcess($columns, $indexes);
$is_group = count($group) < count($select);
$where = $adminer->selectSearchProcess($fields, $indexes);
$order = $adminer->selectOrderProcess($fields, $indexes);
$limit = $adminer->selectLimitProcess();
$from = ($select ? implode(", ", $select) : ($table_status["Oid"] == "t" ? "oid, " : "") . "*") . "\nFROM " . table($TABLE);
$group_by = ($group && count($group) < count($select) ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : "");
$from = ($select ? implode(", ", $select) : "*" . ($oid ? ", $oid" : ""));
if ($jush == "sql") {
foreach ($columns as $key => $val) {
$as = convert_field($fields[$key]);
if ($as) {
$from .= ", $as AS " . idf_escape($key);
}
}
}
$from .= "\nFROM " . table($TABLE);
$group_by = ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : "");
if ($_GET["val"] && is_ajax()) {
header("Content-Type: text/plain; charset=utf-8");
foreach ($_GET["val"] as $unique_idf => $row) {
echo $connection->result("SELECT" . limit(idf_escape(key($row)) . " FROM " . table($TABLE), " WHERE " . where_check($unique_idf) . ($where ? " AND " . implode(" AND ", $where) : "") . ($order ? " ORDER BY " . implode(", ", $order) : ""), 1));
$as = convert_field($fields[key($row)]);
echo $connection->result("SELECT" . limit(($as ? $as : idf_escape(key($row))) . " FROM " . table($TABLE), " WHERE " . where_check($unique_idf) . ($where ? " AND " . implode(" AND ", $where) : "") . ($order ? " ORDER BY " . implode(", ", $order) : ""), 1));
}
exit;
}
@@ -103,8 +116,8 @@ if ($_POST && !$error) {
$command = "INSERT";
$query = "INTO $query";
}
if ($_POST["all"] || ($unselected === array() && $_POST["check"]) || count($group) < count($select)) {
$result = queries($command . " $query" . ($_POST["all"] ? ($where ? "\nWHERE " . implode(" AND ", $where) : "") : "\nWHERE $where_check"));
if ($_POST["all"] || ($unselected === array() && $_POST["check"]) || $is_group) {
$result = queries("$command $query" . ($_POST["all"] ? ($where ? "\nWHERE " . implode(" AND ", $where) : "") : "\nWHERE $where_check"));
$affected = $connection->affected_rows;
} else {
foreach ((array) $_POST["check"] as $val) {
@@ -117,7 +130,14 @@ if ($_POST && !$error) {
}
}
}
queries_redirect(remove_from_uri("page"), lang('%d item(s) have been affected.', $affected), $result);
$message = lang('%d item(s) have been affected.', $affected);
if ($_POST["clone"] && $result && $affected == 1) {
$last_id = last_id();
if ($last_id) {
$message = lang('Item%s has been inserted.', " $last_id");
}
}
queries_redirect(remove_from_uri("page"), $message, $result);
//! display edit page in case of an error
} elseif (!$_POST["import"]) { // modify
if (!$_POST["val"]) {
@@ -133,7 +153,7 @@ if ($_POST && !$error) {
}
$query = table($TABLE) . " SET " . implode(", ", $set);
$where2 = " WHERE " . where_check($unique_idf) . ($where ? " AND " . implode(" AND ", $where) : "");
$result = queries("UPDATE" . (count($group) < count($select) ? " $query$where2" : limit1($query, $where2))); // can change row on a different page without unique key
$result = queries("UPDATE" . ($is_group ? " $query$where2" : limit1($query, $where2))); // can change row on a different page without unique key
if (!$result) {
break;
}
@@ -179,8 +199,11 @@ if ($_POST && !$error) {
}
$table_name = $adminer->tableName($table_status);
if (is_ajax()) {
// needs to send headers
ob_start();
}
page_header(lang('Select') . ": $table_name", $error);
session_write_close();
$set = null;
if (isset($rights["insert"])) {
@@ -218,7 +241,16 @@ if (!$columns) {
$page = floor(max(0, $found_rows - 1) / $limit);
}
$query = "SELECT" . limit((+$limit && $group && count($group) < count($select) && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . $from, ($where ? "\nWHERE " . implode(" AND ", $where) : "") . $group_by, ($limit != "" ? +$limit : null), ($page ? $limit * $page : 0), "\n");
$query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page);
if (!$query) {
$query = "SELECT" . limit(
(+$limit && $group && $is_group && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . $from,
($where ? "\nWHERE " . implode(" AND ", $where) : "") . $group_by,
($limit != "" ? +$limit : null),
($page ? $limit * $page : 0),
"\n"
);
}
echo $adminer->selectQuery($query);
$result = $connection->query($query);
@@ -239,7 +271,7 @@ if (!$columns) {
}
// use count($rows) without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest)
if ($_GET["page"] != "last") {
$found_rows = (+$limit && $group && count($group) < count($select)
$found_rows = (+$limit && $group && $is_group
? ($jush == "sql" ? $connection->result(" SELECT FOUND_ROWS()") : $connection->result("SELECT COUNT(*) FROM ($query) x")) // space to allow mysql.trace_mode
: count($rows)
);
@@ -250,14 +282,14 @@ if (!$columns) {
} else {
$backward_keys = $adminer->backwardKeys($TABLE, $table_name);
echo "<table cellspacing='0' class='nowrap checkable' onclick='tableClick(event);' onkeydown='return editingKeydown(event);'>\n";
echo "<table id='table' cellspacing='0' class='nowrap checkable' onclick='tableClick(event);' onkeydown='return editingKeydown(event);'>\n";
echo "<thead><tr>" . (!$group && $select ? "" : "<td><input type='checkbox' id='all-page' onclick='formCheck(this, /check/);'> <a href='" . h($_GET["modify"] ? remove_from_uri("modify") : $_SERVER["REQUEST_URI"] . "&modify=1") . "'>" . lang('edit') . "</a>");
$names = array();
$functions = array();
reset($select);
$rank = 1;
foreach ($rows[0] as $key => $val) {
if ($table_status["Oid"] != "t" || $key != "oid") {
if ($key != $oid) {
$val = $_GET["columns"][key($select)];
$field = $fields[$select ? ($val ? $val["col"] : current($select)) : $key];
$name = ($field ? $adminer->fieldName($field, $rank) : "*");
@@ -266,8 +298,16 @@ if (!$columns) {
$names[$key] = $name;
$column = idf_escape($key);
$href = remove_from_uri('(order|desc)[^=]*|page') . '&order%5B0%5D=' . urlencode($key);
echo '<th><a href="' . h($href) . '">' . (!$select || $val ? apply_sql_function($val["fun"], $name) : h(current($select))) . "</a>"; //! columns looking like functions
echo "<a href='" . h("$href&desc%5B0%5D=1") . "' title='" . lang('descending') . "' class='text'> ↓</a>";
$desc = "&desc%5B0%5D=1";
echo '<th onmouseover="columnMouse(this);" onmouseout="columnMouse(this, \' hidden\');">';
echo '<a href="' . h($href . ($order[0] == $column || $order[0] == $key || (!$order && $is_group && $group[0] == $column) ? $desc : '')) . '">'; // $order[0] == $key - COUNT(*)
echo (!$select || $val ? apply_sql_function($val["fun"], $name) : h(current($select))) . "</a>"; //! columns looking like functions
echo "<span class='column hidden'>";
echo "<a href='" . h($href . $desc) . "' title='" . lang('descending') . "' class='text'> ↓</a>";
if (!$val["fun"]) {
echo '<a href="#fieldset-search" onclick="selectSearch(\'' . h(js_escape($key)) . '\'); return false;" title="' . lang('Search') . '" class="text jsonly"> =</a>';
}
echo "</span>";
}
$functions[$key] = $val["fun"];
next($select);
@@ -282,13 +322,19 @@ if (!$columns) {
}
}
echo ($backward_keys ? "<th>" . lang('Relations') : "") . "</thead>\n";
if (is_ajax()) {
if ($limit % 2 == 1 && $page % 2 == 1) {
odd();
}
ob_end_clean();
}
foreach ($adminer->rowDescriptions($rows, $foreign_keys) as $n => $row) {
$unique_array = unique_array($rows[$n], $indexes);
$unique_idf = "";
foreach ($unique_array as $key => $val) {
$unique_idf .= "&" . ($val !== null ? urlencode("where[" . bracket_escape($key) . "]") . "=" . urlencode($val) : "null%5B%5D=" . urlencode($key));
}
echo "<tr" . odd() . ">" . (!$group && $select ? "" : "<td>" . checkbox("check[]", substr($unique_idf, 1), in_array(substr($unique_idf, 1), (array) $_POST["check"]), "", "this.form['all'].checked = false; formUncheck('all-page');") . (count($group) < count($select) || information_schema(DB) ? "" : " <a href='" . h(ME . "edit=" . urlencode($TABLE) . $unique_idf) . "'>" . lang('edit') . "</a>"));
echo "<tr" . odd() . ">" . (!$group && $select ? "" : "<td>" . checkbox("check[]", substr($unique_idf, 1), in_array(substr($unique_idf, 1), (array) $_POST["check"]), "", "this.form['all'].checked = false; formUncheck('all-page');") . ($is_group || information_schema(DB) ? "" : " <a href='" . h(ME . "edit=" . urlencode($TABLE) . $unique_idf) . "'>" . lang('edit') . "</a>"));
foreach ($row as $key => $val) {
if (isset($names[$key])) {
$field = $fields[$key];
@@ -304,7 +350,7 @@ if (!$columns) {
if ($val === "") { // === - may be int
$val = "&nbsp;";
} elseif (is_utf8($val)) {
if ($text_length != "" && ereg('text|blob', $field["type"])) {
if ($text_length != "" && ereg('text|lob|geometry|point|linestring|polygon', $field["type"])) {
$val = shorten_utf8($val, max(0, +$text_length)); // usage of LEFT() would reduce traffic but complicate query - expected average speedup: .001 s VS .01 s on local network
} else {
$val = h($val);
@@ -367,35 +413,41 @@ if (!$columns) {
$adminer->backwardKeysPrint($backward_keys, $rows[$n]);
echo "</tr>\n"; // close to allow white-space: pre
}
if (is_ajax()) {
exit;
}
echo "</table>\n";
echo (!$group && $select ? "" : "<script type='text/javascript'>tableCheck();</script>\n");
}
if ($rows || $page) {
if (($rows || $page) && !is_ajax()) {
$exact_count = true;
if ($_GET["page"] != "last" && +$limit && count($group) >= count($select) && ($found_rows >= $limit || $page)) {
if ($_GET["page"] != "last" && +$limit && !$is_group && ($found_rows >= $limit || $page)) {
$found_rows = found_rows($table_status, $where);
if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) {
// slow with big tables
ob_flush();
flush();
$found_rows = $connection->result("SELECT COUNT(*) FROM " . table($TABLE) . ($where ? " WHERE " . implode(" AND ", $where) : ""));
$found_rows = reset(slow_query("SELECT COUNT(*) FROM " . table($TABLE) . ($where ? " WHERE " . implode(" AND ", $where) : "")));
} else {
$exact_count = false;
}
}
echo "<p class='pages'>";
if (+$limit && $found_rows > $limit) {
if (+$limit && ($found_rows === false || $found_rows > $limit)) {
// display first, previous 4, next 4 and last page
$max_page = floor(($found_rows - 1) / $limit);
$max_page = ($found_rows === false
? $page + (count($rows) >= $limit ? 2 : 1)
: floor(($found_rows - 1) / $limit)
);
echo '<a href="' . h(remove_from_uri("page")) . "\" onclick=\"pageClick(this.href, +prompt('" . lang('Page') . "', '" . ($page + 1) . "'), event); return false;\">" . lang('Page') . "</a>:";
echo pagination(0, $page) . ($page > 5 ? " ..." : "");
for ($i = max(1, $page - 4); $i < min($max_page, $page + 5); $i++) {
echo pagination($i, $page);
}
echo ($page + 5 < $max_page ? " ..." : "") . ($exact_count ? pagination($max_page, $page) : ' <a href="' . h(remove_from_uri() . "&page=last") . '">' . lang('last') . "</a>");
echo ($page + 5 < $max_page ? " ..." : "") . ($exact_count && $found_rows !== false ? pagination($max_page, $page) : ' <a href="' . h(remove_from_uri("page") . "&page=last") . '">' . lang('last') . "</a>");
}
echo " (" . ($exact_count ? "" : "~ ") . lang('%d row(s)', $found_rows) . ") " . checkbox("all", 1, 0, lang('whole result')) . "\n";
echo ($found_rows !== false ? " (" . ($exact_count ? "" : "~ ") . lang('%d row(s)', $found_rows) . ")" : "");
echo (+$limit && ($found_rows === false ? count($rows) + 1 : $found_rows - $page * $limit) > $limit ? ' <a href="' . h(remove_from_uri("page") . "&page=" . ($page + 1)) . '" onclick="return !selectLoadMore(this, ' . (+$limit) . ', \'' . lang('Loading') . '\');">' . lang('Load more data') . '</a>' : '');
echo " " . checkbox("all", 1, 0, lang('whole result')) . "\n";
if ($adminer->selectCommandPrint()) {
?>
@@ -431,3 +483,8 @@ if (!$columns) {
echo "</form>\n";
}
}
if (is_ajax()) {
ob_end_clean();
exit;
}

View File

@@ -35,13 +35,13 @@ if (!$error && $_POST) {
if ($query != "" && strlen($query) < 1e6) { // don't add big queries
$q = $query . (ereg(";[ \t\r\n]*\$", $query) ? "" : ";"); //! doesn't work with DELIMITER |
if (!$history || reset(end($history)) != $q) { // no repeated queries
restart_session();
$history[] = array($q, time());
set_session("queries", $history_all); // required because reference is unlinked by stop_session()
stop_session();
}
}
$space = "(?:\\s|/\\*.*\\*/|(?:#|-- )[^\n]*\n|--\n)";
if (!ini_bool("session.use_cookies")) {
session_write_close();
}
$delimiter = ";";
$offset = 0;
$empty = true;
@@ -58,7 +58,7 @@ if (!$error && $_POST) {
$dump_format = $adminer->dumpFormat();
unset($dump_format["sql"]);
while ($query != "") {
if (!$offset && preg_match("~^$space*DELIMITER\\s+(.+)~i", $query, $match)) {
if (!$offset && preg_match("~^$space*DELIMITER\\s+(\\S+)~i", $query, $match)) {
$delimiter = $match[1];
$query = substr($query, strlen($match[0]));
} else {
@@ -136,7 +136,7 @@ if (!$error && $_POST) {
if (preg_match("~^$space*(CREATE|DROP|ALTER)$space+(DATABASE|SCHEMA)\\b~isU", $q)) {
restart_session();
set_session("dbs", null); // clear cache
session_write_close();
stop_session();
}
if (!$_POST["only_errors"]) {
echo "<p class='message' title='" . h($connection->info) . "'>" . lang('Query executed OK, %d row(s) affected.', $connection->affected_rows) . "$time\n";

View File

@@ -23,6 +23,7 @@ pre { margin: 1em 0 0; }
input[type=image] { vertical-align: middle; }
.version { color: #777; font-size: 67%; }
.js .hidden, .nojs .jsonly { display: none; }
.js .column { position: absolute; background: #ddf; padding: .3em 1ex .3em 0; margin-top: -.3em; }
.nowrap td, .nowrap th, td.nowrap { white-space: pre; }
.wrap td { white-space: normal; }
.error { color: red; background: #fee; }
@@ -44,8 +45,13 @@ input[type=image] { vertical-align: middle; }
.active { font-weight: bold; }
.sqlarea { width: 98%; }
.icon { width: 18px; height: 18px; }
#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 { position: absolute; margin: 10px 0 0; padding: 0 0 30px 0; top: 2em; left: 0; width: 19em; }
#menu p { padding: .8em 1em; margin: 0; border-bottom: 1px solid #ccc; }
#dbs { overflow: hidden; }
#logins, #tables { white-space: nowrap; overflow: auto; }
#logins a, #tables a { background: #fff; }
#logout { background: none; border: none; color: blue; font: inherit; padding: 0; text-decoration: underline; cursor: pointer; }
#logout:hover { color: red; }
#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; }

View File

@@ -64,7 +64,7 @@ function typePassword(el, disable) {
}
function loginDriver(driver) {
var trs = driver.parentNode.parentNode.parentNode.rows;
var trs = parentTag(driver, 'table').rows;
for (var i=1; i < trs.length - 1; i++) {
trs[i].className = (/sqlite/.test(driver.value) ? 'hidden' : '');
}
@@ -109,6 +109,64 @@ function textareaKeydown(target, event) {
/** Check whether the query will be executed with index
* @param HTMLFormElement
*/
function selectFieldChange(form) {
var ok = (function () {
var inputs = form.getElementsByTagName('input');
for (var i=0; i < inputs.length; i++) {
if (inputs[i].value && /^fulltext/.test(inputs[i].name)) {
return true;
}
}
var ok = form.limit.value;
var selects = form.getElementsByTagName('select');
var group = false;
var columns = {};
for (var i=0; i < selects.length; i++) {
var select = selects[i];
var col = selectValue(select);
var match = /^(where.+)col\]/.exec(select.name);
if (match) {
var op = selectValue(form[match[1] + 'op]']);
var val = form[match[1] + 'val]'].value;
if (col in indexColumns && (!/LIKE|REGEXP/.test(op) || (op == 'LIKE' && val.charAt(0) != '%'))) {
return true;
} else if (col || val) {
ok = false;
}
}
if ((match = /^(columns.+)fun\]/.exec(select.name))) {
if (/^(avg|count|count distinct|group_concat|max|min|sum)$/.test(col)) {
group = true;
}
var val = selectValue(form[match[1] + 'col]']);
if (val) {
columns[col && col != 'count' ? '' : val] = 1;
}
}
if (col && /^order/.test(select.name)) {
if (!(col in indexColumns)) {
ok = false;
}
break;
}
}
if (group) {
for (var col in columns) {
if (!(col in indexColumns)) {
ok = false;
}
}
}
return ok;
})();
setHtml('noindex', (ok ? '' : '!'));
}
var added = '.', rowCount;
/** Check if val is equal to a-delimiter-b where delimiter is '_', '' or big letter
@@ -178,7 +236,7 @@ function editingAddRow(button, allowed, focus) {
}
var match = /(\d+)(\.\d+)?/.exec(button.name);
var x = match[0] + (match[2] ? added.substr(match[2].length) : added) + '1';
var row = button.parentNode.parentNode;
var row = parentTag(button, 'tr');
var row2 = row.cloneNode(true);
var tags = row.getElementsByTagName('select');
var tags2 = row2.getElementsByTagName('select');
@@ -224,7 +282,7 @@ function editingAddRow(button, allowed, focus) {
function editingRemoveRow(button) {
var field = formField(button.form, button.name.replace(/drop_col(.+)/, 'fields$1[field]'));
field.parentNode.removeChild(field);
button.parentNode.parentNode.style.display = 'none';
parentTag(button, 'tr').style.display = 'none';
return true;
}
@@ -310,9 +368,9 @@ function partitionByChange(el) {
* @param HTMLInputElement
*/
function partitionNameChange(el) {
var row = el.parentNode.parentNode.cloneNode(true);
var row = parentTag(el, 'tr').cloneNode(true);
row.firstChild.firstChild.value = '';
el.parentNode.parentNode.parentNode.appendChild(row);
parentTag(el, 'table').appendChild(row);
el.onchange = function () {};
}
@@ -323,13 +381,13 @@ function partitionNameChange(el) {
*/
function foreignAddRow(field) {
field.onchange = function () { };
var row = field.parentNode.parentNode.cloneNode(true);
var row = parentTag(field, 'tr').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);
parentTag(field, 'table').appendChild(row);
}
@@ -339,8 +397,7 @@ function foreignAddRow(field) {
*/
function indexesAddRow(field) {
field.onchange = function () { };
var parent = field.parentNode.parentNode;
var row = parent.cloneNode(true);
var row = parentTag(field, 'tr').cloneNode(true);
var selects = row.getElementsByTagName('select');
for (var i=0; i < selects.length; i++) {
selects[i].name = selects[i].name.replace(/indexes\[\d+/, '$&1');
@@ -351,7 +408,7 @@ function indexesAddRow(field) {
inputs[i].name = inputs[i].name.replace(/indexes\[\d+/, '$&1');
inputs[i].value = '';
}
parent.parentNode.appendChild(row);
parentTag(field, 'table').appendChild(row);
}
/** Change column in index
@@ -359,7 +416,7 @@ function indexesAddRow(field) {
* @param string name prefix
*/
function indexesChangeColumn(field, prefix) {
var columns = field.parentNode.parentNode.getElementsByTagName('select');
var columns = parentTag(field, 'td').getElementsByTagName('select');
var names = [];
for (var i=0; i < columns.length; i++) {
var value = selectValue(columns[i]);
@@ -390,7 +447,7 @@ function indexesAddColumn(field, prefix) {
var input = column.getElementsByTagName('input')[0];
input.name = input.name.replace(/\]\[\d+/, '$&1');
input.value = '';
field.parentNode.parentNode.appendChild(column);
parentTag(field, 'td').appendChild(column);
field.onchange();
}

View File

@@ -38,11 +38,24 @@ function selectValue(select) {
return ((selected.attributes.value || {}).specified ? selected.value : selected.text);
}
/** Get parent node with specified tag name.
* @param HTMLElement
* @param string
* @return HTMLElement
*/
function parentTag(el, tag) {
var re = new RegExp('^' + tag + '$', 'i');
while (!re.test(el.tagName)) {
el = el.parentNode;
}
return el;
}
/** Set checked class
* @param HTMLInputElement
*/
function trCheck(el) {
var tr = el.parentNode.parentNode;
var tr = parentTag(el, 'tr');
tr.className = tr.className.replace(/(^|\s)checked(\s|$)/, '$2') + (el.checked ? ' checked' : '');
}
@@ -135,7 +148,7 @@ function checkboxClick(event, el) {
}
if (event.shiftKey && (!lastChecked || lastChecked.name == el.name)) {
var checked = (lastChecked ? lastChecked.checked : true);
var inputs = el.parentNode.parentNode.parentNode.getElementsByTagName('input');
var inputs = parentTag(el, 'table').getElementsByTagName('input');
var checking = !lastChecked;
for (var i=0; i < inputs.length; i++) {
var input = inputs[i];
@@ -152,8 +165,9 @@ function checkboxClick(event, el) {
}
}
}
} else {
lastChecked = el;
}
lastChecked = el;
}
/** Set HTML code of an element
@@ -197,6 +211,26 @@ function pageClick(href, page, event) {
/** Display items in menu
* @param HTMLElement
* @param MouseEvent
*/
function menuOver(el, event) {
var a = event.target;
if (/^a$/i.test(a.tagName) && a.offsetLeft + a.offsetWidth > a.parentNode.offsetWidth) {
el.style.overflow = 'visible';
}
}
/** Hide items in menu
* @param HTMLElement
*/
function menuOut(el) {
el.style.overflow = 'auto';
}
/** Add row in select fieldset
* @param HTMLSelectElement
*/
@@ -220,44 +254,41 @@ function selectAddRow(field) {
field.parentNode.parentNode.appendChild(row);
}
/** Check whether the query will be executed with index
* @param HTMLFormElement
*/
function selectFieldChange(form) {
var ok = (function () {
var inputs = form.getElementsByTagName('input');
for (var i=0; i < inputs.length; i++) {
var input = inputs[i];
if (/^fulltext/.test(input.name) && input.value) {
return true;
}
/** Toggles column context menu
* @param HTMLElement
* @param [string] extra class name
*/
function columnMouse(el, className) {
var spans = el.getElementsByTagName('span');
for (var i=0; i < spans.length; i++) {
if (/column/.test(spans[i].className)) {
spans[i].className = 'column' + (className || '');
}
var ok = true;
var selects = form.getElementsByTagName('select');
for (var i=0; i < selects.length; i++) {
var select = selects[i];
var col = selectValue(select);
var match = /^(where.+)col\]/.exec(select.name);
if (match) {
var op = selectValue(form[match[1] + 'op]']);
var val = form[match[1] + 'val]'].value;
if (col in indexColumns && (!/LIKE|REGEXP/.test(op) || (op == 'LIKE' && val.charAt(0) != '%'))) {
return true;
} else if (col || val) {
ok = false;
}
}
//! take grouping in select into account
if (col && /^order/.test(select.name)) {
if (!(col in indexColumns)) {
ok = false;
}
break;
}
}
}
/** Fill column in search field
* @param string
*/
function selectSearch(name) {
var el = document.getElementById('fieldset-search');
el.className = '';
var divs = el.getElementsByTagName('div');
for (var i=0; i < divs.length; i++) {
var div = divs[i];
if (/select/i.test(div.firstChild.tagName) && selectValue(div.firstChild) == name) {
break;
}
return ok;
})();
setHtml('noindex', (ok ? '' : '!'));
}
if (i == divs.length) {
div.firstChild.value = name;
div.firstChild.onchange();
}
div.lastChild.focus();
}
@@ -281,6 +312,20 @@ function bodyKeydown(event, button) {
return true;
}
/** Open form to a new window on Ctrl+click or Shift+click
* @param MouseEvent
*/
function bodyClick(event) {
var target = event.target || event.srcElement;
if ((event.ctrlKey || event.shiftKey) && target.type == 'submit' && /input/i.test(target.tagName)) {
target.form.target = '_blank';
setTimeout(function () {
// if (event.ctrlKey) { focus(); } doesn't work
target.form.target = '';
}, 0);
}
}
/** Change focus by Ctrl+Up or Ctrl+Down
@@ -372,6 +417,7 @@ function selectDblClick(td, event, text) {
return;
}
var original = td.innerHTML;
text = text || /\n/.test(original);
var input = document.createElement(text ? 'textarea' : 'input');
input.onkeydown = function (event) {
if (!event) {
@@ -426,6 +472,38 @@ function selectDblClick(td, event, text) {
/** Load and display next page in select
* @param HTMLLinkElement
* @param string
* @param number
* @return boolean
*/
function selectLoadMore(a, limit, loading) {
var title = a.innerHTML;
var href = a.href;
a.innerHTML = loading;
if (href) {
a.removeAttribute('href');
return ajax(href, function (request) {
document.getElementById('table').innerHTML += request.responseText;
var rows = 0;
request.responseText.replace(/(^|\n)<tr/g, function () {
rows++;
});
if (rows < limit) {
a.parentNode.removeChild(a);
} else {
a.href = href.replace(/\d+$/, function (page) {
return +page + 1;
});
a.innerHTML = title;
}
});
}
}
/** Stop event propagation
* @param Event
*/

View File

@@ -58,9 +58,7 @@ if ($fields) {
echo "(<i>" . implode("</i>, <i>", array_map('h', $foreign_key["target"])) . "</i>)";
echo "<td>" . nbsp($foreign_key["on_delete"]) . "\n";
echo "<td>" . nbsp($foreign_key["on_update"]) . "\n";
if ($jush != "sqlite") {
echo '<td><a href="' . h(ME . 'foreign=' . urlencode($TABLE) . '&name=' . urlencode($name)) . '">' . lang('Alter') . '</a>';
}
echo ($jush == "sqlite" ? "" : '<td><a href="' . h(ME . 'foreign=' . urlencode($TABLE) . '&name=' . urlencode($name)) . '">' . lang('Alter') . '</a>');
}
echo "</table>\n";
}

View File

@@ -1,3 +1,30 @@
Adminer 3.6.0 (released 2012-09-16):
Load more data in select
Edit strings with \n in textarea
Time out long running database list and select count
Use VALUES() in INSERT+UPDATE export
Style logout button as link
Store selected database to permanent login
Ctrl+click and Shift+click on button opens form to a blank window
Switch language by POST
Compress translations
MySQL: Support geometry data types
selectQueryBuild() method (customization)
Serbian translation
Adminer 3.5.1 (released 2012-08-10):
Support same name fields in CSV export
Support Shift+click in export
Adminer 3.5.0 (released 2012-08-05):
Links for column search in select
Autohide column context menu in select
Autodisplay long table names in tables list
Display assigned auto_increment after clone
SQLite: Full alter table
SQLite: Better editing in tables without primary key
SQLite: Display number of rows in database overview
Adminer 3.4.0 (released 2012-06-30):
Link to descending order
Shift+click on checkbox to select consecutive rows

View File

@@ -4,16 +4,14 @@ error_reporting(6135); // errors and warnings
include dirname(__FILE__) . "/adminer/include/version.inc.php";
include dirname(__FILE__) . "/externals/JsShrink/jsShrink.php";
if (!function_exists('jsShrink')) {
function jsShrink($code) {
return $code;
}
}
function add_apo_slashes($s) {
return addcslashes($s, "\\'");
}
function add_quo_slashes($s) {
return addcslashes($s, "\n\r\$\"\\");
}
function remove_lang($match) {
global $translations;
$idf = strtr($match[2], array("\\'" => "'", "\\\\" => "\\"));
@@ -61,6 +59,43 @@ function lang(\$translation, \$number) {
}
}
function lzw_compress($string) {
// compression
$dictionary = array_flip(range("\0", "\xFF"));
$word = "";
$codes = array();
for ($i=0; $i <= strlen($string); $i++) {
$x = $string[$i];
if (strlen($x) && isset($dictionary[$word . $x])) {
$word .= $x;
} elseif ($i) {
$codes[] = $dictionary[$word];
$dictionary[$word . $x] = count($dictionary);
$word = $x;
}
}
// convert codes to binary string
$dictionary_count = 256;
$bits = 8; // ceil(log($dictionary_count, 2))
$return = "";
$rest = 0;
$rest_length = 0;
foreach ($codes as $code) {
$rest = ($rest << $bits) + $code;
$rest_length += $bits;
$dictionary_count++;
if ($dictionary_count >> $bits) {
$bits++;
}
while ($rest_length > 7) {
$rest_length -= 8;
$return .= chr($rest >> $rest_length);
$rest &= (1 << $rest_length) - 1;
}
}
return $return . ($rest_length ? chr($rest << (8 - $rest_length)) : "");
}
function put_file_lang($match) {
global $lang_ids, $project, $langs;
if ($_SESSION["lang"]) {
@@ -72,16 +107,27 @@ function put_file_lang($match) {
$translation_ids = array_flip($lang_ids); // default translation
foreach ($translations as $key => $val) {
if ($val !== null) {
$translation_ids[$lang_ids[$key]] = $val;
$translation_ids[$lang_ids[$key]] = implode("\t", (array) $val);
}
}
$return .= "\tcase \"$lang\": \$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 .= '
case "' . $lang . '": $compressed = "' . add_quo_slashes(lzw_compress(implode("\n", $translation_ids))) . '"; break;';
}
return "switch (\$LANG) {\n$return}\n";
$translations_version = crc32($return);
return '$translations = &$_SESSION["translations"];
if ($_SESSION["translations_version"] != ' . $translations_version . ') {
$translations = array();
$_SESSION["translations_version"] = ' . $translations_version . ';
}
if (!$translations) {
switch ($LANG) {' . $return . '
}
$translations = array();
foreach (explode("\n", lzw_decompress($compressed)) as $val) {
$translations[] = (strpos($val, "\t") ? explode("\t", $val) : $val);
}
}
';
}
function short_identifier($number, $chars) {
@@ -145,7 +191,7 @@ function php_shrink($input) {
$short_variables[$key] = short_identifier($number, $chars); // could use also numbers and \x7f-\xff
}
$set = array_flip(preg_split('//', '!"#$&\'()*+,-./:;<=>?@[\]^`{|}'));
$set = array_flip(preg_split('//', '!"#$%&\'()*+,-./:;<=>?@[\]^`{|}'));
$space = '';
$output = '';
$in_echo = false;
@@ -155,10 +201,10 @@ function php_shrink($input) {
$token = array(0, $token);
}
if ($tokens[$i+2][0] === T_CLOSE_TAG && $tokens[$i+3][0] === T_INLINE_HTML && $tokens[$i+4][0] === T_OPEN_TAG
&& strlen(addcslashes($tokens[$i+3][1], "'\\")) < strlen($tokens[$i+3][1]) + 3
&& strlen(add_apo_slashes($tokens[$i+3][1])) < strlen($tokens[$i+3][1]) + 3
) {
$tokens[$i+2] = array(T_ECHO, 'echo');
$tokens[$i+3] = array(T_CONSTANT_ENCAPSED_STRING, "'" . addcslashes($tokens[$i+3][1], "'\\") . "'");
$tokens[$i+3] = array(T_CONSTANT_ENCAPSED_STRING, "'" . add_apo_slashes($tokens[$i+3][1]) . "'");
$tokens[$i+4] = array(0, ';');
}
if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE || ($token[0] == T_DOC_COMMENT && $doc_comment)) {
@@ -202,12 +248,27 @@ function php_shrink($input) {
}
function minify_css($file) {
return preg_replace('~\\s*([:;{},])\\s*~', '\\1', preg_replace('~/\\*.*\\*/~sU', '', $file));
return lzw_compress(preg_replace('~\\s*([:;{},])\\s*~', '\\1', preg_replace('~/\\*.*\\*/~sU', '', $file)));
}
function minify_js($file) {
$file = str_replace("'../externals/jush/'", "location.protocol + '//www.adminer.org/static/'", $file);
if (function_exists('jsShrink')) {
$file = jsShrink($file);
}
return lzw_compress($file);
}
function compile_file($match) {
global $project;
return call_user_func($match[2], file_get_contents(dirname(__FILE__) . "/$project/$match[1]"));
$file = "";
foreach (explode(";", $match[1]) as $filename) {
$file .= file_get_contents(dirname(__FILE__) . "/$project/$filename");
}
if ($match[2]) {
$file = call_user_func($match[2], $file);
}
return '"' . add_quo_slashes($file) . '"';
}
$driver = "";
@@ -237,7 +298,7 @@ foreach (glob(dirname(__FILE__) . "/adminer/drivers/" . ($driver ? $driver : "*"
$file = file_get_contents($filename);
foreach ($functions as $val) {
if (!strpos($file, "$val(")) {
echo "Missing $val in $filename\n";
fprintf(STDERR, "Missing $val in $filename\n");
}
}
}
@@ -290,11 +351,10 @@ foreach (array("adminer", "editor") as $project) {
$file = str_replace('<?php echo $LANG; ?>', $_SESSION["lang"], $file);
}
$file = str_replace('<script type="text/javascript" src="static/editing.js"></script>' . "\n", "", $file);
$file = preg_replace_callback("~compile_file\\('([^']+)', '([^']+)'\\);~", 'compile_file', $file); // integrate static files
$file = preg_replace_callback("~compile_file\\('([^']+)'(?:, '([^']*)')?\\)~", 'compile_file', $file); // integrate static files
$replace = 'h(preg_replace("~\\\\\\\\?.*~", "", ME)) . "?file=\\1&amp;version=' . $VERSION;
$file = preg_replace('~\\.\\./adminer/static/(default\\.css|functions\\.js|favicon\\.ico)~', '<?php echo ' . $replace . '"; ?>', $file);
$file = preg_replace('~\\.\\./adminer/static/([^\'"]*)~', '" . ' . $replace, $file);
$file = str_replace("'../externals/jush/'", "location.protocol + '//www.adminer.org/static/'", $file);
$file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file);
$file = php_shrink($file);

View File

@@ -56,3 +56,7 @@ outline:0;background:url(http://www.bradezone.com/random/adminer_logo.gif) no-re
* html #lang,* html #menu,* html #breadcrumb{position:absolute}
* html #lang{padding-top:10px;height:30px}
* html form#form{height:100%}
#logins a,#tables a{background: none}
#logout{color:#333;text-decoration:none;border-bottom:1px dotted}
#logout:hover{border-color:#333;background:#333;color:#fff}
.js .column{background:#ddd}

View File

@@ -285,12 +285,9 @@ position: absolute;
#schema .references {
position: absolute;
}
.js .hidden {
.js div.hidden {
display: inline;
}
.js td.hidden, .js input.hidden {
display: none;
}
legend a {
color: #333;
text-decoration: none;
@@ -325,4 +322,17 @@ border-bottom-left-radius: 5px;
-khtml-border-top-right-radius: 5px;
-webkit-border-top-right-radius: 5px;
border-bottom-top-radius: 5px;
}
}
.js .column {
background: #DFDFDF;
}
#logout {
color: #21759B;
}
#logout:hover {
text-decoration: none;
}
#logins a, #tables a {
background: #F1F1F1;
line-height: 1.5em;
}

View File

@@ -2,11 +2,11 @@
/* So I merged them into one file, fixed a couple of problems, added some paddings here and there, voila!
/* Redesigned (iconized) by Hever [hev.cz] - June 2009, ver 0.1.3 */
/**
/**
* Alternative style for Adminer by Frank Bueltge
* @link http://bueltge.de/
*/
/* Added icons */
/* IE doesn't support inline images - using some hack that eliminate IE*/
html/*\*/>/*/*/body .error {background:#FFEEEE url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIsSURBVDjLpVNLSJQBEP7+h6uu62vLVAJDW1KQTMrINQ1vPQzq1GOpa9EppGOHLh0kCEKL7JBEhVCHihAsESyJiE4FWShGRmauu7KYiv6Pma+DGoFrBQ7MzGFmPr5vmDFIYj1mr1WYfrHPovA9VVOqbC7e/1rS9ZlrAVDYHig5WB0oPtBI0TNrUiC5yhP9jeF4X8NPcWfopoY48XT39PjjXeF0vWkZqOjd7LJYrmGasHPCCJbHwhS9/F8M4s8baid764Xi0Ilfp5voorpJfn2wwx/r3l77TwZUvR+qajXVn8PnvocYfXYH6k2ioOaCpaIdf11ivDcayyiMVudsOYqFb60gARJYHG9DbqQFmSVNjaO3K2NpAeK90ZCqtgcrjkP9aUCXp0moetDFEeRXnYCKXhm+uTW0CkBFu4JlxzZkFlbASz4CQGQVBFeEwZm8geyiMuRVntzsL3oXV+YMkvjRsydC1U+lhwZsWXgHb+oWVAEzIwvzyVlk5igsi7DymmHlHsFQR50rjl+981Jy1Fw6Gu0ObTtnU+cgs28AKgDiy+Awpj5OACBAhZ/qh2HOo6i+NeA73jUAML4/qWux8mt6NjW1w599CS9xb0mSEqQBEDAtwqALUmBaG5FV3oYPnTHMjAwetlWksyByaukxQg2wQ9FlccaK/OXA3/uAEUDp3rNIDQ1ctSk6kHh1/jRFoaL4M4snEMeD73gQx4M4PsT1IZ5AfYH68tZY7zv/ApRMY9mnuVMvAAAAAElFTkSuQmCC") no-repeat scroll 0.8em center; padding-left:38px;}
@@ -21,9 +21,7 @@ html/*\*/>/*/*/body select[name="db"] option {padding-left:18px;}
html/*\*/>/*/*/body #menu p a[href*="&select="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHkm9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1zztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wGhGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUHYJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWluUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhNTWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7nHADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGFrwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=") no-repeat scroll left bottom; clear:left; display:block; float:left; height:16px; margin-right:8px; padding-top:1px; overflow:hidden; padding-left:16px; width:0; text-decoration:none;}
html/*\*/>/*/*/body #menu p a[href*="&table="], html/*\*/>/*/*/body #menu p a[href*="&view="] {clear:right; margin-left:24px; display:block; height:17px; padding-bottom:1px; text-decoration:none;}
html/*\*/>/*/*/body #menu p#tables br {display:none;}
html/*\*/>/*/*/body #menu p a[href*="&table="], html/*\*/>/*/*/body #menu p a[href*="&view="] {margin:0; line-height:18px; padding-bottom:1px; text-decoration:none;}
html/*\*/>/*/*/body a[href*="&create="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ6SURBVDjLpZNZSNRRGMV//2XGsjFrMg2z0so2K21xIFpepYUiAsGIICLffI8eWiBBeg3qQV+KwBYKLB8qpHUmrahcKLc0QsxldNSxdPz/79LD1ChBUXTh8sG93POdc75zDa01/7NsgGvPR09rzQmpVZZSCqlAKIWUCqk0QqoZWyKFRir1uvxIbsAGUFqXHQqkpP1L57M3Pm5MMJBKpQHUdF9BKIGQAlcJXOlOVykSdye3leO6MmkGQNyHw+uO/1X3bzGBK+S0B1IqAKqDg3986HeCZPffwvJtoNT7lOZLvUdtAPEDAKBkRzo3QwMUb89InN1uGGD3spdE214xe8MRUnM2MfppNW0Pqy7YAK5UKK2xLbhdP4hlmdxpGMQwwQT8ziNiI534c7cT6WrFazikzF2Eb8HS1IQEDdiWwcHAQmpehTkQSAcgNvSMiYFW5uUUMdV3HW+ywefGNqITJsbUUL75k4FWYJtQ+yaMZcXrk1ANk/33mbdiD7EvlRieETy+FJLkMFcjRRSW3emIAwiF1hqPBfu2LGSWbbA1uZ41SfWkrtxPrPcypsfFiWYzFGzGKTjFV28WEJeIUHETLdOgrmkI1VdHpCdEet5enP4qLK9mKrqMgedv6cyrAP+qxOTiUxAi7oEJi8frELoFoTLpa7nI/HQvscgSRt+0kV1SSW7qYtp7xrBMphm4Mi5h/VIfTcEq1u0oJaknSEdNiMYHET7UvcMpPEN31Ed7zxgASmk1I0g6dK66s8CRak5mVxjnfS05+TsZCw/T9baTx1nnGb47DrQksjE6HrsHYPz6nYt3+Sc3L8+wA2tz0J6pF5OD4WP7Kpq7f5fO79DfSxjdtCtDAAAAAElFTkSuQmCC") no-repeat scroll 2px bottom; padding-left:22px;}
html/*\*/>/*/*/body a[href$="&create="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIpSURBVDjLpZNPSFRRFMZ/749/Kt3IqFTSRoSMmrGIYTTbpEJtjBCCok1Em9JVG1dRC8FFEES5aGFEgRRZWq1iLKKxBiNqLDcltQgmHR9hY6LOu+feFm+YGVsZXbh8nHO53/nud8+xjDH8z3IB7r5avGgMZ8XoBq01okFpjYhGtEGJLtmCKINo/XbgVFPUBdDG9PVEq0P/UvnSvdlwQYFoHQIY/3obpRVKFL5W+OIXUVThrL91AN+XihKCwIeTu85sqPryqsJXUvRARAMwkshsiKB7fw25UgKVJwA40V7H/cl5jh+oL+RGk/P0xIqxl11dr8AXjTYG14HRNxkcx+ZhMoNlg52/ND6VAWMoc6F5+2Zy/l9PMIDrWByL1jI+tcDRaN06BaXxbDqLUnq9AqPBteHpuwUcJ0AIcgBXH93h+/wEyyuLrPk5cmv7gNY8gdIYYyhz4PDeWuIpj85IsS2ujQ2zJAk6DkZpqGnixcwYyU+PifUOX7Eh6DoAx7aIpzwA4imPeMrj+bTH+88PaNkZQWwhsrULsXxie9oAzgcESgUe2NAZCeE6AXZGQhwKh/Cyc5RZVXQ39wFwoeMmjXVhgMqiB8awe0cVP36u0Fi/iW9zvwuzkF3+xUz6Nal0gv6uWww+O02lUwGwmv8FM3l55EtLTvQWXwm+EkRpfNEoUZRXHCE5PUFbuJ0nH4cot1wSH14C3LA2Os6x3m2DwDmgGlgChpLX0/1/AIu8MA7WsWBMAAAAAElFTkSuQmCC") no-repeat scroll left bottom; padding-left:22px;}
@@ -53,7 +51,8 @@ html/*\*/>/*/*/body table thead input {margin-right: 5px;}
html/*\*/>/*/*/body input[name="delete"], html/*\*/>/*/*/body input[name="drop"] {background:transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHSSURBVHjapFM5bsJQEB2zSIDFJrHYpEtyAyoKJAp6CrqIkBPkNDlBAKXjBEgUpKOBCyQNijFiEZvZl8z7wsjESYpkpNFfPO/Nmz9j6Xg80n/M9fWi3W7fMOnd4XAo8qogAbvO5xKvL6lU6s0aL1kVMDjP5ye/36+Gw2FyOp3EQFqtVtTr9WixWHT5/JhOp6s2ghP4ORaLyaFQiGazGa3Xa0HgdrvJ6/WSpmk0Go0MjnvIZDLVM0Gr1brm/WskEkkA3O/3abvdQjq5XC6xgoiVka7rNB6PNT6ns9nsu+OkpODxeBLBYJAGgwHt9/uzQ8Vms6Hdbie+KYqC+ASTFrARBMx2HwgEaDKZiHqn0yktl0uxtzrMMAyKx+MCc+4Cs13hwQCC1GQy+W3Lms2mUIUygbEqEBLNun8z8zswVgUfLO0WD4Z6kekn8/l8okNM8GFVUMYDoVWQ6HA4bEAzoyzL1O12kbRsJajwhYZhiUajJEnShWSAQaqqKnU6HahEGysXg9RoNPJ8+cwZZLSKp47m8/k5Kxzg4XBocNxDLper2ka5Xq+LUeatilahJLN1mEJ+ZDHKJthGAKvVauJnYi9ysHIqQee1xOsLg3/+mf5inwIMAJMhb74NwG5wAAAAAElFTkSuQmCC") no-repeat scroll left center; padding:1px 5px 1px 18px; border:0; cursor:pointer; font-size:.9em;}
html/*\*/>/*/*/body input[name="delete"]:hover, html/*\*/>/*/*/body input[name="drop"]:hover {color:red; background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJdSURBVDjLpZP7S1NhGMf9W7YfogSJboSEUVCY8zJ31trcps6zTI9bLGJpjp1hmkGNxVz4Q6ildtXKXzJNbJRaRmrXoeWx8tJOTWptnrNryre5YCYuI3rh+8vL+/m8PA/PkwIg5X+y5mJWrxfOUBXm91QZM6UluUmthntHqplxUml2lciF6wrmdHriI0Wx3xw2hAediLwZRWRkCPzdDswaSvGqkGCfq8VEUsEyPF1O8Qu3O7A09RbRvjuIttsRbT6HHzebsDjcB4/JgFFlNv9MnkmsEszodIIY7Oaut2OJcSF68Qx8dgv8tmqEL1gQaaARtp5A+N4NzB0lMXxon/uxbI8gIYjB9HytGYuusfiPIQcN71kjgnW6VeFOkgh3XcHLvAwMSDPohOADdYQJdF1FtLMZPmslvhZJk2ahkgRvq4HHUoWHRDqTEDDl2mDkfheiDgt8pw340/EocuClCuFvboQzb0cwIZgki4KhzlaE6w0InipbVzBfqoK/qRH94i0rgokSFeO11iBkp8EdV8cfJo0yD75aE2ZNRvSJ0lZKcBXLaUYmQrCzDT6tDN5SyRqYlWeDLZAg0H4JQ+Jt6M3atNLE10VSwQsN4Z6r0CBwqzXesHmV+BeoyAUri8EyMfi2FowXS5dhd7doo2DVII0V5BAjigP89GEVAtda8b2ehodU4rNaAW+dGfzlFkyo89GTlcrHYCLpKD+V7yeeHNzLjkp24Uu1Ed6G8/F8qjqGRzlbl2H2dzjpMg1KdwsHxOlmJ7GTeZC/nesXbeZ6c9OYnuxUc3fmBuFft/Ff8xMd0s65SXIb/gAAAABJRU5ErkJggg==")}
html/*\*/>/*/*/body input[name="logout"]{ height:16px; border: none; position: absolute; top: 0; left: 140px; margin-top: 8px; background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJHSURBVDjLlZPNi81hFMc/z7137p1mTCFvNZfGSzLIWNjZKRvFRoqNhRCSYm8xS3+AxRRZ2JAFJWJHSQqTQkbEzYwIM+6Yid/znJfH4prLXShOnb6r8/nWOd8Tcs78bz0/f+KMu50y05nK/wy+uHDylbutqS5extvGcxaWqtoGDA8PZ3dnrs2srQc2Zko41UXLmLdyDW5OfvsUkUgbYGbU63UAQggdmvMzFmzZCgTi7CQmkZwdEaX0JwDgTnGbTCaE0G4zw80omhPI92lcEtkNkdgJCCHwJX7mZvNaB0A14SaYJlwTrpHsTkoFlV1nt2c3x5YYo1/vM9A/gKpxdfwyu/v3teCayKq4JEwT5EB2R6WgYmrs2bYbcUNNUVfEhIfFYy69uci+1fuRX84mkawFSxd/4nVWUopUVIykwlQxRTJBTIDA4Pp1jBZPuNW4wUAPmCqWIn29X1k4f5Ku8g9mpKCkakRLVEs1auVuauVuyqHMo8ejNCe+sWPVTkQKXCMmkeZUmUZjETF1tc6ooly+fgUVw9So1/tRN6YnZji46QghBFKKuAouERNhMlbAHZFE6e7pB+He8MMw+GGI4xtOMf1+lsl3TQ4NHf19BSlaO1DB9BfMHdX0O0iqSgiBbJkjm491hClJbA1LxCURgpPzXwAHhg63necAIi3XngXLcRU0fof8ETMljIyM5LGxMcbHxzvy/6fuXdWgt6+PWncv1e4euqo1ZmabvHs5+jn8yzufO7hiiZmuNpNBM13rbvVSpbrXJE7/BMkHtU9jFIC/AAAAAElFTkSuQmCC") no-repeat center left; overflow: hidden; text-indent: 12px; line-height: 0px; cursor:pointer; }
html/*\*/>/*/*/body input[name="logout"], #logout{ height:16px; border: none; position: absolute; top: 0; left: 140px; margin-top: 8px; background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJHSURBVDjLlZPNi81hFMc/z7137p1mTCFvNZfGSzLIWNjZKRvFRoqNhRCSYm8xS3+AxRRZ2JAFJWJHSQqTQkbEzYwIM+6Yid/znJfH4prLXShOnb6r8/nWOd8Tcs78bz0/f+KMu50y05nK/wy+uHDylbutqS5extvGcxaWqtoGDA8PZ3dnrs2srQc2Zko41UXLmLdyDW5OfvsUkUgbYGbU63UAQggdmvMzFmzZCgTi7CQmkZwdEaX0JwDgTnGbTCaE0G4zw80omhPI92lcEtkNkdgJCCHwJX7mZvNaB0A14SaYJlwTrpHsTkoFlV1nt2c3x5YYo1/vM9A/gKpxdfwyu/v3teCayKq4JEwT5EB2R6WgYmrs2bYbcUNNUVfEhIfFYy69uci+1fuRX84mkawFSxd/4nVWUopUVIykwlQxRTJBTIDA4Pp1jBZPuNW4wUAPmCqWIn29X1k4f5Ku8g9mpKCkakRLVEs1auVuauVuyqHMo8ejNCe+sWPVTkQKXCMmkeZUmUZjETF1tc6ooly+fgUVw9So1/tRN6YnZji46QghBFKKuAouERNhMlbAHZFE6e7pB+He8MMw+GGI4xtOMf1+lsl3TQ4NHf19BSlaO1DB9BfMHdX0O0iqSgiBbJkjm491hClJbA1LxCURgpPzXwAHhg63necAIi3XngXLcRU0fof8ETMljIyM5LGxMcbHxzvy/6fuXdWgt6+PWncv1e4euqo1ZmabvHs5+jn8yzufO7hiiZmuNpNBM13rbvVSpbrXJE7/BMkHtU9jFIC/AAAAAElFTkSuQmCC") no-repeat center left; text-indent: 16px; color: #21759B; }
#logout:hover { color: #D54E21; text-decoration: none; }
body {margin: 0; line-height: 1.25em; font-size: 13px; background: #F9F9F9;}
body, select, option, optgroup, button {font-family: "Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;} /* IE6 */
@@ -100,39 +99,25 @@ img {vertical-align: middle; margin: 0; padding: 0;}
.jush-sql {padding: 2px 4px; margin-right: 4px; outline: 1px #BBB dashed; font-size: 9pt;}
#content {margin: 2px 0 0 260px; padding: 10px 20px 20px 0;}
#breadcrumb, #lang {margin: 0; height: 21px; display: block; position: absolute; top: 0; left: 260px; background-color: #f1f1f1; border: 1px solid #E3E3E3; padding: 2px 12px; line-height: 1.25em }
#lang {
right: 20px;
left: auto;
z-index: 10;
}
#lang {right: 20px; left: auto; z-index: 10; }
#lang select {font-size: 8pt;}
#menu {position: absolute; padding: 10px; margin: 0; top: 0; left: 0; width: 220px; background-color: #f1f1f1; border: 1px solid #E3E3E3;}
#menu form {margin: 0;}
#menu p {padding-left: 8px; font-size: 10pt; border-bottom: none;}
#menu form p {padding-left: 0; text-align: left;}
h1 .h1:hover {text-decoration: underline;}
h1 .h1:hover {text-decoration: underline;}
h1, h2 {font: italic normal normal 24px/29px Georgia, "Times New Roman", "Bitstream Charter", Times, serif; margin: 0; padding: 14px 15px 3px 10px; line-height: 35px; text-shadow: rgba(255,255,255,1) 0 1px 0px; background: none;}
h1 {font-size: 12px;}
h1 .h1 {font-size: 12px;}
h2 {padding: 22px 0 0 10px; font-size: 0; height: 2px;}
h3 {margin: 40px 0 0; font-weight: 400; font-size: 130%;}
#menu h1 {
height: 25px;
padding: 0 10px;
margin: 0;
line-height: 20px;
display: block;
}
#menu h1 a {
font-size: 13px;
}
#menu h1 {height: 25px; padding: 0 10px; margin: 0; line-height: 20px; display: block; }
#menu h1 a { font-size: 13px; }
#schema {margin: 1.5em 0 0 220px; position: relative;}
#schema .table {border: 1px solid #E3E3E3; background-color: #F1F1F1; padding: 0 2px; cursor: move; position: absolute;}
#schema .references {position: absolute;}
.js .hidden {display: inline;}
.js .column {background: none; margin: 0; padding: 0; position: relative; }
.js td.hidden, .js input.hidden {display: none;}
legend a {color: #333; text-decoration: none; cursor: default;}
legend a:hover {color: #333;}
@@ -141,3 +126,4 @@ fieldset, legend, table, .error, .message {-moz-border-radius: 5px; -khtml-borde
#breadcrumb, #lang, #menu {-moz-border-radius-bottomright: 5px; -khtml-border-bottom-right-radius: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px;}
#breadcrumb, #lang {-moz-border-radius-bottomleft: 5px; -khtml-border-bottom-left-radius: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px;}
#menu {-moz-border-radius-topright: 5px; -khtml-border-top-right-radius: 5px; -webkit-border-top-right-radius: 5px; border-bottom-top-radius: 5px;}
#logins a, #tables a {background: #F1F1F1;}

View File

@@ -17,7 +17,7 @@ html/*\*/>/*/*/body #menu p a[href*="&select="] {background:url("data:image/png;
html/*\*/>/*/*/body #menu p a[href*="&table="], html/*\*/>/*/*/body #menu p a[href*="&view="] {clear:right; margin-left:24px; display:block; height:17px; padding-bottom:1px; text-decoration:none;}
html/*\*/>/*/*/body #menu p br {display:none;}
html/*\*/>/*/*/body #tables br {display:none;}
html/*\*/>/*/*/body a[href*="&create="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ6SURBVDjLpZNZSNRRGMV//2XGsjFrMg2z0so2K21xIFpepYUiAsGIICLffI8eWiBBeg3qQV+KwBYKLB8qpHUmrahcKLc0QsxldNSxdPz/79LD1ChBUXTh8sG93POdc75zDa01/7NsgGvPR09rzQmpVZZSCqlAKIWUCqk0QqoZWyKFRir1uvxIbsAGUFqXHQqkpP1L57M3Pm5MMJBKpQHUdF9BKIGQAlcJXOlOVykSdye3leO6MmkGQNyHw+uO/1X3bzGBK+S0B1IqAKqDg3986HeCZPffwvJtoNT7lOZLvUdtAPEDAKBkRzo3QwMUb89InN1uGGD3spdE214xe8MRUnM2MfppNW0Pqy7YAK5UKK2xLbhdP4hlmdxpGMQwwQT8ziNiI534c7cT6WrFazikzF2Eb8HS1IQEDdiWwcHAQmpehTkQSAcgNvSMiYFW5uUUMdV3HW+ywefGNqITJsbUUL75k4FWYJtQ+yaMZcXrk1ANk/33mbdiD7EvlRieETy+FJLkMFcjRRSW3emIAwiF1hqPBfu2LGSWbbA1uZ41SfWkrtxPrPcypsfFiWYzFGzGKTjFV28WEJeIUHETLdOgrmkI1VdHpCdEet5enP4qLK9mKrqMgedv6cyrAP+qxOTiUxAi7oEJi8frELoFoTLpa7nI/HQvscgSRt+0kV1SSW7qYtp7xrBMphm4Mi5h/VIfTcEq1u0oJaknSEdNiMYHET7UvcMpPEN31Ed7zxgASmk1I0g6dK66s8CRak5mVxjnfS05+TsZCw/T9baTx1nnGb47DrQksjE6HrsHYPz6nYt3+Sc3L8+wA2tz0J6pF5OD4WP7Kpq7f5fO79DfSxjdtCtDAAAAAElFTkSuQmCC") no-repeat scroll 2px bottom; padding-left:22px;}
@@ -49,6 +49,6 @@ html/*\*/>/*/*/body table td:first-child {white-space:nowrap;}
html/*\*/>/*/*/body input[name="delete"], html/*\*/>/*/*/body input[name="drop"] {background:transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHSSURBVHjapFM5bsJQEB2zSIDFJrHYpEtyAyoKJAp6CrqIkBPkNDlBAKXjBEgUpKOBCyQNijFiEZvZl8z7wsjESYpkpNFfPO/Nmz9j6Xg80n/M9fWi3W7fMOnd4XAo8qogAbvO5xKvL6lU6s0aL1kVMDjP5ye/36+Gw2FyOp3EQFqtVtTr9WixWHT5/JhOp6s2ghP4ORaLyaFQiGazGa3Xa0HgdrvJ6/WSpmk0Go0MjnvIZDLVM0Gr1brm/WskEkkA3O/3abvdQjq5XC6xgoiVka7rNB6PNT6ns9nsu+OkpODxeBLBYJAGgwHt9/uzQ8Vms6Hdbie+KYqC+ASTFrARBMx2HwgEaDKZiHqn0yktl0uxtzrMMAyKx+MCc+4Cs13hwQCC1GQy+W3Lms2mUIUygbEqEBLNun8z8zswVgUfLO0WD4Z6kekn8/l8okNM8GFVUMYDoVWQ6HA4bEAzoyzL1O12kbRsJajwhYZhiUajJEnShWSAQaqqKnU6HahEGysXg9RoNPJ8+cwZZLSKp47m8/k5Kxzg4XBocNxDLper2ka5Xq+LUeatilahJLN1mEJ+ZDHKJthGAKvVauJnYi9ysHIqQee1xOsLg3/+mf5inwIMAJMhb74NwG5wAAAAAElFTkSuQmCC") no-repeat scroll left center; padding:1px 5px 1px 18px; border:0; cursor:pointer; font-size:.9em;}
html/*\*/>/*/*/body input[name="delete"]:hover, html/*\*/>/*/*/body input[name="drop"]:hover {color:red; background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJdSURBVDjLpZP7S1NhGMf9W7YfogSJboSEUVCY8zJ31trcps6zTI9bLGJpjp1hmkGNxVz4Q6ildtXKXzJNbJRaRmrXoeWx8tJOTWptnrNryre5YCYuI3rh+8vL+/m8PA/PkwIg5X+y5mJWrxfOUBXm91QZM6UluUmthntHqplxUml2lciF6wrmdHriI0Wx3xw2hAediLwZRWRkCPzdDswaSvGqkGCfq8VEUsEyPF1O8Qu3O7A09RbRvjuIttsRbT6HHzebsDjcB4/JgFFlNv9MnkmsEszodIIY7Oaut2OJcSF68Qx8dgv8tmqEL1gQaaARtp5A+N4NzB0lMXxon/uxbI8gIYjB9HytGYuusfiPIQcN71kjgnW6VeFOkgh3XcHLvAwMSDPohOADdYQJdF1FtLMZPmslvhZJk2ahkgRvq4HHUoWHRDqTEDDl2mDkfheiDgt8pw340/EocuClCuFvboQzb0cwIZgki4KhzlaE6w0InipbVzBfqoK/qRH94i0rgokSFeO11iBkp8EdV8cfJo0yD75aE2ZNRvSJ0lZKcBXLaUYmQrCzDT6tDN5SyRqYlWeDLZAg0H4JQ+Jt6M3atNLE10VSwQsN4Z6r0CBwqzXesHmV+BeoyAUri8EyMfi2FowXS5dhd7doo2DVII0V5BAjigP89GEVAtda8b2ehodU4rNaAW+dGfzlFkyo89GTlcrHYCLpKD+V7yeeHNzLjkp24Uu1Ed6G8/F8qjqGRzlbl2H2dzjpMg1KdwsHxOlmJ7GTeZC/nesXbeZ6c9OYnuxUc3fmBuFft/Ff8xMd0s65SXIb/gAAAABJRU5ErkJggg==")}
html/*\*/>/*/*/body input[name="logout"]{ width:16px; height:16px; border: none; background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJHSURBVDjLlZPNi81hFMc/z7137p1mTCFvNZfGSzLIWNjZKRvFRoqNhRCSYm8xS3+AxRRZ2JAFJWJHSQqTQkbEzYwIM+6Yid/znJfH4prLXShOnb6r8/nWOd8Tcs78bz0/f+KMu50y05nK/wy+uHDylbutqS5extvGcxaWqtoGDA8PZ3dnrs2srQc2Zko41UXLmLdyDW5OfvsUkUgbYGbU63UAQggdmvMzFmzZCgTi7CQmkZwdEaX0JwDgTnGbTCaE0G4zw80omhPI92lcEtkNkdgJCCHwJX7mZvNaB0A14SaYJlwTrpHsTkoFlV1nt2c3x5YYo1/vM9A/gKpxdfwyu/v3teCayKq4JEwT5EB2R6WgYmrs2bYbcUNNUVfEhIfFYy69uci+1fuRX84mkawFSxd/4nVWUopUVIykwlQxRTJBTIDA4Pp1jBZPuNW4wUAPmCqWIn29X1k4f5Ku8g9mpKCkakRLVEs1auVuauVuyqHMo8ejNCe+sWPVTkQKXCMmkeZUmUZjETF1tc6ooly+fgUVw9So1/tRN6YnZji46QghBFKKuAouERNhMlbAHZFE6e7pB+He8MMw+GGI4xtOMf1+lsl3TQ4NHf19BSlaO1DB9BfMHdX0O0iqSgiBbJkjm491hClJbA1LxCURgpPzXwAHhg63necAIi3XngXLcRU0fof8ETMljIyM5LGxMcbHxzvy/6fuXdWgt6+PWncv1e4euqo1ZmabvHs5+jn8yzufO7hiiZmuNpNBM13rbvVSpbrXJE7/BMkHtU9jFIC/AAAAAElFTkSuQmCC") no-repeat center left; overflow: hidden; text-indent: 18px; line-height: 0px; cursor:pointer; margin-left:6px;}
html/*\*/>/*/*/body input[name="logout"], #logout{ width:16px; height:16px; border: none; background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJHSURBVDjLlZPNi81hFMc/z7137p1mTCFvNZfGSzLIWNjZKRvFRoqNhRCSYm8xS3+AxRRZ2JAFJWJHSQqTQkbEzYwIM+6Yid/znJfH4prLXShOnb6r8/nWOd8Tcs78bz0/f+KMu50y05nK/wy+uHDylbutqS5extvGcxaWqtoGDA8PZ3dnrs2srQc2Zko41UXLmLdyDW5OfvsUkUgbYGbU63UAQggdmvMzFmzZCgTi7CQmkZwdEaX0JwDgTnGbTCaE0G4zw80omhPI92lcEtkNkdgJCCHwJX7mZvNaB0A14SaYJlwTrpHsTkoFlV1nt2c3x5YYo1/vM9A/gKpxdfwyu/v3teCayKq4JEwT5EB2R6WgYmrs2bYbcUNNUVfEhIfFYy69uci+1fuRX84mkawFSxd/4nVWUopUVIykwlQxRTJBTIDA4Pp1jBZPuNW4wUAPmCqWIn29X1k4f5Ku8g9mpKCkakRLVEs1auVuauVuyqHMo8ejNCe+sWPVTkQKXCMmkeZUmUZjETF1tc6ooly+fgUVw9So1/tRN6YnZji46QghBFKKuAouERNhMlbAHZFE6e7pB+He8MMw+GGI4xtOMf1+lsl3TQ4NHf19BSlaO1DB9BfMHdX0O0iqSgiBbJkjm491hClJbA1LxCURgpPzXwAHhg63necAIi3XngXLcRU0fof8ETMljIyM5LGxMcbHxzvy/6fuXdWgt6+PWncv1e4euqo1ZmabvHs5+jn8yzufO7hiiZmuNpNBM13rbvVSpbrXJE7/BMkHtU9jFIC/AAAAAElFTkSuQmCC") no-repeat center left; overflow: hidden; text-indent: 18px; line-height: 0px; cursor:pointer; margin-left:6px;}
/*Used icons: Silk icon set 1.3 by Mark James --- http://www.famfamfam.com/lab/icons/silk/ */

View File

@@ -222,4 +222,38 @@ input[name=logout] {
input[name=logout]:hover {
background:#ea0202;
}
}
#logins a, #tables a {
background:none;
}
#logins a:hover, #tables a:hover {
background:#006aeb;
}
#logout {
color:#006aeb;
text-decoration:none;
}
#logout:hover {
color:white;
background:#006aeb;
}
.js .column {
background:#f2eee1;
}
#content table thead a.text:hover {
text-decoration:none;
}
#version, .version {
font-size:50%;
}
#h1:hover {
color:white;
}

View File

@@ -30,6 +30,10 @@ class Adminer {
return get_databases($flush);
}
function queryTimeout() {
return 5;
}
function headers() {
return true;
}
@@ -184,7 +188,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
if (ereg('date|timestamp', $field["type"]) && $val !== null) {
return preg_replace('~^(\\d{2}(\\d+))-(0?(\\d+))-(0?(\\d+))~', lang('$1-$3-$5'), $val);
}
return (ereg("binary", $field["type"]) ? reset(unpack("H*", $val)) : $val);
return $val;
}
function selectColumnsPrint($select, $columns) {
@@ -193,7 +197,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
function selectSearchPrint($where, $columns, $indexes) {
$where = (array) $_GET["where"];
echo '<fieldset><legend>' . lang('Search') . "</legend><div>\n";
echo '<fieldset id="fieldset-search"><legend>' . lang('Search') . "</legend><div>\n";
$keys = array();
foreach ($where as $key => $val) {
$keys[$val["col"]] = $key;
@@ -407,6 +411,10 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
return false;
}
function selectQueryBuild($select, $where, $group, $order, $limit, $page) {
return "";
}
function messageQuery($query) {
return " <span class='time'>" . @date("H:i:s") . "</span><!--\n" . str_replace("--", "--><!-- ", $query) . "\n-->";
}
@@ -468,15 +476,14 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
$return = ($match["p1"] != "" ? $match["p1"] : ($match["p2"] != "" ? ($match["p2"] < 70 ? 20 : 19) . $match["p2"] : gmdate("Y"))) . "-$match[p3]$match[p4]-$match[p5]$match[p6]" . end($match);
}
$return = ($field["type"] == "bit" && ereg('^[0-9]+$', $value) ? $return : q($return));
if ($value == "" && ($field["null"] || !ereg('char|text', $field["type"])) && !like_bool($field)) {
if ($value == "" && like_bool($field)) {
$return = "0";
} elseif ($value == "" && ($field["null"] || !ereg('char|text', $field["type"]))) {
$return = "NULL";
} elseif (ereg('^(md5|sha1)$', $function)) {
$return = "$function($return)";
}
if (ereg("binary", $field["type"])) {
$return = "unhex($return)";
}
return $return;
return unconvert_field($field, $return);
}
function dumpOutput() {
@@ -532,7 +539,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
foreach ((array) $_SESSION["pwds"]["server"][""] as $username => $password) {
if ($password !== null) {
if ($first) {
echo "<p>\n";
echo "<p id='logins' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
$first = false;
}
echo "<a href='" . h(auth_url("server", "", $username)) . "'>" . ($username != "" ? h($username) : "<i>" . lang('empty') . "</i>") . "</a><br>\n";
@@ -542,11 +549,12 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
?>
<form action="" method="post">
<p class="logout">
<input type="submit" name="logout" value="<?php echo lang('Logout'); ?>">
<input type="submit" name="logout" value="<?php echo lang('Logout'); ?>" id="logout">
<input type="hidden" name="token" value="<?php echo $token; ?>">
</p>
</form>
<?php
$this->databasesPrint($missing);
if ($missing != "db" && $missing != "ns") {
$table_status = table_status();
if (!$table_status) {
@@ -558,8 +566,11 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
}
}
function databasesPrint($missing) {
}
function tablesPrint($tables) {
echo "<p id='tables'>\n";
echo "<p id='tables' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
foreach ($tables as $row) {
$name = $this->tableName($row);
if (isset($row["Engine"]) && $name != "") { // ignore views and tables without name

View File

@@ -1,5 +1,8 @@
<?php
if (list($table, $id, $name) = $adminer->_foreignColumn(column_foreign_keys($_GET["source"]), $_GET["field"])) {
if ($_GET["script"] == "kill") {
$connection->query("KILL " . (+$_POST["kill"]));
} elseif (list($table, $id, $name) = $adminer->_foreignColumn(column_foreign_keys($_GET["source"]), $_GET["field"])) {
$result = $connection->query("SELECT $id, $name FROM " . table($table) . " WHERE " . (ereg('^[0-9]+$', $_GET["value"]) ? "$id = $_GET[value] OR " : "") . "$name LIKE " . q("$_GET[value]%") . " ORDER BY 2 LIMIT 11");
for ($i=0; $i < 10 && ($row = $result->fetch_row()); $i++) {
echo "<a href='" . h(ME . "edit=" . urlencode($table) . "&where" . urlencode("[" . bracket_escape(idf_unescape($id)) . "]") . "=" . urlencode($row[0])) . "'>" . h($row[1]) . "</a><br>\n";

View File

@@ -3,6 +3,9 @@
function bodyLoad(version) {
}
function selectFieldChange(form) {
}
function whisperClick(event, field) {
var el = event.target || event.srcElement;
if (/^a$/i.test(el.tagName) && !(event.button || event.ctrlKey || event.shiftKey || event.altKey || event.metaKey)) {

2
externals/jush vendored

View File

@@ -37,7 +37,7 @@ class AdminerDumpXml {
while ($row = $result->fetch_assoc()) {
echo "\t<table name='" . h($table) . "'>\n";
foreach ($row as $key => $val) {
echo "\t\t<column name='" . h($key) . "'>" . h($val) . "</column>\n";
echo "\t\t<column name='" . h($key) . "'" . (isset($val) ? "" : " null='null'") . ">" . h($val) . "</column>\n";
}
echo "\t</table>\n";
}

View File

@@ -40,6 +40,8 @@ class AdminerPlugin extends Adminer {
case 2: return parent::$function($args[0], $args[1]);
case 3: return parent::$function($args[0], $args[1], $args[2]);
case 4: return parent::$function($args[0], $args[1], $args[2], $args[3]);
case 5: return parent::$function($args[0], $args[1], $args[2], $args[3], $args[4]);
case 6: return parent::$function($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]);
default: trigger_error('Too many parameters.', E_USER_WARNING);
}
}
@@ -53,6 +55,8 @@ class AdminerPlugin extends Adminer {
case 2: $return = $plugin->$function($args[0], $args[1]); break;
case 3: $return = $plugin->$function($args[0], $args[1], $args[2]); break;
case 4: $return = $plugin->$function($args[0], $args[1], $args[2], $args[3]); break;
case 5: $return = $plugin->$function($args[0], $args[1], $args[2], $args[3], $args[4]); break;
case 6: $return = $plugin->$function($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]); break;
default: trigger_error('Too many parameters.', E_USER_WARNING);
}
if ($return !== null) {
@@ -117,6 +121,11 @@ class AdminerPlugin extends Adminer {
return $this->_applyPlugin(__FUNCTION__, $args);
}
function queryTimeout() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function headers() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
@@ -267,6 +276,11 @@ class AdminerPlugin extends Adminer {
return $this->_applyPlugin(__FUNCTION__, $args);
}
function selectQueryBuild() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function messageQuery() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
@@ -312,6 +326,11 @@ class AdminerPlugin extends Adminer {
return $this->_applyPlugin(__FUNCTION__, $args);
}
function databasesPrint() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);
}
function tablesPrint() {
$args = func_get_args();
return $this->_applyPlugin(__FUNCTION__, $args);

View File

@@ -23,7 +23,7 @@ function tablesFilter(value) {
</script>
<p class="jsonly"><input onkeyup="tablesFilter(this.value);">
<?php
echo "<p id='tables'>\n";
echo "<p id='tables' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
foreach ($tables as $table => $type) {
echo '<span><a href="' . h(ME) . 'select=' . urlencode($table) . '"' . bold($_GET["select"] == $table) . ">" . lang('select') . "</a> ";
echo '<a href="' . h(ME) . 'table=' . urlencode($table) . '"' . bold($_GET["table"] == $table) . ">" . h($table) . "</a><br></span>\n";

View File

@@ -18,7 +18,17 @@
</tr>
<tr>
<td>open</td>
<td>adminer/?username=ODBC&amp;lang=en</td>
<td>adminer/?username=ODBC</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>name=lang</td>
<td>label=English</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>css=#lang &gt; input[type=&quot;submit&quot;]</td>
<td></td>
</tr>
<tr>

View File

@@ -38,7 +38,7 @@
</tr>
<tr>
<td>verifyTextPresent</td>
<td>1 item has been affected.</td>
<td>Item 2 has been inserted.</td>
<td></td>
</tr>

View File

@@ -3,7 +3,6 @@ Create view and routine options
Variables editation
Blob download and image display in edit form (important for Editor with hidden fields in select and SQL command)
Add title to Logout, edit (in select) and select (in menu) for style "hever"
Shift-click in checkboxes to select range
Export by GET parameters
Only first part of big BZ2 export is readable, files are missing in TAR
Draggable columns in alter table (thanks to Michal Manak)
@@ -14,7 +13,7 @@ Selectable <option>(on update)<option>CURRENT_TIMESTAMP for timestamp - https://
? Filter by value in row under <thead> in select
? Column and table names auto-completition in SQL textarea - http://blog.quplo.com/2010/06/css-code-completion-in-your-browser/
? Aliasing of built-in functions can save 7 KB, function minification can save 7 KB, substitution of repetitive $a["a"] can save 4 KB, substitution of $_GET and friends can save 2 KB, aliasing of $connection->query can save 24 B, JS Closure compiler can save 2 KB, not enclosing HTML attribute values can save 1.2 KB, replacing \\n by \n can save .3 KB
? Branch binary_compile: LZW compression of translations can save 30 KB, LZW compression of all texts can save 11 KB, remove of base64_decode() + using chars 127-255 in minification can save 1 KB
? Branch binary_compile: LZW compression of all texts can save 11 KB, using chars 127-255 in minification can save 1 KB
Editor:
Three-state checkbox for boolean searches