adminer-4.7.6/000077500000000000000000000000001361500001000131315ustar00rootroot00000000000000adminer-4.7.6/.github/000077500000000000000000000000001361500001000144715ustar00rootroot00000000000000adminer-4.7.6/.github/FUNDING.yml000066400000000000000000000001121361500001000163000ustar00rootroot00000000000000patreon: jakubvrana custom: ["https://sourceforge.net/p/adminer/donate/"] adminer-4.7.6/.travis.yml000066400000000000000000000002701361500001000152410ustar00rootroot00000000000000language: php php: - 5.6 - 7.1 - 7.2 - 7.3 script: git diff --name-only $TRAVIS_COMMIT_RANGE | grep '\.php$' | xargs -n1 -P8 php -l | grep -v 'No syntax errors'; test $? -eq 1 adminer-4.7.6/adminer/000077500000000000000000000000001361500001000145505ustar00rootroot00000000000000adminer-4.7.6/adminer/call.inc.php000066400000000000000000000047751361500001000167610ustar00rootroot00000000000000 $field) { if (substr($field["inout"], -3) == "OUT") { $out[$i] = "@" . idf_escape($field["field"]) . " AS " . idf_escape($field["field"]); } if (!$field["inout"] || substr($field["inout"], 0, 2) == "IN") { $in[] = $i; } } if (!$error && $_POST) { $call = array(); foreach ($routine["fields"] as $key => $field) { if (in_array($key, $in)) { $val = process_input($field); if ($val === false) { $val = "''"; } if (isset($out[$key])) { $connection->query("SET @" . idf_escape($field["field"]) . " = $val"); } } $call[] = (isset($out[$key]) ? "@" . idf_escape($field["field"]) : $val); } $query = (isset($_GET["callf"]) ? "SELECT" : "CALL") . " " . table($PROCEDURE) . "(" . implode(", ", $call) . ")"; $start = microtime(true); $result = $connection->multi_query($query); $affected = $connection->affected_rows; // getting warnigns overwrites this echo $adminer->selectQuery($query, $start, !$result); if (!$result) { echo "

" . error() . "\n"; } else { $connection2 = connect(); if (is_object($connection2)) { $connection2->select_db(DB); } do { $result = $connection->store_result(); if (is_object($result)) { select($result, $connection2); } else { echo "

" . lang('Routine has been called, %d row(s) affected.', $affected) . " " . @date("H:i:s") . "\n" // @ - time zone may be not set ; } } while ($connection->next_result()); if ($out) { select($connection->query("SELECT " . implode(", ", $out))); } } } ?>

\n"; foreach ($in as $key) { $field = $routine["fields"][$key]; $name = $field["field"]; echo "" . $adminer->fieldName($field); $value = $_POST["fields"][$name]; if ($value != "") { if ($field["type"] == "enum") { $value = +$value; } if ($field["type"] == "set") { $value = array_sum($value); } } input($field, $value, (string) $_POST["function"][$name]); // param name can be empty echo "\n"; } echo "\n"; } ?>

adminer-4.7.6/adminer/create.inc.php000066400000000000000000000222401361500001000172740ustar00rootroot00000000000000 $field) { $foreign_keys[str_replace("`", "``", $table_name) . "`" . str_replace("`", "``", $field["field"])] = $table_name; // not idf_escape() - used in JS } $orig_fields = array(); $table_status = array(); if ($TABLE != "") { $orig_fields = fields($TABLE); $table_status = table_status($TABLE); if (!$table_status) { $error = lang('No tables.'); } } $row = $_POST; $row["fields"] = (array) $row["fields"]; if ($row["auto_increment_col"]) { $row["fields"][$row["auto_increment_col"]]["auto_increment"] = true; } if ($_POST) { set_adminer_settings(array("comments" => $_POST["comments"], "defaults" => $_POST["defaults"])); } if ($_POST && !process_fields($row["fields"]) && !$error) { if ($_POST["drop"]) { queries_redirect(substr(ME, 0, -1), lang('Table has been dropped.'), drop_tables(array($TABLE))); } else { $fields = array(); $all_fields = array(); $use_all_fields = false; $foreign = array(); $orig_field = reset($orig_fields); $after = " FIRST"; foreach ($row["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 if ($field["field"] != "") { if (!$field["has_default"]) { $field["default"] = null; } if ($key == $row["auto_increment_col"]) { $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 != "" && $jush != "sqlite" ? "ADD" : " ") . format_foreign_key(array( 'table' => $foreign_keys[$field["type"]], 'source' => array($field["field"]), 'target' => array($type_field["field"]), 'on_delete' => $field["on_delete"], )); } $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 = ""; if ($partition_by[$row["partition_by"]]) { $partitions = array(); if ($row["partition_by"] == 'RANGE' || $row["partition_by"] == 'LIST') { foreach (array_filter($row["partition_names"]) as $key => $val) { $value = $row["partition_values"][$key]; $partitions[] = "\n PARTITION " . idf_escape($val) . " VALUES " . ($row["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection } } $partitioning .= "\nPARTITION BY $row[partition_by]($row[partition])" . ($partitions // $row["partition"] can be expression, not only column ? " (" . implode(",", $partitions) . "\n)" : ($row["partitions"] ? " PARTITIONS " . (+$row["partitions"]) : "") ); } elseif (support("partitioning") && preg_match("~partitioned~", $table_status["Create_options"])) { $partitioning .= "\nREMOVE PARTITIONING"; } $message = lang('Table has been altered.'); if ($TABLE == "") { cookie("adminer_engine", $row["Engine"]); $message = lang('Table has been created.'); } $name = trim($row["name"]); queries_redirect(ME . (support("table") ? "table=" : "select=") . urlencode($name), $message, alter_table( $TABLE, $name, ($jush == "sqlite" && ($use_all_fields || $foreign) ? $all_fields : $fields), $foreign, ($row["Comment"] != $table_status["Comment"] ? $row["Comment"] : null), ($row["Engine"] && $row["Engine"] != $table_status["Engine"] ? $row["Engine"] : ""), ($row["Collation"] && $row["Collation"] != $table_status["Collation"] ? $row["Collation"] : ""), ($row["Auto_increment"] != "" ? number($row["Auto_increment"]) : ""), $partitioning )); } } page_header(($TABLE != "" ? lang('Alter table') : lang('Create table')), $error, array("table" => $TABLE), h($TABLE)); if (!$_POST) { $row = array( "Engine" => $_COOKIE["adminer_engine"], "fields" => array(array("field" => "", "type" => (isset($types["int"]) ? "int" : (isset($types["integer"]) ? "integer" : "")), "on_update" => "")), "partition_names" => array(""), ); if ($TABLE != "") { $row = $table_status; $row["name"] = $TABLE; $row["fields"] = array(); if (!$_GET["auto_increment"]) { // don't prefill by original Auto_increment for the sake of performance and not reusing deleted ids $row["Auto_increment"] = ""; } foreach ($orig_fields as $field) { $field["has_default"] = isset($field["default"]); $row["fields"][] = $field; } if (support("partitioning")) { $from = "FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = " . q(DB) . " AND TABLE_NAME = " . q($TABLE); $result = $connection->query("SELECT PARTITION_METHOD, PARTITION_ORDINAL_POSITION, PARTITION_EXPRESSION $from ORDER BY PARTITION_ORDINAL_POSITION DESC LIMIT 1"); list($row["partition_by"], $row["partitions"], $row["partition"]) = $result->fetch_row(); $partitions = get_key_vals("SELECT PARTITION_NAME, PARTITION_DESCRIPTION $from AND PARTITION_NAME != '' ORDER BY PARTITION_ORDINAL_POSITION"); $partitions[""] = ""; $row["partition_names"] = array_keys($partitions); $row["partition_values"] = array_values($partitions); } } } $collations = collations(); $engines = engines(); // case of engine may differ foreach ($engines as $engine) { if (!strcasecmp($engine, $row["Engine"])) { $row["Engine"] = $engine; break; } } ?>

: " autocapitalize="off"> " . optionlist(array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . "" . on_help("getTarget(event).value", 1) . script("qsl('select').onchange = helpClose;") : ""); ?> "(" . lang('collation') . ")") + $collations, $row["Collation"]) : ""); ?>

: "> ' : '') ; ?>

" . optionlist(array("" => "") + $partition_by, $row["partition_by"]) . "" . on_help("getTarget(event).value.replace(/./, 'PARTITION BY \$&')", 1) . script("qsl('select').onchange = partitionByChange;"); ?> (">) : " value=""> > $val) { echo ''; echo '

adminer-4.7.6/adminer/database.inc.php000066400000000000000000000057001361500001000175770ustar00rootroot00000000000000

' . h($name) . '
' : '' ) . "\n" . ($collations ? html_select("collation", array("" => "(" . lang('collation') . ")") + $collations, $row["collation"]) . doc_link(array( 'sql' => "charset-charsets.html", 'mariadb' => "supported-character-sets-and-collations/", 'mssql' => "ms187963.aspx", )) : ""); echo script("focus(qs('#name'));"); ?> " . confirm(lang('Drop %s?', DB)) . "\n"; } elseif (!$_POST["add_x"] && $_GET["db"] == "") { echo "\n"; } ?>

adminer-4.7.6/adminer/db.inc.php000066400000000000000000000305251361500001000164230ustar00rootroot00000000000000 1 && ($_POST["drop"] || $_POST["truncate"] || $_POST["copy"])) { queries("SET foreign_key_checks = 0"); // allows to truncate or drop several tables at once } if ($_POST["truncate"]) { if ($_POST["tables"]) { $result = truncate_tables($_POST["tables"]); } $message = lang('Tables have been truncated.'); } elseif ($_POST["move"]) { $result = move_tables((array) $_POST["tables"], (array) $_POST["views"], $_POST["target"]); $message = lang('Tables have been moved.'); } elseif ($_POST["copy"]) { $result = copy_tables((array) $_POST["tables"], (array) $_POST["views"], $_POST["target"]); $message = lang('Tables have been copied.'); } elseif ($_POST["drop"]) { if ($_POST["views"]) { $result = drop_views($_POST["views"]); } if ($result && $_POST["tables"]) { $result = drop_tables($_POST["tables"]); } $message = lang('Tables have been dropped.'); } elseif ($jush != "sql") { $result = ($jush == "sqlite" ? queries("VACUUM") : apply_queries("VACUUM" . ($_POST["optimize"] ? "" : " ANALYZE"), $_POST["tables"]) ); $message = lang('Tables have been optimized.'); } elseif (!$_POST["tables"]) { $message = lang('No tables.'); } elseif ($result = queries(($_POST["optimize"] ? "OPTIMIZE" : ($_POST["check"] ? "CHECK" : ($_POST["repair"] ? "REPAIR" : "ANALYZE"))) . " TABLE " . implode(", ", array_map('idf_escape', $_POST["tables"])))) { while ($row = $result->fetch_assoc()) { $message .= "" . h($row["Table"]) . ": " . h($row["Msg_text"]) . "
"; } } queries_redirect(substr(ME, 0, -1), $message, $result); } page_header(($_GET["ns"] == "" ? lang('Database') . ": " . h(DB) : lang('Schema') . ": " . h($_GET["ns"])), $error, true); if ($adminer->homepage()) { if ($_GET["ns"] !== "") { echo "

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

\n"; $tables_list = tables_list(); if (!$tables_list) { echo "

" . lang('No tables.') . "\n"; } else { echo "

\n"; if (support("table")) { echo "
" . lang('Search data in tables') . "
"; echo ""; echo script("qsl('input').onkeydown = partialArg(bodyKeydown, 'search');", ""); echo " \n"; echo "
\n"; if ($_POST["search"] && $_POST["query"] != "") { $_GET["where"][0]["op"] = "LIKE %%"; search_tables(); } } echo "
\n"; echo "\n"; echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});"); echo ''; echo '\n"; $tables = 0; foreach ($tables_list as $name => $type) { $view = ($type !== null && !preg_match('~table~i', $type)); $id = h("Table-" . $name); echo '
' . script("qs('#check-all').onclick = partial(formCheck, /^(tables|views)\[/);", ""); echo '' . lang('Table'); echo '' . lang('Engine') . doc_link(array('sql' => 'storage-engines.html')); echo '' . lang('Collation') . doc_link(array('sql' => 'charset-charsets.html', 'mariadb' => 'supported-character-sets-and-collations/')); echo '' . lang('Data Length') . doc_link(array('sql' => 'show-table-status.html', 'pgsql' => 'functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT', 'oracle' => 'REFRN20286')); echo '' . lang('Index Length') . doc_link(array('sql' => 'show-table-status.html', 'pgsql' => 'functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT')); echo '' . lang('Data Free') . doc_link(array('sql' => 'show-table-status.html')); echo '' . lang('Auto Increment') . doc_link(array('sql' => 'example-auto-increment.html', 'mariadb' => 'auto_increment/')); echo '' . lang('Rows') . doc_link(array('sql' => 'show-table-status.html', 'pgsql' => 'catalog-pg-class.html#CATALOG-PG-CLASS', 'oracle' => 'REFRN20286')); echo (support("comment") ? '' . lang('Comment') . doc_link(array('sql' => 'show-table-status.html', 'pgsql' => 'functions-info.html#FUNCTIONS-INFO-COMMENT-TABLE')) : ''); echo "
' . checkbox(($view ? "views[]" : "tables[]"), $name, in_array($name, $tables_views, true), "", "", "", $id); echo '' . (support("table") || support("indexes") ? "" . h($name) . '' : h($name)); if ($view) { echo '' . (preg_match('~materialized~i', $type) ? lang('Materialized view') : lang('View')) . ''; echo '?'; } else { foreach (array( "Engine" => array(), "Collation" => array(), "Data_length" => array("create", lang('Alter table')), "Index_length" => array("indexes", lang('Alter indexes')), "Data_free" => array("edit", lang('New item')), "Auto_increment" => array("auto_increment=1&create", lang('Alter table')), "Rows" => array("select", lang('Select data')), ) as $key => $link) { $id = " id='$key-" . h($name) . "'"; echo ($link ? "" . (support("table") || $key == "Rows" || (support("indexes") && $key != "Data_length") ? "?" : "?" ) : ""); } $tables++; } echo (support("comment") ? "" : ""); } echo "
" . lang('%d in total', count($tables_list)); echo "" . h($jush == "sql" ? $connection->result("SELECT @@storage_engine") : ""); echo "" . h(db_collation(DB, collations())); foreach (array("Data_length", "Index_length", "Data_free") as $key) { echo ""; } echo "
\n"; echo "
\n"; if (!information_schema(DB)) { echo "\n"; } echo "
\n"; echo script("tableCheck();"); } echo '

" . lang('Routines') . "

\n"; $routines = routines(); if ($routines) { echo "\n"; echo '\n"; odd(''); foreach ($routines as $row) { $name = ($row["SPECIFIC_NAME"] == $row["ROUTINE_NAME"] ? "" : "&name=" . urlencode($row["ROUTINE_NAME"])); // not computed on the pages to be able to print the header first echo ''; echo '
' . lang('Name') . '' . lang('Type') . '' . lang('Return type') . "
' . h($row["ROUTINE_NAME"]) . ''; echo '' . h($row["ROUTINE_TYPE"]); echo '' . h($row["DTD_IDENTIFIER"]); echo '' . lang('Alter') . ""; } echo "
\n"; } echo '

" . lang('Sequences') . "

\n"; $sequences = get_vals("SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = current_schema() ORDER BY sequence_name"); if ($sequences) { echo "\n"; echo "\n"; odd(''); foreach ($sequences as $val) { echo "
" . lang('Name') . "
" . h($val) . "\n"; } echo "
\n"; } echo "

" . lang('User types') . "

\n"; $user_types = types(); if ($user_types) { echo "\n"; echo "\n"; odd(''); foreach ($user_types as $val) { echo "
" . lang('Name') . "
" . h($val) . "\n"; } echo "
\n"; } echo "

" . lang('Events') . "

\n"; $rows = get_rows("SHOW EVENTS"); if ($rows) { echo "\n"; echo "\n"; foreach ($rows as $row) { echo ""; echo "
" . lang('Name') . "" . lang('Schedule') . "" . lang('Start') . "" . lang('End') . "
" . h($row["Name"]); echo "" . ($row["Execute at"] ? lang('At given time') . "" . $row["Execute at"] : lang('Every') . " " . $row["Interval value"] . " " . $row["Interval field"] . "$row[Starts]"); echo "$row[Ends]"; echo '' . lang('Alter') . ''; } echo "
\n"; $event_scheduler = $connection->result("SELECT @@event_scheduler"); if ($event_scheduler && $event_scheduler != "ON") { echo "

event_scheduler: " . h($event_scheduler) . "\n"; } } echo '

" . error() . "\n"; } return $return; } function table_status($name = "", $fast = false) { $return = array(); foreach (($name != "" ? array($name => true) : tables_list()) as $table => $type) { $row = array("Name" => $table, "Auto_increment" => ""); if (!$fast) { $meta = sdb_request('DomainMetadata', array('DomainName' => $table)); if ($meta) { foreach (array( "Rows" => "ItemCount", "Data_length" => "ItemNamesSizeBytes", "Index_length" => "AttributeValuesSizeBytes", "Data_free" => "AttributeNamesSizeBytes", ) as $key => $val) { $row[$key] = (string) $meta->$val; } } } if ($name != "") { return $row; } $return[$table] = $row; } return $return; } function explain($connection, $query) { } function error() { global $connection; return h($connection->error); } function information_schema() { } function is_view($table_status) { } function indexes($table, $connection2 = null) { return array( array("type" => "PRIMARY", "columns" => array("itemName()")), ); } function fields($table) { return fields_from_edit(); } function foreign_keys($table) { return array(); } function table($idf) { return idf_escape($idf); } function idf_escape($idf) { return "`" . str_replace("`", "``", $idf) . "`"; } function limit($query, $where, $limit, $offset = 0, $separator = " ") { return " $query$where" . ($limit !== null ? $separator . "LIMIT $limit" : ""); } function unconvert_field($field, $return) { return $return; } function fk_support($table_status) { } function engines() { return array(); } function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) { return ($table == "" && sdb_request('CreateDomain', array('DomainName' => $name))); } function drop_tables($tables) { foreach ($tables as $table) { if (!sdb_request('DeleteDomain', array('DomainName' => $table))) { return false; } } return true; } function count_tables($databases) { foreach ($databases as $db) { return array($db => count(tables_list())); } } function found_rows($table_status, $where) { return ($where ? null : $table_status["Rows"]); } function last_id() { } function hmac($algo, $data, $key, $raw_output = false) { // can use hash_hmac() since PHP 5.1.2 $blocksize = 64; if (strlen($key) > $blocksize) { $key = pack("H*", $algo($key)); } $key = str_pad($key, $blocksize, "\0"); $k_ipad = $key ^ str_repeat("\x36", $blocksize); $k_opad = $key ^ str_repeat("\x5C", $blocksize); $return = $algo($k_opad . pack("H*", $algo($k_ipad . $data))); if ($raw_output) { $return = pack("H*", $return); } return $return; } function sdb_request($action, $params = array()) { global $adminer, $connection; list($host, $params['AWSAccessKeyId'], $secret) = $adminer->credentials(); $params['Action'] = $action; $params['Timestamp'] = gmdate('Y-m-d\TH:i:s+00:00'); $params['Version'] = '2009-04-15'; $params['SignatureVersion'] = 2; $params['SignatureMethod'] = 'HmacSHA1'; ksort($params); $query = ''; foreach ($params as $key => $val) { $query .= '&' . rawurlencode($key) . '=' . rawurlencode($val); } $query = str_replace('%7E', '~', substr($query, 1)); $query .= "&Signature=" . urlencode(base64_encode(hmac('sha1', "POST\n" . preg_replace('~^https?://~', '', $host) . "\n/\n$query", $secret, true))); @ini_set('track_errors', 1); // @ - may be disabled $file = @file_get_contents((preg_match('~^https?://~', $host) ? $host : "http://$host"), false, stream_context_create(array('http' => array( 'method' => 'POST', // may not fit in URL with GET 'content' => $query, 'ignore_errors' => 1, // available since PHP 5.2.10 )))); if (!$file) { $connection->error = $php_errormsg; return false; } libxml_use_internal_errors(true); $xml = simplexml_load_string($file); if (!$xml) { $error = libxml_get_last_error(); $connection->error = $error->message; return false; } if ($xml->Errors) { $error = $xml->Errors->Error; $connection->error = "$error->Message ($error->Code)"; return false; } $connection->error = ''; $tag = $action . "Result"; return ($xml->$tag ? $xml->$tag : true); } function sdb_request_all($action, $tag, $params = array(), $timeout = 0) { $return = array(); $start = ($timeout ? microtime(true) : 0); $limit = (preg_match('~LIMIT\s+(\d+)\s*$~i', $params['SelectExpression'], $match) ? $match[1] : 0); do { $xml = sdb_request($action, $params); if (!$xml) { break; } foreach ($xml->$tag as $element) { $return[] = $element; } if ($limit && count($return) >= $limit) { $_GET["next"] = $xml->NextToken; break; } if ($timeout && microtime(true) - $start > $timeout) { return false; } $params['NextToken'] = $xml->NextToken; if ($limit) { $params['SelectExpression'] = preg_replace('~\d+\s*$~', $limit - count($return), $params['SelectExpression']); } } while ($xml->NextToken); return $return; } $jush = "simpledb"; $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "IS NOT NULL"); $functions = array(); $grouping = array("count"); $edit_functions = array(array("json")); } adminer-4.7.6/adminer/drivers/sqlite.inc.php000066400000000000000000000577001361500001000210210ustar00rootroot00000000000000_link = new SQLite3($filename); $version = $this->_link->version(); $this->server_info = $version["versionString"]; } function query($query) { $result = @$this->_link->query($query); $this->error = ""; if (!$result) { $this->errno = $this->_link->lastErrorCode(); $this->error = $this->_link->lastErrorMsg(); return false; } elseif ($result->numColumns()) { return new Min_Result($result); } $this->affected_rows = $this->_link->changes(); return true; } function quote($string) { return (is_utf8($string) ? "'" . $this->_link->escapeString($string) . "'" : "x'" . reset(unpack('H*', $string)) . "'" ); } function store_result() { return $this->_result; } function result($query, $field = 0) { $result = $this->query($query); if (!is_object($result)) { return false; } $row = $result->_result->fetchArray(); return $row[$field]; } } class Min_Result { var $_result, $_offset = 0, $num_rows; function __construct($result) { $this->_result = $result; } function fetch_assoc() { return $this->_result->fetchArray(SQLITE3_ASSOC); } function fetch_row() { return $this->_result->fetchArray(SQLITE3_NUM); } function fetch_field() { $column = $this->_offset++; $type = $this->_result->columnType($column); return (object) array( "name" => $this->_result->columnName($column), "type" => $type, "charsetnr" => ($type == SQLITE3_BLOB ? 63 : 0), // 63 - binary ); } function __desctruct() { return $this->_result->finalize(); } } } else { class Min_SQLite { var $extension = "SQLite", $server_info, $affected_rows, $error, $_link; function __construct($filename) { $this->server_info = sqlite_libversion(); $this->_link = new SQLiteDatabase($filename); } 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; } elseif ($result === true) { $this->affected_rows = $this->changes(); return true; } return new Min_Result($result); } function quote($string) { return "'" . sqlite_escape_string($string) . "'"; } function store_result() { return $this->_result; } function result($query, $field = 0) { $result = $this->query($query); if (!is_object($result)) { return false; } $row = $result->_result->fetch(); return $row[$field]; } } class Min_Result { var $_result, $_offset = 0, $num_rows; function __construct($result) { $this->_result = $result; if (method_exists($result, 'numRows')) { // not available in unbuffered query $this->num_rows = $result->numRows(); } } function fetch_assoc() { $row = $this->_result->fetch(SQLITE_ASSOC); if (!$row) { return false; } $return = array(); foreach ($row as $key => $val) { $return[($key[0] == '"' ? idf_unescape($key) : $key)] = $val; } return $return; } function fetch_row() { return $this->_result->fetch(SQLITE_NUM); } function fetch_field() { $name = $this->_result->fieldName($this->_offset++); $pattern = '(\[.*]|"(?:[^"]|"")*"|(.+))'; if (preg_match("~^($pattern\\.)?$pattern\$~", $name, $match)) { $table = ($match[3] != "" ? $match[3] : idf_unescape($match[2])); $name = ($match[5] != "" ? $match[5] : idf_unescape($match[4])); } return (object) array( "name" => $name, "orgname" => $name, "orgtable" => $table, ); } } } } elseif (extension_loaded("pdo_sqlite")) { class Min_SQLite extends Min_PDO { var $extension = "PDO_SQLite"; function __construct($filename) { $this->dsn(DRIVER . ":$filename", "", ""); } } } if (class_exists("Min_SQLite")) { class Min_DB extends Min_SQLite { function __construct() { parent::__construct(":memory:"); $this->query("PRAGMA foreign_keys = 1"); } function select_db($filename) { if (is_readable($filename) && $this->query("ATTACH " . $this->quote(preg_match("~(^[/\\\\]|:)~", $filename) ? $filename : dirname($_SERVER["SCRIPT_FILENAME"]) . "/$filename") . " AS a")) { // is_readable - SQLite 3 parent::__construct($filename); $this->query("PRAGMA foreign_keys = 1"); return true; } return false; } function multi_query($query) { return $this->_result = $this->query($query); } function next_result() { return false; } } } class Min_Driver extends Min_SQL { function insertUpdate($table, $rows, $primary) { $values = array(); foreach ($rows as $set) { $values[] = "(" . implode(", ", $set) . ")"; } return queries("REPLACE INTO " . table($table) . " (" . implode(", ", array_keys(reset($rows))) . ") VALUES\n" . implode(",\n", $values)); } function tableHelp($name) { if ($name == "sqlite_sequence") { return "fileformat2.html#seqtab"; } if ($name == "sqlite_master") { return "fileformat2.html#$name"; } } } function idf_escape($idf) { return '"' . str_replace('"', '""', $idf) . '"'; } function table($idf) { return idf_escape($idf); } function connect() { global $adminer; list(, , $password) = $adminer->credentials(); if ($password != "") { return lang('Database does not support password.'); } return new Min_DB; } function get_databases() { return array(); } function limit($query, $where, $limit, $offset = 0, $separator = " ") { return " $query$where" . ($limit !== null ? $separator . "LIMIT $limit" . ($offset ? " OFFSET $offset" : "") : ""); } function limit1($table, $query, $where, $separator = "\n") { global $connection; return (preg_match('~^INTO~', $query) || $connection->result("SELECT sqlite_compileoption_used('ENABLE_UPDATE_DELETE_LIMIT')") ? limit($query, $where, 1, 0, $separator) : " $query WHERE rowid = (SELECT rowid FROM " . table($table) . $where . $separator . "LIMIT 1)" //! use primary key in tables with WITHOUT rowid ); } function db_collation($db, $collations) { global $connection; return $connection->result("PRAGMA encoding"); // there is no database list so $db == DB } function engines() { return array(); } function logged_user() { return get_current_user(); // should return effective user } function tables_list() { return get_key_vals("SELECT name, type FROM sqlite_master WHERE type IN ('table', 'view') ORDER BY (name = 'sqlite_sequence'), name"); } function count_tables($databases) { return array(); } function table_status($name = "") { global $connection; $return = array(); foreach (get_rows("SELECT name AS Name, type AS Engine, 'rowid' AS Oid, '' AS Auto_increment FROM sqlite_master WHERE type IN ('table', 'view') " . ($name != "" ? "AND name = " . q($name) : "ORDER BY name")) as $row) { $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) { $return[$row["name"]]["Auto_increment"] = $row["seq"]; } return ($name != "" ? $return[$name] : $return); } function is_view($table_status) { return $table_status["Engine"] == "view"; } function fk_support($table_status) { global $connection; return !$connection->result("SELECT sqlite_compileoption_used('OMIT_FOREIGN_KEY')"); } function fields($table) { global $connection; $return = array(); $primary = ""; foreach (get_rows("PRAGMA table_info(" . table($table) . ")") as $row) { $name = $row["name"]; $type = strtolower($row["type"]); $default = $row["dflt_value"]; $return[$name] = array( "field" => $name, "type" => (preg_match('~int~i', $type) ? "integer" : (preg_match('~char|clob|text~i', $type) ? "text" : (preg_match('~blob~i', $type) ? "blob" : (preg_match('~real|floa|doub~i', $type) ? "real" : "numeric")))), "full_type" => $type, "default" => (preg_match("~'(.*)'~", $default, $match) ? str_replace("''", "'", $match[1]) : ($default == "NULL" ? null : $default)), "null" => !$row["notnull"], "privileges" => array("select" => 1, "insert" => 1, "update" => 1), "primary" => $row["pk"], ); if ($row["pk"]) { if ($primary != "") { $return[$primary]["auto_increment"] = false; } elseif (preg_match('~^integer$~i', $type)) { $return[$name]["auto_increment"] = true; } $primary = $name; } } $sql = $connection->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table)); preg_match_all('~(("[^"]*+")+|[a-z0-9_]+)\s+text\s+COLLATE\s+(\'[^\']+\'|\S+)~i', $sql, $matches, PREG_SET_ORDER); foreach ($matches as $match) { $name = str_replace('""', '"', preg_replace('~^"|"$~', '', $match[1])); if ($return[$name]) { $return[$name]["collation"] = trim($match[3], "'"); } } return $return; } function indexes($table, $connection2 = null) { global $connection; if (!is_object($connection2)) { $connection2 = $connection; } $return = array(); $sql = $connection2->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table)); if (preg_match('~\bPRIMARY\s+KEY\s*\((([^)"]+|"[^"]*"|`[^`]*`)++)~i', $sql, $match)) { $return[""] = array("type" => "PRIMARY", "columns" => array(), "lengths" => array(), "descs" => array()); preg_match_all('~((("[^"]*+")+|(?:`[^`]*+`)+)|(\S+))(\s+(ASC|DESC))?(,\s*|$)~i', $match[1], $matches, PREG_SET_ORDER); foreach ($matches as $match) { $return[""]["columns"][] = idf_unescape($match[2]) . $match[4]; $return[""]["descs"][] = (preg_match('~DESC~i', $match[5]) ? '1' : null); } } if (!$return) { foreach (fields($table) as $name => $field) { if ($field["primary"]) { $return[""] = array("type" => "PRIMARY", "columns" => array($name), "lengths" => array(), "descs" => array(null)); } } } $sqls = get_key_vals("SELECT name, sql FROM sqlite_master WHERE type = 'index' AND tbl_name = " . q($table), $connection2); foreach (get_rows("PRAGMA index_list(" . table($table) . ")", $connection2) as $row) { $name = $row["name"]; $index = array("type" => ($row["unique"] ? "UNIQUE" : "INDEX")); $index["lengths"] = array(); $index["descs"] = array(); foreach (get_rows("PRAGMA index_info(" . idf_escape($name) . ")", $connection2) as $row1) { $index["columns"][] = $row1["name"]; $index["descs"][] = null; } if (preg_match('~^CREATE( UNIQUE)? INDEX ' . preg_quote(idf_escape($name) . ' ON ' . idf_escape($table), '~') . ' \((.*)\)$~i', $sqls[$name], $regs)) { preg_match_all('/("[^"]*+")+( DESC)?/', $regs[2], $matches); foreach ($matches[2] as $key => $val) { if ($val) { $index["descs"][$key] = '1'; } } } if (!$return[""] || $index["type"] != "UNIQUE" || $index["columns"] != $return[""]["columns"] || $index["descs"] != $return[""]["descs"] || !preg_match("~^sqlite_~", $name)) { $return[$name] = $index; } } return $return; } function foreign_keys($table) { $return = array(); foreach (get_rows("PRAGMA foreign_key_list(" . table($table) . ")") as $row) { $foreign_key = &$return[$row["id"]]; //! idf_unescape in SQLite2 if (!$foreign_key) { $foreign_key = $row; } $foreign_key["source"][] = $row["from"]; $foreign_key["target"][] = $row["to"]; } return $return; } function view($name) { global $connection; return array("select" => preg_replace('~^(?:[^`"[]+|`[^`]*`|"[^"]*")* AS\s+~iU', '', $connection->result("SELECT sql FROM sqlite_master WHERE name = " . q($name)))); //! identifiers may be inside [] } function collations() { return (isset($_GET["create"]) ? get_vals("PRAGMA collation_list", 1) : array()); } function information_schema($db) { return false; } function error() { global $connection; return h($connection->error); } function check_sqlite_name($name) { // avoid creating PHP files on unsecured servers global $connection; $extensions = "db|sdb|sqlite"; if (!preg_match("~^[^\\0]*\\.($extensions)\$~", $name)) { $connection->error = lang('Please use one of the extensions %s.', str_replace("|", ", ", $extensions)); return false; } return true; } function create_database($db, $collation) { global $connection; if (file_exists($db)) { $connection->error = lang('File exists.'); return false; } if (!check_sqlite_name($db)) { return false; } try { $link = new Min_SQLite($db); } catch (Exception $ex) { $connection->error = $ex->getMessage(); return false; } $link->query('PRAGMA encoding = "UTF-8"'); $link->query('CREATE TABLE adminer (i)'); // otherwise creates empty file $link->query('DROP TABLE adminer'); return true; } function drop_databases($databases) { global $connection; $connection->__construct(":memory:"); // to unlock file, doesn't work in PDO on Windows foreach ($databases as $db) { if (!@unlink($db)) { $connection->error = lang('File exists.'); return false; } } return true; } function rename_database($name, $collation) { global $connection; if (!check_sqlite_name($name)) { return false; } $connection->__construct(":memory:"); $connection->error = lang('File exists.'); return @rename(DB, $name); } function auto_increment() { return " PRIMARY KEY" . (DRIVER == "sqlite" ? " AUTOINCREMENT" : ""); } function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) { global $connection; $use_all_fields = ($table == "" || $foreign); foreach ($fields as $field) { if ($field[0] != "" || !$field[1] || $field[2]) { $use_all_fields = true; break; } } $alter = array(); $originals = array(); foreach ($fields as $field) { if ($field[1]) { $alter[] = ($use_all_fields ? $field[1] : "ADD " . implode($field[1])); if ($field[0] != "") { $originals[$field[0]] = $field[1][0]; } } } if (!$use_all_fields) { foreach ($alter as $val) { if (!queries("ALTER TABLE " . table($table) . " $val")) { return false; } } if ($table != $name && !queries("ALTER TABLE " . table($table) . " RENAME TO " . table($name))) { return false; } } elseif (!recreate_table($table, $name, $alter, $originals, $foreign, $auto_increment)) { return false; } if ($auto_increment) { queries("BEGIN"); queries("UPDATE sqlite_sequence SET seq = $auto_increment WHERE name = " . q($name)); // ignores error if (!$connection->affected_rows) { queries("INSERT INTO sqlite_sequence (name, seq) VALUES (" . q($name) . ", $auto_increment)"); } queries("COMMIT"); } return true; } function recreate_table($table, $name, $fields, $originals, $foreign, $auto_increment, $indexes = array()) { global $connection; if ($table != "") { if (!$fields) { foreach (fields($table) as $key => $field) { if ($indexes) { $field["auto_increment"] = 0; } $fields[] = process_field($field, $field); $originals[$key] = idf_escape($key); } } $primary_key = false; foreach ($fields as $field) { if ($field[6]) { $primary_key = true; } } $drop_indexes = array(); foreach ($indexes as $key => $val) { if ($val[2] == "DROP") { $drop_indexes[$val[1]] = true; unset($indexes[$key]); } } foreach (indexes($table) as $key_name => $index) { $columns = array(); foreach ($index["columns"] as $key => $column) { if (!$originals[$column]) { continue 2; } $columns[] = $originals[$column] . ($index["descs"][$key] ? " DESC" : ""); } if (!$drop_indexes[$key_name]) { if ($index["type"] != "PRIMARY" || !$primary_key) { $indexes[] = array($index["type"], $key_name, $columns); } } } foreach ($indexes as $key => $val) { if ($val[0] == "PRIMARY") { unset($indexes[$key]); $foreign[] = " PRIMARY KEY (" . implode(", ", $val[2]) . ")"; } } foreach (foreign_keys($table) as $key_name => $foreign_key) { foreach ($foreign_key["source"] as $key => $column) { if (!$originals[$column]) { continue 2; } $foreign_key["source"][$key] = idf_unescape($originals[$column]); } if (!isset($foreign[" $key_name"])) { $foreign[] = " " . format_foreign_key($foreign_key); } } queries("BEGIN"); } foreach ($fields as $key => $field) { $fields[$key] = " " . implode($field); } $fields = array_merge($fields, array_filter($foreign)); $temp_name = ($table == $name ? "adminer_$name" : $name); if (!queries("CREATE TABLE " . table($temp_name) . " (\n" . implode(",\n", $fields) . "\n)")) { // implicit ROLLBACK to not overwrite $connection->error return false; } if ($table != "") { if ($originals && !queries("INSERT INTO " . table($temp_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]"; } $auto_increment = $auto_increment ? 0 : $connection->result("SELECT seq FROM sqlite_sequence WHERE name = " . q($table)); // if $auto_increment is set then it will be updated later if (!queries("DROP TABLE " . table($table)) // drop before creating indexes and triggers to allow using old names || ($table == $name && !queries("ALTER TABLE " . table($temp_name) . " RENAME TO " . table($name))) || !alter_indexes($name, $indexes) ) { return false; } if ($auto_increment) { queries("UPDATE sqlite_sequence SET seq = $auto_increment WHERE name = " . q($name)); // ignores error } foreach ($triggers as $trigger) { if (!queries($trigger)) { return false; } } queries("COMMIT"); } return true; } function index_sql($table, $type, $name, $columns) { return "CREATE $type " . ($type != "INDEX" ? "INDEX " : "") . idf_escape($name != "" ? $name : uniqid($table . "_")) . " ON " . table($table) . " $columns" ; } function alter_indexes($table, $alter) { foreach ($alter as $primary) { if ($primary[0] == "PRIMARY") { return recreate_table($table, $table, array(), array(), array(), 0, $alter); } } foreach (array_reverse($alter) as $val) { if (!queries($val[2] == "DROP" ? "DROP INDEX " . idf_escape($val[1]) : index_sql($table, $val[0], $val[1], "(" . implode(", ", $val[2]) . ")") )) { return false; } } return true; } function truncate_tables($tables) { return apply_queries("DELETE FROM", $tables); } function drop_views($views) { return apply_queries("DROP VIEW", $views); } function drop_tables($tables) { return apply_queries("DROP TABLE", $tables); } function move_tables($tables, $views, $target) { return false; } function trigger($name) { global $connection; if ($name == "") { return array("Statement" => "BEGIN\n\t;\nEND"); } $idf = '(?:[^`"\s]+|`[^`]*`|"[^"]*")+'; $trigger_options = trigger_options(); preg_match( "~^CREATE\\s+TRIGGER\\s*$idf\\s*(" . implode("|", $trigger_options["Timing"]) . ")\\s+([a-z]+)(?:\\s+OF\\s+($idf))?\\s+ON\\s*$idf\\s*(?:FOR\\s+EACH\\s+ROW\\s)?(.*)~is", $connection->result("SELECT sql FROM sqlite_master WHERE type = 'trigger' AND name = " . q($name)), $match ); $of = $match[3]; return array( "Timing" => strtoupper($match[1]), "Event" => strtoupper($match[2]) . ($of ? " OF" : ""), "Of" => ($of[0] == '`' || $of[0] == '"' ? idf_unescape($of) : $of), "Trigger" => $name, "Statement" => $match[4], ); } function triggers($table) { $return = array(); $trigger_options = trigger_options(); foreach (get_rows("SELECT * FROM sqlite_master WHERE type = 'trigger' AND tbl_name = " . q($table)) as $row) { preg_match('~^CREATE\s+TRIGGER\s*(?:[^`"\s]+|`[^`]*`|"[^"]*")+\s*(' . implode("|", $trigger_options["Timing"]) . ')\s*(.*?)\s+ON\b~i', $row["sql"], $match); $return[$row["name"]] = array($match[1], $match[2]); } return $return; } function trigger_options() { return array( "Timing" => array("BEFORE", "AFTER", "INSTEAD OF"), "Event" => array("INSERT", "UPDATE", "UPDATE OF", "DELETE"), "Type" => array("FOR EACH ROW"), ); } function begin() { return queries("BEGIN"); } function last_id() { global $connection; return $connection->result("SELECT LAST_INSERT_ROWID()"); } function explain($connection, $query) { return $connection->query("EXPLAIN QUERY PLAN $query"); } function found_rows($table_status, $where) { } function types() { return array(); } function schemas() { return array(); } function get_schema() { return ""; } function set_schema($scheme) { return true; } function create_sql($table, $auto_increment, $style) { global $connection; $return = $connection->result("SELECT sql FROM sqlite_master WHERE type IN ('table', 'view') AND name = " . q($table)); foreach (indexes($table) as $name => $index) { if ($name == '') { continue; } $return .= ";\n\n" . index_sql($table, $index['type'], $name, "(" . implode(", ", array_map('idf_escape', $index['columns'])) . ")"); } return $return; } function truncate_sql($table) { return "DELETE FROM " . table($table); } function use_sql($database) { } function trigger_sql($table) { return implode(get_vals("SELECT sql || ';;\n' FROM sqlite_master WHERE type = 'trigger' AND tbl_name = " . q($table))); } function show_variables() { global $connection; $return = array(); foreach (array("auto_vacuum", "cache_size", "count_changes", "default_cache_size", "empty_result_callbacks", "encoding", "foreign_keys", "full_column_names", "fullfsync", "journal_mode", "journal_size_limit", "legacy_file_format", "locking_mode", "page_size", "max_page_count", "read_uncommitted", "recursive_triggers", "reverse_unordered_selects", "secure_delete", "short_column_names", "synchronous", "temp_store", "temp_store_directory", "schema_version", "integrity_check", "quick_check") as $key) { $return[$key] = $connection->result("PRAGMA $key"); } return $return; } function show_status() { $return = array(); foreach (get_vals("PRAGMA compile_options") as $option) { list($key, $val) = explode("=", $option, 2); $return[$key] = $val; } return $return; } function convert_field($field) { } function unconvert_field($field, $return) { return $return; } function support($feature) { return preg_match('~^(columns|database|drop_col|dump|indexes|descidx|move_col|sql|status|table|trigger|variables|view|view_trigger)$~', $feature); } $jush = "sqlite"; $types = array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0); $structured_types = array_keys($types); $unsigned = array(); $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"); // REGEXP can be user defined function $functions = array("hex", "length", "lower", "round", "unixepoch", "upper"); $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"); $edit_functions = array( array( // "text" => "date('now')/time('now')/datetime('now')", ), array( "integer|real|numeric" => "+/-", // "text" => "date/time/datetime", "text" => "||", ) ); } adminer-4.7.6/adminer/dump.inc.php000066400000000000000000000177151361500001000170110ustar00rootroot00000000000000 1)); $is_sql = preg_match('~sql~', $_POST["format"]); if ($is_sql) { echo "-- Adminer $VERSION " . $drivers[DRIVER] . " dump\n\n"; if ($jush == "sql") { echo "SET NAMES utf8; SET time_zone = '+00:00'; SET foreign_key_checks = 0; " . ($_POST["data_style"] ? "SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'; " : "") . " "; $connection->query("SET time_zone = '+00:00';"); } } $style = $_POST["db_style"]; $databases = array(DB); if (DB == "") { $databases = $_POST["databases"]; if (is_string($databases)) { $databases = explode("\n", rtrim(str_replace("\r", "", $databases), "\n")); } } foreach ((array) $databases as $db) { $adminer->dumpDatabase($db); if ($connection->select_db($db)) { if ($is_sql && preg_match('~CREATE~', $style) && ($create = $connection->result("SHOW CREATE DATABASE " . idf_escape($db), 1))) { set_utf8mb4($create); if ($style == "DROP+CREATE") { echo "DROP DATABASE IF EXISTS " . idf_escape($db) . ";\n"; } echo "$create;\n"; } if ($is_sql) { if ($style) { echo use_sql($db) . ";\n\n"; } $out = ""; if ($_POST["routines"]) { foreach (array("FUNCTION", "PROCEDURE") as $routine) { foreach (get_rows("SHOW $routine STATUS WHERE Db = " . q($db), null, "-- ") as $row) { $create = remove_definer($connection->result("SHOW CREATE $routine " . idf_escape($row["Name"]), 2)); set_utf8mb4($create); $out .= ($style != 'DROP+CREATE' ? "DROP $routine IF EXISTS " . idf_escape($row["Name"]) . ";;\n" : "") . "$create;;\n\n"; } } } if ($_POST["events"]) { foreach (get_rows("SHOW EVENTS", null, "-- ") as $row) { $create = remove_definer($connection->result("SHOW CREATE EVENT " . idf_escape($row["Name"]), 3)); set_utf8mb4($create); $out .= ($style != 'DROP+CREATE' ? "DROP EVENT IF EXISTS " . idf_escape($row["Name"]) . ";;\n" : "") . "$create;;\n\n"; } } if ($out) { echo "DELIMITER ;;\n\n$out" . "DELIMITER ;\n\n"; } } if ($_POST["table_style"] || $_POST["data_style"]) { $views = array(); foreach (table_status('', true) as $name => $table_status) { $table = (DB == "" || in_array($name, (array) $_POST["tables"])); $data = (DB == "" || in_array($name, (array) $_POST["data"])); if ($table || $data) { if ($ext == "tar") { $tmp_file = new TmpFile; ob_start(array($tmp_file, 'write'), 1e5); } $adminer->dumpTable($name, ($table ? $_POST["table_style"] : ""), (is_view($table_status) ? 2 : 0)); if (is_view($table_status)) { $views[] = $name; } elseif ($data) { $fields = fields($name); $adminer->dumpData($name, $_POST["data_style"], "SELECT *" . convert_fields($fields, $fields) . " FROM " . table($name)); } if ($is_sql && $_POST["triggers"] && $table && ($triggers = trigger_sql($name))) { echo "\nDELIMITER ;;\n$triggers\nDELIMITER ;\n"; } if ($ext == "tar") { ob_end_flush(); tar_file((DB != "" ? "" : "$db/") . "$name.csv", $tmp_file); } elseif ($is_sql) { echo "\n"; } } } foreach ($views as $view) { $adminer->dumpTable($view, $_POST["table_style"], 1); } if ($ext == "tar") { echo pack("x512"); } } } } if ($is_sql) { echo "-- " . $connection->result("SELECT NOW()") . "\n"; } exit; } page_header(lang('Export'), $error, ($_GET["export"] != "" ? array("table" => $_GET["export"]) : array()), h(DB)); ?>

"text", "format" => "sql", "db_style" => (DB != "" ? "" : "CREATE"), "table_style" => "DROP+CREATE", "data_style" => "INSERT"); } if (!isset($row["events"])) { // backwards compatibility $row["routines"] = $row["events"] = ($_GET["dump"] == ""); $row["triggers"] = $row["table_style"]; } echo "
" . lang('Output') . "" . html_select("output", $adminer->dumpOutput(), $row["output"], 0) . "\n"; // 0 - radio echo "
" . lang('Format') . "" . html_select("format", $adminer->dumpFormat(), $row["format"], 0) . "\n"; // 0 - radio echo ($jush == "sqlite" ? "" : "
" . lang('Database') . "" . html_select('db_style', $db_style, $row["db_style"]) . (support("routine") ? checkbox("routines", 1, $row["routines"], lang('Routines')) : "") . (support("event") ? checkbox("events", 1, $row["events"], lang('Events')) : "") ); echo "
" . lang('Tables') . "" . html_select('table_style', $table_style, $row["table_style"]) . checkbox("auto_increment", 1, $row["auto_increment"], lang('Auto Increment')) . (support("trigger") ? checkbox("triggers", 1, $row["triggers"], lang('Triggers')) : "") ; echo "
" . lang('Data') . "" . html_select('data_style', $data_style, $row["data_style"]); ?>

"; echo "\n"; $databases = $adminer->databases(); if ($databases) { foreach ($databases as $db) { if (!information_schema($db)) { $prefix = preg_replace('~_.*~', '', $db); echo "
" . script("qs('#check-tables').onclick = partial(formCheck, /^tables\\[/);", ""); echo "" . script("qs('#check-data').onclick = partial(formCheck, /^data\\[/);", ""); echo "\n"; $views = ""; $tables_list = tables_list(); foreach ($tables_list as $name => $type) { $prefix = preg_replace('~_.*~', '', $name); $checked = ($TABLE == "" || $TABLE == (substr($TABLE, -1) == "%" ? "$prefix%" : $name)); //! % may be part of table name $print = "
" . checkbox("tables[]", $name, $checked, $name, "", "block"); if ($type !== null && !preg_match('~table~i', $type)) { $views .= "$print\n"; } else { echo "$print\n"; } $prefixes[$prefix]++; } echo $views; if ($tables_list) { echo script("ajaxSetHtml('" . js_escape(ME) . "script=db');"); } } else { echo "
"; echo ""; echo script("qs('#check-databases').onclick = partial(formCheck, /^databases\\[/);", ""); echo "
" . checkbox("databases[]", $db, $TABLE == "" || $TABLE == "$prefix%", $db, "", "block") . "\n"; $prefixes[$prefix]++; } } } else { echo "
"; } } ?>

$val) { if ($key != "" && $val > 1) { echo ($first ? "

" : " ") . "" . h($key) . ""; $first = false; } } adminer-4.7.6/adminer/edit.inc.php000066400000000000000000000063031361500001000167600ustar00rootroot00000000000000 $field) { if (!isset($field["privileges"][$update ? "update" : "insert"]) || $adminer->fieldName($field) == "" || $field["generated"]) { unset($fields[$name]); } } if ($_POST && !$error && !isset($_GET["select"])) { $location = $_POST["referer"]; if ($_POST["insert"]) { // continue edit or insert $location = ($update ? null : $_SERVER["REQUEST_URI"]); } elseif (!preg_match('~^.+&select=.+$~', $location)) { $location = ME . "select=" . urlencode($TABLE); } $indexes = indexes($TABLE); $unique_array = unique_array($_GET["where"], $indexes); $query_where = "\nWHERE $where"; if (isset($_POST["delete"])) { queries_redirect( $location, lang('Item has been deleted.'), $driver->delete($TABLE, $query_where, !$unique_array) ); } else { $set = array(); foreach ($fields as $name => $field) { $val = process_input($field); if ($val !== false && $val !== null) { $set[idf_escape($name)] = $val; } } if ($update) { if (!$set) { redirect($location); } queries_redirect( $location, lang('Item has been updated.'), $driver->update($TABLE, $set, $query_where, !$unique_array) ); if (is_ajax()) { page_headers(); page_messages($error); exit; } } else { $result = $driver->insert($TABLE, $set); $last_id = ($result ? last_id() : 0); queries_redirect($location, lang('Item%s has been inserted.', ($last_id ? " $last_id" : "")), $result); //! link } } } $row = null; if ($_POST["save"]) { $row = (array) $_POST["fields"]; } elseif ($where) { $select = array(); foreach ($fields as $name => $field) { if (isset($field["privileges"]["select"])) { $as = convert_field($field); if ($_POST["clone"] && $field["auto_increment"]) { $as = "''"; } if ($jush == "sql" && preg_match("~enum|set~", $field["type"])) { $as = "1*" . idf_escape($name); } $select[] = ($as ? "$as AS " : "") . idf_escape($name); } } $row = array(); if (!support("table")) { $select = array("*"); } if ($select) { $result = $driver->select($TABLE, $select, array($where), $select, array(), (isset($_GET["select"]) ? 2 : 1)); if (!$result) { $error = error(); } else { $row = $result->fetch_assoc(); if (!$row) { // MySQLi returns null $row = false; } } if (isset($_GET["select"]) && (!$row || $result->fetch_assoc())) { // $result->num_rows != 1 isn't available in all drivers $row = null; } } } if (!support("table") && !$fields) { if (!$where) { // insert $result = $driver->select($TABLE, array("*"), $where, array("*")); $row = ($result ? $result->fetch_assoc() : false); if (!$row) { $row = array($driver->primary => ""); } } if ($row) { foreach ($row as $key => $val) { if (!$where) { $row[$key] = null; } $fields[$key] = array("field" => $key, "null" => ($key != $driver->primary), "auto_increment" => ($key == $driver->primary)); } } } edit_form($TABLE, $fields, $row, $update); adminer-4.7.6/adminer/event.inc.php000066400000000000000000000062451361500001000171610ustar00rootroot00000000000000 "ENABLE", "DISABLED" => "DISABLE", "SLAVESIDE_DISABLED" => "DISABLE ON SLAVE"); $row = $_POST; if ($_POST && !$error) { if ($_POST["drop"]) { query_redirect("DROP EVENT " . idf_escape($EVENT), substr(ME, 0, -1), lang('Event has been dropped.')); } elseif (in_array($row["INTERVAL_FIELD"], $intervals) && isset($statuses[$row["STATUS"]])) { $schedule = "\nON SCHEDULE " . ($row["INTERVAL_VALUE"] ? "EVERY " . q($row["INTERVAL_VALUE"]) . " $row[INTERVAL_FIELD]" . ($row["STARTS"] ? " STARTS " . q($row["STARTS"]) : "") . ($row["ENDS"] ? " ENDS " . q($row["ENDS"]) : "") //! ALTER EVENT doesn't drop ENDS - MySQL bug #39173 : "AT " . q($row["STARTS"]) ) . " ON COMPLETION" . ($row["ON_COMPLETION"] ? "" : " NOT") . " PRESERVE" ; queries_redirect(substr(ME, 0, -1), ($EVENT != "" ? lang('Event has been altered.') : lang('Event has been created.')), queries(($EVENT != "" ? "ALTER EVENT " . idf_escape($EVENT) . $schedule . ($EVENT != $row["EVENT_NAME"] ? "\nRENAME TO " . idf_escape($row["EVENT_NAME"]) : "") : "CREATE EVENT " . idf_escape($row["EVENT_NAME"]) . $schedule ) . "\n" . $statuses[$row["STATUS"]] . " COMMENT " . q($row["EVENT_COMMENT"]) . rtrim(" DO\n$row[EVENT_DEFINITION]", ";") . ";" )); } } page_header(($EVENT != "" ? lang('Alter event') . ": " . h($EVENT) : lang('Create event')), $error); if (!$row && $EVENT != "") { $rows = get_rows("SELECT * FROM information_schema.EVENTS WHERE EVENT_SCHEMA = " . q(DB) . " AND EVENT_NAME = " . q($EVENT)); $row = reset($rows); } ?>

" data-maxlength="64" autocapitalize="off">
">
">
" class="size">
" data-maxlength="64">

adminer-4.7.6/adminer/file.inc.php000066400000000000000000000031211361500001000167450ustar00rootroot00000000000000 $val) { $target[$key] = $row["target"][$key]; } $row["target"] = $target; } if ($jush == "sqlite") { queries_redirect($location, $message, recreate_table($TABLE, $TABLE, array(), array(), array(" $name" => ($_POST["drop"] ? "" : " " . format_foreign_key($row))))); } else { $alter = "ALTER TABLE " . table($TABLE); $drop = "\nDROP " . ($jush == "sql" ? "FOREIGN KEY " : "CONSTRAINT ") . idf_escape($name); if ($_POST["drop"]) { query_redirect($alter . $drop, $location, $message); } else { query_redirect($alter . ($name != "" ? "$drop," : "") . "\nADD" . format_foreign_key($row), $location, $message); $error = lang('Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.') . "
$error"; //! no partitioning } } } page_header(lang('Foreign key'), $error, array("table" => $TABLE), h($TABLE)); if ($_POST) { ksort($row["source"]); if ($_POST["add"]) { $row["source"][] = ""; } elseif ($_POST["change"] || $_POST["change-js"]) { $row["target"] = array(); } } elseif ($name != "") { $foreign_keys = foreign_keys($TABLE); $row = $foreign_keys[$name]; $row["source"][] = ""; } else { $row["table"] = $TABLE; $row["source"] = array(""); } ?>
select_db($row["db"]); } if ($row["ns"] != "") { set_schema($row["ns"]); } $referencable = array_keys(array_filter(table_status('', true), 'fk_support')); $target = ($TABLE === $row["table"] ? $source : array_keys(fields(in_array($row["table"], $referencable) ? $row["table"] : reset($referencable)))); $onchange = "this.form['change-js'].value = '1'; this.form.submit();"; echo "

" . lang('Target table') . ": " . html_select("table", $referencable, $row["table"], $onchange) . "\n"; if ($jush == "pgsql") { echo lang('Schema') . ": " . html_select("ns", $adminer->schemas(), $row["ns"] != "" ? $row["ns"] : $_GET["ns"], $onchange); } elseif ($jush != "sqlite") { $dbs = array(); foreach ($adminer->databases() as $db) { if (!information_schema($db)) { $dbs[] = $db; } } echo lang('DB') . ": " . html_select("db", $dbs, $row["db"] != "" ? $row["db"] : $_GET["db"], $onchange); } ?>

$val) { echo ""; echo "
" . html_select("source[" . (+$key) . "]", array(-1 => "") + $source, $val, ($j == count($row["source"]) - 1 ? "foreignAddRow.call(this);" : 1), "label-source"); echo "" . html_select("target[" . (+$key) . "]", $target, $row["target"][$key], 1, "label-target"); $j++; } ?>

: "") + explode("|", $on_actions), $row["on_delete"]); ?> : "") + explode("|", $on_actions), $row["on_update"]); ?> "innodb-foreign-key-constraints.html", 'mariadb' => "foreign-keys/", 'pgsql' => "sql-createtable.html#SQL-CREATETABLE-REFERENCES", 'mssql' => "ms174979.aspx", 'oracle' => "https://docs.oracle.com/cd/B19306_01/server.102/b14200/clauses002.htm#sthref2903", )); ?>

adminer-4.7.6/adminer/include/000077500000000000000000000000001361500001000161735ustar00rootroot00000000000000adminer-4.7.6/adminer/include/adminer.inc.php000066400000000000000000001075201361500001000211000ustar00rootroot00000000000000Adminer"; } /** Connection parameters * @return array ($server, $username, $password) */ function credentials() { return array(SERVER, $_GET["username"], get_password()); } /** Get SSL connection options * @return array array("key" => filename, "cert" => filename, "ca" => filename) or null */ function connectSsl() { } /** Get key used for permanent login * @param bool * @return string cryptic string which gets combined with password or false in case of an error */ function permanentLogin($create = false) { return password_file($create); } /** Return key used to group brute force attacks; behind a reverse proxy, you want to return the last part of X-Forwarded-For * @return string */ function bruteForceKey() { return $_SERVER["REMOTE_ADDR"]; } /** Get server name displayed in breadcrumbs * @param string * @return string HTML code or null */ function serverName($server) { return h($server); } /** Identifier of selected database * @return string */ function database() { // should be used everywhere instead of DB return DB; } /** Get cached list of databases * @param bool * @return array */ function databases($flush = true) { return get_databases($flush); } /** Get list of schemas * @return array */ function schemas() { return schemas(); } /** Specify limit for waiting on some slow queries like DB list * @return float number of seconds */ function queryTimeout() { return 2; } /** Headers to send before HTML output * @return null */ function headers() { } /** Get Content Security Policy headers * @return array of arrays with directive name in key, allowed sources in value */ function csp() { return csp(); } /** Print HTML code inside * @return bool true to link favicon.ico and adminer.css if exists */ function head() { ?> \n"; echo $this->loginFormField('driver', '' . lang('System') . '', html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);") . "\n"); echo $this->loginFormField('server', '' . lang('Server') . '', '' . "\n"); echo $this->loginFormField('username', '' . lang('Username') . '', '' . script("focus(qs('#username')); qs('#username').form['auth[driver]'].onchange();")); echo $this->loginFormField('password', '' . lang('Password') . '', '' . "\n"); echo $this->loginFormField('db', '' . lang('Database') . '', '' . "\n"); echo "\n"; echo "

\n"; echo checkbox("auth[permanent]", 1, $_COOKIE["adminer_permanent"], lang('Permanent login')) . "\n"; } /** Get login form field * @param string * @param string HTML * @param string HTML * @return string */ function loginFormField($name, $heading, $value) { return $heading . $value; } /** Authorize the user * @param string * @param string * @return mixed true for success, string for error message, false for unknown error */ function login($login, $password) { if ($password == "") { return lang('Adminer does not support accessing a database without a password, more information.', target_blank()); } return true; } /** Table caption used in navigation and headings * @param array result of SHOW TABLE STATUS * @return string HTML code, "" to ignore table */ function tableName($tableStatus) { return h($tableStatus["Name"]); } /** Field caption used in select and edit * @param array single field returned from fields() * @param int order of column in select * @return string HTML code, "" to ignore field */ function fieldName($field, $order = 0) { return '' . h($field["field"]) . ''; } /** Print links after select heading * @param array result of SHOW TABLE STATUS * @param string new item options, NULL for no new item * @return null */ function selectLinks($tableStatus, $set = "") { global $jush, $driver; echo '

\n"; // required for IE9 inline edit if (!$failed && ($warnings = $driver->warnings())) { $id = "warnings"; $return = ", " . lang('Warnings') . "" . script("qsl('a').onclick = partial(toggle, '$id');", "") . "$return\n" ; } return "

" . h(str_replace("\n", " ", $query)) . " (" . format_time($start) . ")" . (support("sql") ? " " . lang('Edit') . "" : "") . $return ; } /** Query printed in SQL command before execution * @param string query to be executed * @return string escaped query to be printed */ function sqlCommandQuery($query) { return shorten_utf8(trim($query), 1000); } /** Description of a row in a table * @param string * @return string SQL expression, empty string for no description */ function rowDescription($table) { return ""; } /** Get descriptions of selected data * @param array all data to print * @param array * @return array */ function rowDescriptions($rows, $foreignKeys) { return $rows; } /** Get a link to use in select table * @param string raw value of the field * @param array single field returned from fields() * @return string or null to create the default link */ function selectLink($val, $field) { } /** Value printed in select table * @param string HTML-escaped value to print * @param string link to foreign key * @param array single field returned from fields() * @param array original value before applying editVal() and escaping * @return string */ function selectVal($val, $link, $field, $original) { $return = ($val === null ? "NULL" : (preg_match("~char|binary|boolean~", $field["type"]) && !preg_match("~var~", $field["type"]) ? "$val" : $val)); if (preg_match('~blob|bytea|raw|file~', $field["type"]) && !is_utf8($val)) { $return = "" . lang('%d byte(s)', strlen($original)) . ""; } if (preg_match('~json~', $field["type"])) { $return = "$return"; } return ($link ? "$return" : $return); } /** Value conversion used in select and edit * @param string * @param array single field returned from fields() * @return string */ function editVal($val, $field) { return $val; } /** Print table structure in tabular format * @param array data about individual fields * @return null */ function tableStructurePrint($fields) { echo "

\n"; echo "\n"; echo "\n"; foreach ($fields as $field) { echo "
" . lang('Column') . "" . lang('Type') . (support("comment") ? "" . lang('Comment') : "") . "
" . h($field["field"]); echo "" . h($field["full_type"]) . ""; echo ($field["null"] ? " NULL" : ""); echo ($field["auto_increment"] ? " " . lang('Auto Increment') . "" : ""); echo (isset($field["default"]) ? " [" . h($field["default"]) . "]" : ""); echo (support("comment") ? "" . h($field["comment"]) : ""); echo "\n"; } echo "
\n"; echo "
\n"; } /** Print list of indexes on table in tabular format * @param array data about all indexes on a table * @return null */ function tableIndexesPrint($indexes) { echo "\n"; foreach ($indexes as $name => $index) { ksort($index["columns"]); // enforce correct columns order $print = array(); foreach ($index["columns"] as $key => $val) { $print[] = "" . h($val) . "" . ($index["lengths"][$key] ? "(" . $index["lengths"][$key] . ")" : "") . ($index["descs"][$key] ? " DESC" : "") ; } echo "
$index[type]" . implode(", ", $print) . "\n"; } echo "
\n"; } /** Print columns box in select * @param array result of selectColumnsProcess()[0] * @param array selectable columns * @return null */ function selectColumnsPrint($select, $columns) { global $functions, $grouping; print_fieldset("select", lang('Select'), $select); $i = 0; $select[""] = array(); foreach ($select as $key => $val) { $val = $_GET["columns"][$key]; $column = select_input( " name='columns[$i][col]'", $columns, $val["col"], ($key !== "" ? "selectFieldChange" : "selectAddRow") ); echo "
" . ($functions || $grouping ? "" . on_help("getTarget(event).value && getTarget(event).value.replace(/ |\$/, '(') + ')'", 1) . script("qsl('select').onchange = function () { helpClose();" . ($key !== "" ? "" : " qsl('select, input', this.parentNode).onchange();") . " };", "") . "($column)" : $column) . "
\n"; $i++; } echo "\n"; } /** Print search box in select * @param array result of selectSearchProcess() * @param array selectable columns * @param array * @return null */ function selectSearchPrint($where, $columns, $indexes) { print_fieldset("search", lang('Search'), $where); foreach ($indexes as $i => $index) { if ($index["type"] == "FULLTEXT") { echo "
(" . implode(", ", array_map('h', $index["columns"])) . ") AGAINST"; echo " "; echo script("qsl('input').oninput = selectFieldChange;", ""); echo checkbox("boolean[$i]", 1, isset($_GET["boolean"][$i]), "BOOL"); echo "
\n"; } } $change_next = "this.parentNode.firstChild.onchange();"; foreach (array_merge((array) $_GET["where"], array(array())) as $i => $val) { if (!$val || ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators))) { echo "
" . select_input( " name='where[$i][col]'", $columns, $val["col"], ($val ? "selectFieldChange" : "selectAddRow"), "(" . lang('anywhere') . ")" ); echo html_select("where[$i][op]", $this->operators, $val["op"], $change_next); echo ""; echo script("mixin(qsl('input'), {oninput: function () { $change_next }, onkeydown: selectSearchKeydown, onsearch: selectSearchSearch});", ""); echo "
\n"; } } echo "\n"; } /** Print order box in select * @param array result of selectOrderProcess() * @param array selectable columns * @param array * @return null */ function selectOrderPrint($order, $columns, $indexes) { print_fieldset("sort", lang('Sort'), $order); $i = 0; foreach ((array) $_GET["order"] as $key => $val) { if ($val != "") { echo "
" . select_input(" name='order[$i]'", $columns, $val, "selectFieldChange"); echo checkbox("desc[$i]", 1, isset($_GET["desc"][$key]), lang('descending')) . "
\n"; $i++; } } echo "
" . select_input(" name='order[$i]'", $columns, "", "selectAddRow"); echo checkbox("desc[$i]", 1, false, lang('descending')) . "
\n"; echo "\n"; } /** Print limit box in select * @param string result of selectLimitProcess() * @return null */ function selectLimitPrint($limit) { echo "
" . lang('Limit') . "
"; //
for easy styling echo ""; echo script("qsl('input').oninput = selectFieldChange;", ""); echo "
\n"; } /** Print text length box in select * @param string result of selectLengthProcess() * @return null */ function selectLengthPrint($text_length) { if ($text_length !== null) { echo "
" . lang('Text length') . "
"; echo ""; echo "
\n"; } } /** Print action box in select * @param array * @return null */ function selectActionPrint($indexes) { echo "
" . lang('Action') . "
"; echo ""; echo " "; echo "\n"; echo "var indexColumns = "; $columns = array(); foreach ($indexes as $index) { $current_key = reset($index["columns"]); if ($index["type"] != "FULLTEXT" && $current_key) { $columns[$current_key] = 1; } } $columns[""] = 1; foreach ($columns as $key => $val) { json_row($key); } echo ";\n"; echo "selectFieldChange.call(qs('#form')['select']);\n"; echo "\n"; echo "
\n"; } /** Print command box in select * @return bool whether to print default commands */ function selectCommandPrint() { return !information_schema(DB); } /** Print import box in select * @return bool whether to print default import */ function selectImportPrint() { return !information_schema(DB); } /** Print extra text in the end of a select form * @param array fields holding e-mails * @param array selectable columns * @return null */ function selectEmailPrint($emailFields, $columns) { } /** Process columns box in select * @param array selectable columns * @param array * @return array (array(select_expressions), array(group_expressions)) */ function selectColumnsProcess($columns, $indexes) { global $functions, $grouping; $select = array(); // select expressions, empty for * $group = array(); // expressions without aggregation - will be used for GROUP BY if an aggregation function is used foreach ((array) $_GET["columns"] as $key => $val) { if ($val["fun"] == "count" || ($val["col"] != "" && (!$val["fun"] || in_array($val["fun"], $functions) || in_array($val["fun"], $grouping)))) { $select[$key] = apply_sql_function($val["fun"], ($val["col"] != "" ? idf_escape($val["col"]) : "*")); if (!in_array($val["fun"], $grouping)) { $group[] = $select[$key]; } } } return array($select, $group); } /** Process search box in select * @param array * @param array * @return array expressions to join by AND */ function selectSearchProcess($fields, $indexes) { global $connection, $driver; $return = array(); foreach ($indexes as $i => $index) { if ($index["type"] == "FULLTEXT" && $_GET["fulltext"][$i] != "") { $return[] = "MATCH (" . implode(", ", array_map('idf_escape', $index["columns"])) . ") AGAINST (" . q($_GET["fulltext"][$i]) . (isset($_GET["boolean"][$i]) ? " IN BOOLEAN MODE" : "") . ")"; } } foreach ((array) $_GET["where"] as $key => $val) { if ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators)) { $prefix = ""; $cond = " $val[op]"; if (preg_match('~IN$~', $val["op"])) { $in = process_length($val["val"]); $cond .= " " . ($in != "" ? $in : "(NULL)"); } elseif ($val["op"] == "SQL") { $cond = " $val[val]"; // SQL injection } elseif ($val["op"] == "LIKE %%") { $cond = " LIKE " . $this->processInput($fields[$val["col"]], "%$val[val]%"); } elseif ($val["op"] == "ILIKE %%") { $cond = " ILIKE " . $this->processInput($fields[$val["col"]], "%$val[val]%"); } elseif ($val["op"] == "FIND_IN_SET") { $prefix = "$val[op](" . q($val["val"]) . ", "; $cond = ")"; } elseif (!preg_match('~NULL$~', $val["op"])) { $cond .= " " . $this->processInput($fields[$val["col"]], $val["val"]); } if ($val["col"] != "") { $return[] = $prefix . $driver->convertSearch(idf_escape($val["col"]), $val, $fields[$val["col"]]) . $cond; } else { // find anywhere $cols = array(); foreach ($fields as $name => $field) { if ((preg_match('~^[-\d.' . (preg_match('~IN$~', $val["op"]) ? ',' : '') . ']+$~', $val["val"]) || !preg_match('~' . number_type() . '|bit~', $field["type"])) && (!preg_match("~[\x80-\xFF]~", $val["val"]) || preg_match('~char|text|enum|set~', $field["type"])) ) { $cols[] = $prefix . $driver->convertSearch(idf_escape($name), $val, $field) . $cond; } } $return[] = ($cols ? "(" . implode(" OR ", $cols) . ")" : "1 = 0"); } } } return $return; } /** Process order box in select * @param array * @param array * @return array expressions to join by comma */ function selectOrderProcess($fields, $indexes) { $return = array(); foreach ((array) $_GET["order"] as $key => $val) { if ($val != "") { $return[] = (preg_match('~^((COUNT\(DISTINCT |[A-Z0-9_]+\()(`(?:[^`]|``)+`|"(?:[^"]|"")+")\)|COUNT\(\*\))$~', $val) ? $val : idf_escape($val)) //! MS SQL uses [] . (isset($_GET["desc"][$key]) ? " DESC" : "") ; } } return $return; } /** Process limit box in select * @return string expression to use in LIMIT, will be escaped */ function selectLimitProcess() { return (isset($_GET["limit"]) ? $_GET["limit"] : "50"); } /** Process length box in select * @return string number of characters to shorten texts, will be escaped */ function selectLengthProcess() { return (isset($_GET["text_length"]) ? $_GET["text_length"] : "100"); } /** Process extras in select form * @param array AND conditions * @param array * @return bool true if processed, false to process other parts of form */ function selectEmailProcess($where, $foreignKeys) { 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 * @param string elapsed time * @param bool * @return string */ function messageQuery($query, $time, $failed = false) { global $jush, $driver; restart_session(); $history = &get_session("queries"); if (!$history[$_GET["db"]]) { $history[$_GET["db"]] = array(); } if (strlen($query) > 1e6) { $query = preg_replace('~[\x80-\xFF]+$~', '', substr($query, 0, 1e6)) . "\n…"; // [\x80-\xFF] - valid UTF-8, \n - can end by one-line comment } $history[$_GET["db"]][] = array($query, time(), $time); // not DB - $_GET["db"] is changed in database.inc.php //! respect $_GET["ns"] $sql_id = "sql-" . count($history[$_GET["db"]]); $return = "" . lang('SQL command') . "\n"; if (!$failed && ($warnings = $driver->warnings())) { $id = "warnings-" . count($history[$_GET["db"]]); $return = "" . lang('Warnings') . ", $return\n"; } return " " . @date("H:i:s") . "" // @ - time zone may be not set . " $return' ; } /** Functions displayed in edit form * @param array single field from fields() * @return array */ function editFunctions($field) { global $edit_functions; $return = ($field["null"] ? "NULL/" : ""); foreach ($edit_functions as $key => $functions) { if (!$key || (!isset($_GET["call"]) && (isset($_GET["select"]) || where($_GET)))) { // relative functions foreach ($functions as $pattern => $val) { if (!$pattern || preg_match("~$pattern~", $field["type"])) { $return .= "/$val"; } } if ($key && !preg_match('~set|blob|bytea|raw|file~', $field["type"])) { $return .= "/SQL"; } } } if ($field["auto_increment"] && !isset($_GET["select"]) && !where($_GET)) { $return = lang('Auto Increment'); } return explode("/", $return); } /** Get options to display edit field * @param string table name * @param array single field from fields() * @param string attributes to use inside the tag * @param string * @return string custom input field or empty string for default */ function editInput($table, $field, $attrs, $value) { if ($field["type"] == "enum") { return (isset($_GET["select"]) ? " " : "") . ($field["null"] ? " " : "") . enum_input("radio", $attrs, $field, $value, 0) // 0 - empty ; } return ""; } /** Get hint for edit field * @param string table name * @param array single field from fields() * @param string * @return string */ function editHint($table, $field, $value) { return ""; } /** Process sent input * @param array single field from fields() * @param string * @param string * @return string expression to use in a query */ function processInput($field, $value, $function = "") { if ($function == "SQL") { return $value; // SQL injection } $name = $field["field"]; $return = q($value); if (preg_match('~^(now|getdate|uuid)$~', $function)) { $return = "$function()"; } elseif (preg_match('~^current_(date|timestamp)$~', $function)) { $return = $function; } elseif (preg_match('~^([+-]|\|\|)$~', $function)) { $return = idf_escape($name) . " $function $return"; } elseif (preg_match('~^[+-] interval$~', $function)) { $return = idf_escape($name) . " $function " . (preg_match("~^(\\d+|'[0-9.: -]') [A-Z_]+\$~i", $value) ? $value : $return); } elseif (preg_match('~^(addtime|subtime|concat)$~', $function)) { $return = "$function(" . idf_escape($name) . ", $return)"; } elseif (preg_match('~^(md5|sha1|password|encrypt)$~', $function)) { $return = "$function($return)"; } return unconvert_field($field, $return); } /** Returns export output options * @return array */ function dumpOutput() { $return = array('text' => lang('open'), 'file' => lang('save')); if (function_exists('gzencode')) { $return['gz'] = 'gzip'; } return $return; } /** Returns export format options * @return array empty to disable export */ function dumpFormat() { return array('sql' => 'SQL', 'csv' => 'CSV,', 'csv;' => 'CSV;', 'tsv' => 'TSV'); } /** Export database structure * @param string * @return null prints data */ function dumpDatabase($db) { } /** Export table structure * @param string * @param string * @param int 0 table, 1 view, 2 temporary view table * @return null prints data */ function dumpTable($table, $style, $is_view = 0) { if ($_POST["format"] != "sql") { echo "\xef\xbb\xbf"; // UTF-8 byte order mark if ($style) { dump_csv(array_keys(fields($table))); } } else { if ($is_view == 2) { $fields = array(); foreach (fields($table) as $name => $field) { $fields[] = idf_escape($name) . " $field[full_type]"; } $create = "CREATE TABLE " . table($table) . " (" . implode(", ", $fields) . ")"; } else { $create = create_sql($table, $_POST["auto_increment"], $style); } set_utf8mb4($create); if ($style && $create) { if ($style == "DROP+CREATE" || $is_view == 1) { echo "DROP " . ($is_view == 2 ? "VIEW" : "TABLE") . " IF EXISTS " . table($table) . ";\n"; } if ($is_view == 1) { $create = remove_definer($create); } echo "$create;\n\n"; } } } /** Export table data * @param string * @param string * @param string * @return null prints data */ function dumpData($table, $style, $query) { global $connection, $jush; $max_packet = ($jush == "sqlite" ? 0 : 1048576); // default, minimum is 1024 if ($style) { if ($_POST["format"] == "sql") { if ($style == "TRUNCATE+INSERT") { echo truncate_sql($table) . ";\n"; } $fields = fields($table); } $result = $connection->query($query, 1); // 1 - MYSQLI_USE_RESULT //! enum and set as numbers if ($result) { $insert = ""; $buffer = ""; $keys = array(); $suffix = ""; $fetch_function = ($table != '' ? 'fetch_assoc' : 'fetch_row'); while ($row = $result->$fetch_function()) { 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($keys); $style = "INSERT"; } dump_csv($row); } else { if (!$insert) { $insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('idf_escape', $keys)) . ") VALUES"; } foreach ($row as $key => $val) { $field = $fields[$key]; $row[$key] = ($val !== null ? unconvert_field($field, preg_match(number_type(), $field["type"]) && !preg_match('~\[~', $field["full_type"]) && is_numeric($val) ? $val : q(($val === false ? 0 : $val))) : "NULL" ); } $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 { echo $buffer . $suffix; $buffer = $insert . $s; } } } if ($buffer) { echo $buffer . $suffix; } } elseif ($_POST["format"] == "sql") { echo "-- " . str_replace("\n", " ", $connection->error) . "\n"; } } } /** Set export filename * @param string * @return string filename without extension */ function dumpFilename($identifier) { return friendly_url($identifier != "" ? $identifier : (SERVER != "" ? SERVER : "localhost")); } /** Send headers for export * @param string * @param bool * @return string extension */ function dumpHeaders($identifier, $multi_table = false) { $output = $_POST["output"]; $ext = (preg_match('~sql~', $_POST["format"]) ? "sql" : ($multi_table ? "tar" : "csv")); // multiple CSV packed to TAR header("Content-Type: " . ($output == "gz" ? "application/x-gzip" : ($ext == "tar" ? "application/x-tar" : ($ext == "sql" || $output != "file" ? "text/plain" : "text/csv") . "; charset=utf-8" ))); if ($output == "gz") { ob_start('ob_gzencode', 1e6); } return $ext; } /** Set the path of the file for webserver load * @return string path of the sql dump file */ function importServerPath() { return "adminer.sql"; } /** Print homepage * @return bool whether to print default homepage */ function homepage() { echo '

name(); ?> id="version">

$servers) { foreach ($servers as $server => $usernames) { foreach ($usernames as $username => $password) { if ($password !== null) { $dbs = $_SESSION["db"][$vendor][$server][$username]; foreach (($dbs ? array_keys($dbs) : array("")) as $db) { $output .= "
  • ($drivers[$vendor]) " . h($username . ($server != "" ? "@" . $this->serverName($server) : "") . ($db != "" ? " - $db" : "")) . "\n"; } } } } } if ($output) { echo "\n" . script("mixin(qs('#logins'), {onmouseover: menuOver, onmouseout: menuOut});"); } } else { if ($_GET["ns"] !== "" && !$missing && DB != "") { $connection->select_db(DB); $tables = table_status('', true); } echo script_src("../externals/jush/modules/jush.js"); echo script_src("../externals/jush/modules/jush-textarea.js"); echo script_src("../externals/jush/modules/jush-txt.js"); echo script_src("../externals/jush/modules/jush-js.js"); if (support("sql")) { echo script_src("../externals/jush/modules/jush-$jush.js"); ?> > $type) { $links[] = preg_quote($table, '/'); } echo "var jushLinks = { $jush: [ '" . js_escape(ME) . (support("table") ? "table=" : "select=") . "\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n"; foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) { echo "jushLinks.$val = jushLinks.$jush;\n"; } } $server_info = $connection->server_info; ?> bodyLoad(''); databasesPrint($missing); if (DB == "" || !$missing) { echo "

    " . lang('No tables.') . "\n"; } else { $this->tablesPrint($tables); } } } } /** Prints databases list in menu * @param string * @return null */ function databasesPrint($missing) { global $adminer, $connection; $databases = $this->databases(); if ($databases && !in_array(DB, $databases)) { array_unshift($databases, DB); } ?>

    " . lang('DB') . ": " . ($databases ? "$db_events" : "\n" ); echo "\n"; if ($missing != "db" && DB != "" && $connection->select_db(DB)) { if (support("scheme")) { echo "
    " . lang('Schema') . ": $db_events"; if ($_GET["ns"] != "") { set_schema($_GET["ns"]); } } } foreach (array("import", "sql", "schema", "dump", "privileges") as $val) { if (isset($_GET[$val])) { echo ""; break; } } echo "

    \n"; } /** Prints table list in menu * @param array result of table_status('', true) * @return null */ function tablesPrint($tables) { echo "\n"; } } $adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer); if ($adminer->operators === null) { $adminer->operators = $operators; } adminer-4.7.6/adminer/include/auth.inc.php000066400000000000000000000164271361500001000204270ustar00rootroot00000000000000 $val) { if ($val[0] < $time) { unset($invalids[$ip]); } } } $invalid = &$invalids[$adminer->bruteForceKey()]; if (!$invalid) { $invalid = array($time + 30*60, 0); // active for 30 minutes } $invalid[1]++; file_write_unlock($fp, serialize($invalids)); } function check_invalid_login() { global $adminer; $invalids = unserialize(@file_get_contents(get_temp_dir() . "/adminer.invalid")); // @ - may not exist $invalid = $invalids[$adminer->bruteForceKey()]; $next_attempt = ($invalid[1] > 29 ? $invalid[0] - time() : 0); // allow 30 invalid attempts if ($next_attempt > 0) { //! do the same with permanent login auth_error(lang('Too many unsuccessful logins, try again in %d minute(s).', ceil($next_attempt / 60))); } } $auth = $_POST["auth"]; if ($auth) { session_regenerate_id(); // defense against session fixation $vendor = $auth["driver"]; $server = $auth["server"]; $username = $auth["username"]; $password = (string) $auth["password"]; $db = $auth["db"]; set_password($vendor, $server, $username, $password); $_SESSION["db"][$vendor][$server][$username][$db] = true; if ($auth["permanent"]) { $key = base64_encode($vendor) . "-" . base64_encode($server) . "-" . base64_encode($username) . "-" . base64_encode($db); $private = $adminer->permanentLogin(true); $permanent[$key] = "$key:" . base64_encode($private ? encrypt_string($password, $private) : ""); cookie("adminer_permanent", implode(" ", $permanent)); } if (count($_POST) == 1 // 1 - auth || DRIVER != $vendor || SERVER != $server || $_GET["username"] !== $username // "0" == "00" || DB != $db ) { redirect(auth_url($vendor, $server, $username, $db)); } } elseif ($_POST["logout"]) { if ($has_token && !verify_token()) { page_header(lang('Logout'), lang('Invalid CSRF token. Send the form again.')); page_footer("db"); exit; } else { foreach (array("pwds", "db", "dbs", "queries") as $key) { set_session($key, null); } unset_permanent(); redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.') . ' ' . lang('Thanks for using Adminer, consider donating.')); } } elseif ($permanent && !$_SESSION["pwds"]) { session_regenerate_id(); $private = $adminer->permanentLogin(); foreach ($permanent as $key => $val) { list(, $cipher) = explode(":", $val); list($vendor, $server, $username, $db) = array_map('base64_decode', explode("-", $key)); set_password($vendor, $server, $username, decrypt_string(base64_decode($cipher), $private)); $_SESSION["db"][$vendor][$server][$username][$db] = true; } } function unset_permanent() { global $permanent; foreach ($permanent as $key => $val) { list($vendor, $server, $username, $db) = array_map('base64_decode', explode("-", $key)); if ($vendor == DRIVER && $server == SERVER && $username == $_GET["username"] && $db == DB) { unset($permanent[$key]); } } cookie("adminer_permanent", implode(" ", $permanent)); } /** Renders an error message and a login form * @param string plain text * @return null exits */ function auth_error($error) { global $adminer, $has_token; $session_name = session_name(); if (isset($_GET["username"])) { header("HTTP/1.1 403 Forbidden"); // 401 requires sending WWW-Authenticate header if (($_COOKIE[$session_name] || $_GET[$session_name]) && !$has_token) { $error = lang('Session expired, please login again.'); } else { restart_session(); add_invalid_login(); $password = get_password(); if ($password !== null) { if ($password === false) { $error .= '
    ' . lang('Master password expired. Implement %s method to make it permanent.', target_blank(), 'permanentLogin()'); } set_password(DRIVER, SERVER, $_GET["username"], null); } unset_permanent(); } } if (!$_COOKIE[$session_name] && $_GET[$session_name] && ini_bool("session.use_only_cookies")) { $error = lang('Session support must be enabled.'); } $params = session_get_cookie_params(); cookie("adminer_key", ($_COOKIE["adminer_key"] ? $_COOKIE["adminer_key"] : rand_string()), $params["lifetime"]); page_header(lang('Login'), $error, null); echo "
    \n"; echo "
    "; if (hidden_fields($_POST, array("auth"))) { // expired session echo "

    " . lang('The action will be performed after successful login with the same credentials.') . "\n"; } echo "

    \n"; $adminer->loginForm(); echo "
    \n"; page_footer("auth"); exit; } if (isset($_GET["username"]) && !class_exists("Min_DB")) { 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; } stop_session(true); if (isset($_GET["username"]) && is_string(get_password())) { list($host, $port) = explode(":", SERVER, 2); if (is_numeric($port) && ($port < 1024 || $port > 65535)) { auth_error(lang('Connecting to privileged ports is not allowed.')); } check_invalid_login(); $connection = connect(); $driver = new Min_Driver($connection); } $login = null; if (!is_object($connection) || ($login = $adminer->login($_GET["username"], get_password())) !== true) { $error = (is_string($connection) ? h($connection) : (is_string($login) ? $login : lang('Invalid credentials.'))); auth_error($error . (preg_match('~^ | $~', get_password()) ? '
    ' . lang('There is a space in the input password which might be the cause.') : '')); } if ($auth && $_POST["token"]) { $_POST["token"] = $token; // reset token after explicit login } $error = ''; ///< @var string if ($_POST) { if (!verify_token()) { $ini = "max_input_vars"; $max_vars = ini_get($ini); if (extension_loaded("suhosin")) { foreach (array("suhosin.request.max_vars", "suhosin.post.max_vars") as $key) { $val = ini_get($key); if ($val && (!$max_vars || $val < $max_vars)) { $ini = $key; $max_vars = $val; } } } $error = (!$_POST["token"] && $max_vars ? lang('Maximum number of allowed fields exceeded. Please increase %s.', "'$ini'") : lang('Invalid CSRF token. Send the form again.') . ' ' . lang('If you did not send this request from Adminer then close this page.') ); } } elseif ($_SERVER["REQUEST_METHOD"] == "POST") { // posted form with no data means that post_max_size exceeded because Adminer always sends token at least $error = lang('Too big POST data. Reduce the data or increase the %s configuration directive.', "'post_max_size'"); if (isset($_GET["sql"])) { $error .= ' ' . lang('You can upload a big SQL file via FTP and import it from server.'); } } adminer-4.7.6/adminer/include/bootstrap.inc.php000066400000000000000000000103221361500001000214670ustar00rootroot00000000000000 $_POST["signature"], "version" => $_POST["version"]))); } exit; } global $adminer, $connection, $driver, $drivers, $edit_functions, $enum_length, $error, $functions, $grouping, $HTTPS, $inout, $jush, $LANG, $langs, $on_actions, $permanent, $structured_types, $has_token, $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"]; } if (!strpos($_SERVER["REQUEST_URI"], '?') && $_SERVER["QUERY_STRING"] != "") { // IIS 7 compatibility $_SERVER["REQUEST_URI"] .= "?$_SERVER[QUERY_STRING]"; } if ($_SERVER["HTTP_X_FORWARDED_PREFIX"]) { $_SERVER["REQUEST_URI"] = $_SERVER["HTTP_X_FORWARDED_PREFIX"] . $_SERVER["REQUEST_URI"]; } $HTTPS = ($_SERVER["HTTPS"] && strcasecmp($_SERVER["HTTPS"], "off")) || ini_bool("session.cookie_secure"); // session.cookie_secure could be set on HTTP if we are behind a reverse proxy @ini_set("session.use_trans_sid", false); // protect links in export, @ - may be disabled if (!defined("SID")) { session_cache_limiter(""); // to allow restarting session session_name("adminer_sid"); // use specific session name to get own namespace $params = array(0, preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"]), "", $HTTPS); if (version_compare(PHP_VERSION, '5.2.0') >= 0) { $params[] = true; // HttpOnly } call_user_func_array('session_set_cookie_params', $params); // ini_set() may be disabled session_start(); } // disable magic quotes to be able to use database escaping function remove_slashes(array(&$_GET, &$_POST, &$_COOKIE), $filter); if (get_magic_quotes_runtime()) { set_magic_quotes_runtime(false); } @set_time_limit(0); // @ - can be disabled @ini_set("zend.ze1_compatibility_mode", false); // @ - deprecated @ini_set("precision", 15); // @ - can be disabled, 15 - internal PHP precision include "../adminer/include/lang.inc.php"; include "../adminer/lang/$LANG.inc.php"; include "../adminer/include/pdo.inc.php"; include "../adminer/include/driver.inc.php"; include "../adminer/drivers/sqlite.inc.php"; include "../adminer/drivers/pgsql.inc.php"; include "../adminer/drivers/oracle.inc.php"; include "../adminer/drivers/mssql.inc.php"; include "../adminer/drivers/firebird.inc.php"; include "../adminer/drivers/simpledb.inc.php"; include "../adminer/drivers/mongo.inc.php"; include "../adminer/drivers/elastic.inc.php"; include "../adminer/drivers/clickhouse.inc.php"; include "../adminer/drivers/mysql.inc.php"; // must be included as last driver define("SERVER", $_GET[DRIVER]); // read from pgsql=localhost define("DB", $_GET["db"]); // for the sake of speed and size define("ME", str_replace(":", "%3a", preg_replace('~^[^?]*/([^?]*).*~', '\1', $_SERVER["REQUEST_URI"])) . '?' . (sid() ? SID . '&' : '') . (SERVER !== null ? DRIVER . "=" . urlencode(SERVER) . '&' : '') . (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '') . (DB != "" ? 'db=' . urlencode(DB) . '&' . (isset($_GET["ns"]) ? "ns=" . urlencode($_GET["ns"]) . "&" : "") : '') ); include "../adminer/include/version.inc.php"; 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/editing.inc.php"; include "./include/connect.inc.php"; $on_actions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; ///< @var string used in foreign_keys() adminer-4.7.6/adminer/include/connect.inc.php000066400000000000000000000103721361500001000211100ustar00rootroot00000000000000\n"; foreach (array( 'database' => lang('Create database'), 'privileges' => lang('Privileges'), 'processlist' => lang('Process list'), 'variables' => lang('Variables'), 'status' => lang('Status'), ) as $key => $val) { if (support($key)) { echo "$val\n"; } } echo "

    " . lang('%s version: %s through PHP extension %s', $drivers[DRIVER], "" . h($connection->server_info) . "", "$connection->extension") . "\n"; echo "

    " . lang('Logged as: %s', "" . h(logged_user()) . "") . "\n"; $databases = $adminer->databases(); if ($databases) { $scheme = support("scheme"); $collations = collations(); echo "

    \n"; echo "\n"; echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});"); echo "" . (support("database") ? "\n" ; $databases = ($_GET["dbsize"] ? count_tables($databases) : array_flip($databases)); foreach ($databases as $db => $tables) { $root = h(ME) . "db=" . urlencode($db); $id = h("Db-" . $db); echo "" . (support("database") ? "
    " : "") . "" . lang('Database') . " - " . lang('Refresh') . "" . "" . lang('Collation') . "" . lang('Tables') . "" . lang('Size') . " - " . lang('Compute') . "" . script("qsl('a').onclick = partial(ajaxSetHtml, '" . js_escape(ME) . "script=connect');", "") . "
    " . checkbox("db[]", $db, in_array($db, (array) $_POST["db"]), "", "", "", $id) : ""); echo "" . h($db) . ""; $collation = h(db_collation($db, $collations)); echo "" . (support("database") ? "$collation" : $collation); echo "" . ($_GET["dbsize"] ? $tables : "?") . ""; echo "" . ($_GET["dbsize"] ? db_size($db) : "?"); echo "\n"; } echo "
    \n"; echo (support("database") ? "\n" : "" ); echo "\n"; echo "
    \n"; echo script("tableCheck();"); } } page_footer("db"); } if (isset($_GET["status"])) { $_GET["variables"] = $_GET["status"]; } if (isset($_GET["import"])) { $_GET["sql"] = $_GET["import"]; } 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 exit; } if (support("scheme") && DB != "" && $_GET["ns"] !== "") { if (!isset($_GET["ns"])) { redirect(preg_replace('~ns=[^&]*&~', '', ME) . "ns=" . get_schema()); } if (!set_schema($_GET["ns"])) { header("HTTP/1.1 404 Not Found"); page_header(lang('Schema') . ": " . h($_GET["ns"]), lang('Invalid schema.'), true); page_footer("ns"); exit; } } adminer-4.7.6/adminer/include/coverage.inc.php000066400000000000000000000013021361500001000212430ustar00rootroot00000000000000 $lines) { foreach ($lines as $l => $val) { if (!$coverage[$filename][$l] || $val > 0) { $coverage[$filename][$l] = $val; } } file_put_contents($coverage_filename, serialize($coverage)); } } xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); register_shutdown_function('save_coverage'); } adminer-4.7.6/adminer/include/design.inc.php000066400000000000000000000157741361500001000207430ustar00rootroot00000000000000 "link", "key2" => array("link", "desc")), null for nothing, false for driver only, true for driver and server * @param string used after colon in title and heading, should be HTML escaped * @return null */ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") { global $LANG, $VERSION, $adminer, $drivers, $jush; page_headers(); if (is_ajax() && $error) { page_messages($error); exit; } $title_all = $title . ($title2 != "" ? ": $title2" : ""); $title_page = strip_tags($title_all . (SERVER != "" && SERVER != "localhost" ? h(" - " . SERVER) : "") . " - " . $adminer->name()); ?> <?php echo $title_page; ?> head()) { ?> css() as $css) { ?> time()) { // 86400 - 1 day in seconds $version = unserialize(file_get_contents($filename)); $public = "-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwqWOVuF5uw7/+Z70djoK RlHIZFZPO0uYRezq90+7Amk+FDNd7KkL5eDve+vHRJBLAszF/7XKXe11xwliIsFs DFWQlsABVZB3oisKCBEuI71J4kPH8dKGEWR9jDHFw3cWmoH3PmqImX6FISWbG3B8 h7FIx3jEaw5ckVPVTeo5JRm/1DZzJxjyDenXvBQ/6o9DgZKeNDgxwKzH+sw9/YCO jHnq1cFpOIISzARlrHMa/43YfeNRAm/tsBXjSxembBPo7aQZLAWHmaj5+K19H10B nCpz9Y++cipkVEiKRGih4ZEvjoFysEOdRLj6WiD/uUNky4xGeA6LaJqh5XpkFkcQ fQIDAQAB -----END PUBLIC KEY----- "; if (openssl_verify($version["version"], base64_decode($version["signature"]), $public) == 1) { $_COOKIE["adminer_version"] = $version["version"]; // doesn't need to send to the browser } } ?> > mixin(document.body, {onkeydown: bodyKeydown, onclick: bodyClick}); document.body.className = document.body.className.replace(/ nojs/, ' js'); var offlineMessage = ''; var thousandsSeparator = '';
    ' . $drivers[DRIVER] . ' » '; $link = substr(preg_replace('~\b(db|ns)=[^&]*&~', '', ME), 0, -1); $server = $adminer->serverName(SERVER); $server = ($server != "" ? $server : lang('Server')); if ($breadcrumb === false) { echo "$server\n"; } else { echo "$server » "; if ($_GET["ns"] != "" || (DB != "" && is_array($breadcrumb))) { echo '' . h(DB) . ' » '; } if (is_array($breadcrumb)) { if ($_GET["ns"] != "") { echo '' . h($_GET["ns"]) . ' » '; } foreach ($breadcrumb as $key => $val) { $desc = (is_array($val) ? $val[1] : h($val)); if ($desc != "") { echo "$desc » "; } } } echo "$title\n"; } } echo "

    $title_all

    \n"; echo "\n"; restart_session(); page_messages($error); $databases = &get_session("dbs"); if (DB != "" && $databases && !in_array(DB, $databases, true)) { $databases = null; } stop_session(); define("PAGE_HEADER", 1); } /** Send HTTP headers * @return null */ function page_headers() { global $adminer; header("Content-Type: text/html; charset=utf-8"); header("Cache-Control: no-cache"); header("X-Frame-Options: deny"); // ClickJacking protection in IE8, Safari 4, Chrome 2, Firefox 3.6.9 header("X-XSS-Protection: 0"); // prevents introducing XSS in IE8 by removing safe parts of the page header("X-Content-Type-Options: nosniff"); header("Referrer-Policy: origin-when-cross-origin"); foreach ($adminer->csp() as $csp) { $header = array(); foreach ($csp as $key => $val) { $header[] = "$key $val"; } header("Content-Security-Policy: " . implode("; ", $header)); } $adminer->headers(); } /** Get Content Security Policy headers * @return array of arrays with directive name in key, allowed sources in value */ function csp() { return array( array( "script-src" => "'self' 'unsafe-inline' 'nonce-" . get_nonce() . "' 'strict-dynamic'", // 'self' is a fallback for browsers not supporting 'strict-dynamic', 'unsafe-inline' is a fallback for browsers not supporting 'nonce-' "connect-src" => "'self'", "frame-src" => "https://www.adminer.org", "object-src" => "'none'", "base-uri" => "'none'", "form-action" => "'self'", ), ); } /** Get a CSP nonce * @return string Base64 value */ function get_nonce() { static $nonce; if (!$nonce) { $nonce = base64_encode(rand_string()); } return $nonce; } /** Print flash and error messages * @param string * @return null */ function page_messages($error) { $uri = preg_replace('~^[^?]*~', '', $_SERVER["REQUEST_URI"]); $messages = $_SESSION["messages"][$uri]; if ($messages) { echo "
    " . implode("
    \n
    ", $messages) . "
    " . script("messagesPrint();"); unset($_SESSION["messages"][$uri]); } if ($error) { echo "
    $error
    \n"; } } /** Print HTML footer * @param string "auth", "db", "ns" * @return null */ function page_footer($missing = "") { global $adminer, $token; ?>

    _conn = $connection; } /** Select data from table * @param string * @param array result of $adminer->selectColumnsProcess()[0] * @param array result of $adminer->selectSearchProcess() * @param array result of $adminer->selectColumnsProcess()[1] * @param array result of $adminer->selectOrderProcess() * @param int result of $adminer->selectLimitProcess() * @param int index of page starting at zero * @param bool whether to print the query * @return Min_Result */ function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) { global $adminer, $jush; $is_group = (count($group) < count($select)); $query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page); if (!$query) { $query = "SELECT" . limit( ($_GET["page"] != "last" && $limit != "" && $group && $is_group && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . implode(", ", $select) . "\nFROM " . table($table), ($where ? "\nWHERE " . implode(" AND ", $where) : "") . ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : ""), ($limit != "" ? +$limit : null), ($page ? $limit * $page : 0), "\n" ); } $start = microtime(true); $return = $this->_conn->query($query); if ($print) { echo $adminer->selectQuery($query, $start, !$return); } return $return; } /** Delete data from table * @param string * @param string " WHERE ..." * @param int 0 or 1 * @return bool */ function delete($table, $queryWhere, $limit = 0) { $query = "FROM " . table($table); return queries("DELETE" . ($limit ? limit1($table, $query, $queryWhere) : " $query$queryWhere")); } /** Update data in table * @param string * @param array escaped columns in keys, quoted data in values * @param string " WHERE ..." * @param int 0 or 1 * @param string * @return bool */ function update($table, $set, $queryWhere, $limit = 0, $separator = "\n") { $values = array(); foreach ($set as $key => $val) { $values[] = "$key = $val"; } $query = table($table) . " SET$separator" . implode(",$separator", $values); return queries("UPDATE" . ($limit ? limit1($table, $query, $queryWhere, $separator) : " $query$queryWhere")); } /** Insert data into table * @param string * @param array escaped columns in keys, quoted data in values * @return bool */ function insert($table, $set) { return queries("INSERT INTO " . table($table) . ($set ? " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")" : " DEFAULT VALUES" )); } /** Insert or update data in table * @param string * @param array * @param array of arrays with escaped columns in keys and quoted data in values * @return bool */ /*abstract*/ function insertUpdate($table, $rows, $primary) { return false; } /** Begin transaction * @return bool */ function begin() { return queries("BEGIN"); } /** Commit transaction * @return bool */ function commit() { return queries("COMMIT"); } /** Rollback transaction * @return bool */ function rollback() { return queries("ROLLBACK"); } /** Return query with a timeout * @param string * @param int seconds * @return string or null if the driver doesn't support query timeouts */ function slowQuery($query, $timeout) { } /** Convert column to be searchable * @param string escaped column name * @param array array("op" => , "val" => ) * @param array * @return string */ function convertSearch($idf, $val, $field) { return $idf; } /** Convert value returned by database to actual value * @param string * @param array * @return string */ function value($val, $field) { return (method_exists($this->_conn, 'value') ? $this->_conn->value($val, $field) : (is_resource($val) ? stream_get_contents($val) : $val) ); } /** Quote binary string * @param string * @return string */ function quoteBinary($s) { return q($s); } /** Get warnings about the last command * @return string HTML */ function warnings() { return ''; } /** Get help link for table * @param string * @return string relative URL or null */ function tableHelp($name) { } } adminer-4.7.6/adminer/include/editing.inc.php000066400000000000000000000527121361500001000211060ustar00rootroot00000000000000 orgtable - create links from these columns $indexes = array(); // orgtable => array(column => colno) - primary keys $columns = array(); // orgtable => array(column => ) - not selected columns in primary key $blobs = array(); // colno => bool - display bytes for blobs $types = array(); // colno => type - display char in $return = array(); // table => orgtable - mapping to use in EXPLAIN odd(''); // reset odd for each result for ($i=0; (!$limit || $i < $limit) && ($row = $result->fetch_row()); $i++) { if (!$i) { echo "
    \n"; echo "\n"; echo ""; for ($j=0; $j < count($row); $j++) { $field = $result->fetch_field(); $name = $field->name; $orgtable = $field->orgtable; $orgname = $field->orgname; $return[$field->table] = $orgtable; if ($orgtables && $jush == "sql") { // MySQL EXPLAIN $links[$j] = ($name == "table" ? "table=" : ($name == "possible_keys" ? "indexes=" : null)); } elseif ($orgtable != "") { if (!isset($indexes[$orgtable])) { // find primary key in each table $indexes[$orgtable] = array(); foreach (indexes($orgtable, $connection2) as $index) { if ($index["type"] == "PRIMARY") { $indexes[$orgtable] = array_flip($index["columns"]); break; } } $columns[$orgtable] = $indexes[$orgtable]; } if (isset($columns[$orgtable][$orgname])) { unset($columns[$orgtable][$orgname]); $indexes[$orgtable][$orgname] = $j; $links[$j] = $orgtable; } } if ($field->charsetnr == 63) { // 63 - binary $blobs[$j] = true; } $types[$j] = $field->type; echo "name != $orgname ? " title='" . h(($orgtable != "" ? "$orgtable." : "") . $orgname) . "'" : "") . ">" . h($name) . ($orgtables ? doc_link(array( 'sql' => "explain-output.html#explain_" . strtolower($name), 'mariadb' => "explain/#the-columns-in-explain-select", )) : "") ; } echo "\n"; } echo ""; foreach ($row as $key => $val) { if ($val === null) { $val = "NULL"; } elseif ($blobs[$key] && !is_utf8($val)) { $val = "" . lang('%d byte(s)', strlen($val)) . ""; //! link to download } else { $val = h($val); if ($types[$key] == 254) { // 254 - char $val = "$val"; } } if (isset($links[$key]) && !$columns[$links[$key]]) { if ($orgtables && $jush == "sql") { // MySQL EXPLAIN $table = $row[array_search("table=", $links)]; $link = $links[$key] . urlencode($orgtables[$table] != "" ? $orgtables[$table] : $table); } else { $link = "edit=" . urlencode($links[$key]); foreach ($indexes[$links[$key]] as $col => $j) { $link .= "&where" . urlencode("[" . bracket_escape($col) . "]") . "=" . urlencode($row[$j]); } } $val = "$val"; } echo "
    $val"; } } echo ($i ? "
    \n
    " : "

    " . lang('No rows.')) . "\n"; return $return; } /** Get referencable tables with single column primary key except self * @param string * @return array ($table_name => $field) */ function referencable_primary($self) { $return = array(); // table_name => field foreach (table_status('', true) as $table_name => $table) { if ($table_name != $self && fk_support($table)) { foreach (fields($table_name) as $field) { if ($field["primary"]) { if ($return[$table_name]) { // multi column primary key unset($return[$table_name]); break; } $return[$table_name] = $field; } } } } return $return; } /** Get settings stored in a cookie * @return array */ function adminer_settings() { parse_str($_COOKIE["adminer_settings"], $settings); return $settings; } /** Get setting stored in a cookie * @param string * @return array */ function adminer_setting($key) { $settings = adminer_settings(); return $settings[$key]; } /** Store settings to a cookie * @param array * @return bool */ function set_adminer_settings($settings) { return cookie("adminer_settings", http_build_query($settings + adminer_settings())); } /** Print SQL "; } /** Print table columns for type edit * @param string * @param array * @param array * @param array returned by referencable_primary() * @param array extra types to prepend * @return null */ function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_types = array()) { global $structured_types, $types, $unsigned, $on_actions; $type = $field["type"]; ?> " size="3" aria-labelledby="label-length">

    "; echo "$legend"; echo script("qsl('a').onclick = partial(toggle, 'fieldset-$id');", ""); echo ""; echo "
    dumpFormat(); foreach ((array) $_GET["columns"] as $column) { if ($column["fun"]) { unset($format['sql']); break; } } if ($format) { print_fieldset("export", lang('Export') . " "); $output = $adminer->dumpOutput(); echo ($output ? html_select("output", $output, $adminer_import["output"]) . " " : ""); echo html_select("format", $format, $adminer_import["format"]); echo " \n"; echo "\n"; } $adminer->selectEmailPrint(array_filter($email_fields, 'strlen'), $columns); } echo "\n"; if ($adminer->selectImportPrint()) { echo "
    "; echo "" . lang('Import') . ""; echo script("qsl('a').onclick = partial(toggle, 'import');", ""); echo ""; echo "
    "; } echo "\n"; echo "\n"; echo (!$group && $select ? "" : script("tableCheck();")); } } } if (is_ajax()) { ob_end_clean(); exit; } adminer-4.7.6/adminer/sequence.inc.php000066400000000000000000000022031361500001000176360ustar00rootroot00000000000000

    " autocapitalize="off"> " . confirm(lang('Drop %s?', $SEQUENCE)) . "\n"; } ?>

    adminer-4.7.6/adminer/sql.inc.php000066400000000000000000000261131361500001000166330ustar00rootroot00000000000000dumpTable("", ""); $adminer->dumpData("", "table", $_POST["query"]); exit; } restart_session(); $history_all = &get_session("queries"); $history = &$history_all[DB]; if (!$error && $_POST["clear"]) { $history = array(); redirect(remove_from_uri("history")); } page_header((isset($_GET["import"]) ? lang('Import') : lang('SQL command')), $error); if (!$error && $_POST) { $fp = false; if (!isset($_GET["import"])) { $query = $_POST["query"]; } elseif ($_POST["webfile"]) { $sql_file_path = $adminer->importServerPath(); $fp = @fopen((file_exists($sql_file_path) ? $sql_file_path : "compress.zlib://$sql_file_path.gz" ), "rb"); $query = ($fp ? fread($fp, 1e6) : false); } else { $query = get_file("sql_file", true); } if (is_string($query)) { // get_file() returns error as number, fread() as false if (function_exists('memory_get_usage')) { @ini_set("memory_limit", max(ini_bytes("memory_limit"), 2 * strlen($query) + memory_get_usage() + 8e6)); // @ - may be disabled, 2 - substr and trim, 8e6 - other variables } if ($query != "" && strlen($query) < 1e6) { // don't add big queries $q = $query . (preg_match("~;[ \t\r\n]*\$~", $query) ? "" : ";"); //! doesn't work with DELIMITER | if (!$history || reset(end($history)) != $q) { // no repeated queries restart_session(); $history[] = array($q, time()); //! add elapsed time set_session("queries", $history_all); // required because reference is unlinked by stop_session() stop_session(); } } $space = "(?:\\s|/\\*[\s\S]*?\\*/|(?:#|-- )[^\n]*\n?|--\r?\n)"; $delimiter = ";"; $offset = 0; $empty = true; $connection2 = connect(); // connection for exploring indexes and EXPLAIN (to not replace FOUND_ROWS()) //! PDO - silent error if (is_object($connection2) && DB != "") { $connection2->select_db(DB); if ($_GET["ns"] != "") { set_schema($_GET["ns"], $connection2); } } $commands = 0; $errors = array(); $parse = '[\'"' . ($jush == "sql" ? '`#' : ($jush == "sqlite" ? '`[' : ($jush == "mssql" ? '[' : ''))) . ']|/\*|-- |$' . ($jush == "pgsql" ? '|\$[^$]*\$' : ''); $total_start = microtime(true); parse_str($_COOKIE["adminer_export"], $adminer_export); $dump_format = $adminer->dumpFormat(); unset($dump_format["sql"]); while ($query != "") { if (!$offset && preg_match("~^$space*+DELIMITER\\s+(\\S+)~i", $query, $match)) { $delimiter = $match[1]; $query = substr($query, strlen($match[0])); } else { preg_match('(' . preg_quote($delimiter) . "\\s*|$parse)", $query, $match, PREG_OFFSET_CAPTURE, $offset); // should always match list($found, $pos) = $match[0]; if (!$found && $fp && !feof($fp)) { $query .= fread($fp, 1e5); } else { if (!$found && rtrim($query) == "") { break; } $offset = $pos + strlen($found); if ($found && rtrim($found) != $delimiter) { // find matching quote or comment end while (preg_match('(' . ($found == '/*' ? '\*/' : ($found == '[' ? ']' : (preg_match('~^-- |^#~', $found) ? "\n" : preg_quote($found) . "|\\\\."))) . '|$)s', $query, $match, PREG_OFFSET_CAPTURE, $offset)) { //! respect sql_mode NO_BACKSLASH_ESCAPES $s = $match[0][0]; if (!$s && $fp && !feof($fp)) { $query .= fread($fp, 1e5); } else { $offset = $match[0][1] + strlen($s); if ($s[0] != "\\") { break; } } } } else { // end of a query $empty = false; $q = substr($query, 0, $pos); $commands++; $print = "
    " . $adminer->sqlCommandQuery($q) . "
    \n"; if ($jush == "sqlite" && preg_match("~^$space*+ATTACH\\b~i", $q, $match)) { // PHP doesn't support setting SQLITE_LIMIT_ATTACHED echo $print; echo "

    " . lang('ATTACH queries are not supported.') . "\n"; $errors[] = " $commands"; if ($_POST["error_stops"]) { break; } } else { if (!$_POST["only_errors"]) { echo $print; ob_flush(); flush(); // can take a long time - show the running query } $start = microtime(true); //! don't allow changing of character_set_results, convert encoding of displayed query if ($connection->multi_query($q) && is_object($connection2) && preg_match("~^$space*+USE\\b~i", $q)) { $connection2->query($q); } do { $result = $connection->store_result(); if ($connection->error) { echo ($_POST["only_errors"] ? $print : ""); echo "

    " . lang('Error in query') . ($connection->errno ? " ($connection->errno)" : "") . ": " . error() . "\n"; $errors[] = " $commands"; if ($_POST["error_stops"]) { break 2; } } else { $time = " (" . format_time($start) . ")" . (strlen($q) < 1000 ? " " . lang('Edit') . "" : "") // 1000 - maximum length of encoded URL in IE is 2083 characters ; $affected = $connection->affected_rows; // getting warnigns overwrites this $warnings = ($_POST["only_errors"] ? "" : $driver->warnings()); $warnings_id = "warnings-$commands"; if ($warnings) { $time .= ", " . lang('Warnings') . "" . script("qsl('a').onclick = partial(toggle, '$warnings_id');", ""); } $explain = null; $explain_id = "explain-$commands"; if (is_object($result)) { $limit = $_POST["limit"]; $orgtables = select($result, $connection2, array(), $limit); if (!$_POST["only_errors"]) { echo "

    \n"; $num_rows = $result->num_rows; echo "

    " . ($num_rows ? ($limit && $num_rows > $limit ? lang('%d / ', $limit) : "") . lang('%d row(s)', $num_rows) : ""); echo $time; if ($connection2 && preg_match("~^($space|\\()*+SELECT\\b~i", $q) && ($explain = explain($connection2, $q))) { echo ", Explain" . script("qsl('a').onclick = partial(toggle, '$explain_id');", ""); } $id = "export-$commands"; echo ", " . lang('Export') . "" . script("qsl('a').onclick = partial(toggle, '$id');", "") . "\n" . "

    \n" ; } } else { if (preg_match("~^$space*+(CREATE|DROP|ALTER)$space++(DATABASE|SCHEMA)\\b~i", $q)) { restart_session(); set_session("dbs", null); // clear cache stop_session(); } if (!$_POST["only_errors"]) { echo "

    " . lang('Query executed OK, %d row(s) affected.', $affected) . "$time\n"; } } echo ($warnings ? "

    \n" : ""); if ($explain) { echo "\n"; } } $start = microtime(true); } while ($connection->next_result()); } $query = substr($query, $offset); $offset = 0; } } } } if ($empty) { echo "

    " . lang('No commands to execute.') . "\n"; } elseif ($_POST["only_errors"]) { echo "

    " . lang('%d query(s) executed OK.', $commands - count($errors)); echo " (" . format_time($total_start) . ")\n"; } elseif ($errors && $commands > 1) { echo "

    " . lang('Error in query') . ": " . implode("", $errors) . "\n"; } //! MS SQL - SET SHOWPLAN_ALL OFF } else { echo "

    " . upload_error($query) . "\n"; } } ?>

    "; if (!isset($_GET["import"])) { $q = $_GET["sql"]; // overwrite $q from if ($_POST) to save memory if ($_POST) { $q = $_POST["query"]; } elseif ($_GET["history"] == "all") { $q = $history; } elseif ($_GET["history"] != "") { $q = $history[$_GET["history"]][0]; } echo "

    "; textarea("query", $q, 20); echo script(($_POST ? "" : "qs('textarea').focus();\n") . "qs('#form').onsubmit = partial(sqlSubmit, qs('#form'), '" . remove_from_uri("sql|limit|error_stops|only_errors") . "');"); echo "

    $execute\n"; echo lang('Limit rows') . ": \n"; } else { echo "

    " . lang('File upload') . "
    "; $gz = (extension_loaded("zlib") ? "[.gz]" : ""); echo (ini_bool("file_uploads") ? "SQL$gz (< " . ini_get("upload_max_filesize") . "B): \n$execute" // ignore post_max_size because it is for all form fields together and bytes computing would be necessary : lang('File uploads are disabled.') ); echo "
    \n"; $importServerPath = $adminer->importServerPath(); if ($importServerPath) { echo "
    " . lang('From server') . "
    "; echo lang('Webserver file %s', "" . h($importServerPath) . "$gz"); echo ' '; echo "
    \n"; } echo "

    "; } echo checkbox("error_stops", 1, ($_POST ? $_POST["error_stops"] : isset($_GET["import"])), lang('Stop on error')) . "\n"; echo checkbox("only_errors", 1, ($_POST ? $_POST["only_errors"] : isset($_GET["import"])), lang('Show only errors')) . "\n"; echo "\n"; if (!isset($_GET["import"]) && $history) { print_fieldset("history", lang('History'), $_GET["history"] != ""); for ($val = end($history); $val; $val = prev($history)) { // not array_reverse() to save memory $key = key($history); list($q, $time, $elapsed) = $val; echo '' . lang('Edit') . "" . " " . @date("H:i:s", $time) . "" // @ - time zone may be not set . " " . shorten_utf8(ltrim(str_replace("\n", " ", str_replace("\r", "", preg_replace('~^(#|-- ).*~m', '', $q)))), 80, "") . ($elapsed ? " ($elapsed)" : "") . "
    \n" ; } echo "\n"; echo "" . lang('Edit all') . "\n"; echo "\n"; } ?>

    adminer-4.7.6/adminer/sqlite.php000066400000000000000000000005701361500001000165640ustar00rootroot00000000000000 div { background: #fff; padding: 0 0 .5em; } .footer fieldset { margin-top: 0; } .links a { white-space: nowrap; margin-right: 20px; } .logout { margin-top: .5em; position: absolute; top: 0; right: 0; } .loadmore { margin-left: 1ex; } /* .edit used in designs */ #menu { position: absolute; margin: 10px 0 0; padding: 0 0 30px 0; top: 2em; left: 0; width: 19em; } #menu p, #logins, #tables { padding: .8em 1em; margin: 0; border-bottom: 1px solid #ccc; } #logins li, #tables li { list-style: none; } #dbs { overflow: hidden; } #logins, #tables { white-space: nowrap; overflow: auto; } #logins a, #tables a, #tables span { background: #fff; } #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; } #h1 { color: #777; text-decoration: none; font-style: italic; } #version { font-size: 67%; color: red; } #schema { margin-left: 60px; position: relative; -moz-user-select: none; -webkit-user-select: none; } #schema .table { border: 1px solid silver; padding: 0 2px; cursor: move; position: absolute; } #schema .references { position: absolute; } #help { position: absolute; border: 1px solid #999; background: #eee; padding: 5px; font-family: monospace; z-index: 1; } .rtl h2 { margin: 0 -18px 20px 0; } .rtl p, .rtl table, .rtl .error, .rtl .message { margin: 1em 0 0 20px; } .rtl .logout { left: 0; right: auto; } .rtl #content { margin: 2em 21em 0 0; padding: 10px 0 20px 20px; } .rtl #breadcrumb { left: auto; right: 21em; margin: 0 -18px 0 0; } .rtl .pages { left: auto; right: 21em; } .rtl input.wayoff { left: auto; right: -1000px; } .rtl #lang, .rtl #menu { left: auto; right: 0; } @media all and (max-device-width: 880px) { .pages { left: auto; } #menu { position: static; width: auto; } #content { margin-left: 10px; } #lang { position: static; border-top: 1px solid #999; } #breadcrumb { left: auto; } .rtl .pages { right: auto; } .rtl #content { margin-right: 10px; } .rtl #breadcrumb { right: auto; } } @media print { #lang, #menu { display: none; } #content { margin-left: 1em; } #breadcrumb { left: 1em; } .nowrap td, .nowrap th, td.nowrap { white-space: normal; } } adminer-4.7.6/adminer/static/down.gif000066400000000000000000000001171361500001000174740ustar00rootroot00000000000000GIF89a1îî™™!ů, „Ź©ËíMńĚ*)ľ[Wţ\˘ÇL&Ůśƶ•Çň;adminer-4.7.6/adminer/static/editing.js000066400000000000000000000504561361500001000200320ustar00rootroot00000000000000// Adminer specific functions /** Load syntax highlighting * @param string first three characters of database system version * @param [boolean] */ function bodyLoad(version, maria) { if (window.jush) { jush.create_links = ' target="_blank" rel="noreferrer noopener"'; if (version) { for (var key in jush.urls) { var obj = jush.urls; if (typeof obj[key] != 'string') { obj = obj[key]; key = 0; if (maria) { for (var i = 1; i < obj.length; i++) { obj[i] = obj[i] .replace(/\.html/, '/') .replace(/(numeric)(-type-overview)/, '$1-data$2') .replace(/#statvar_.*/, '#$$1') ; } } } obj[key] = obj[key] .replace(/dev\.mysql\.com\/doc\/mysql\/en\//, (maria ? 'mariadb.com/kb/en/library/' : '$&')) // MariaDB .replace(/\/doc\/mysql/, '/doc/refman/' + version) // MySQL .replace(/\/docs\/current/, '/docs/' + version) // PostgreSQL ; } } if (window.jushLinks) { jush.custom_links = jushLinks; } jush.highlight_tag('code', 0); var tags = qsa('textarea'); for (var i = 0; i < tags.length; i++) { if (/(^|\s)jush-/.test(tags[i].className)) { var pre = jush.textarea(tags[i]); if (pre) { setupSubmitHighlightInput(pre); } } } } } /** Get value of dynamically created form field * @param HTMLFormElement * @param string * @return HTMLElement */ function formField(form, name) { // required in IE < 8, form.elements[name] doesn't work for (var i=0; i < form.length; i++) { if (form[i].name == name) { return form[i]; } } } /** Try to change input type to password or to text * @param HTMLInputElement * @param boolean */ function typePassword(el, disable) { try { el.type = (disable ? 'text' : 'password'); } catch (e) { } } /** Install toggle handler * @param [HTMLElement] */ function messagesPrint(el) { var els = qsa('.toggle', el); for (var i = 0; i < els.length; i++) { els[i].onclick = partial(toggle, els[i].getAttribute('href').substr(1)); } } /** Hide or show some login rows for selected driver * @param HTMLSelectElement */ function loginDriver(driver) { var trs = parentTag(driver, 'table').rows; var disabled = /sqlite/.test(selectValue(driver)); alterClass(trs[1], 'hidden', disabled); // 1 - row with server trs[1].getElementsByTagName('input')[0].disabled = disabled; } var dbCtrl; var dbPrevious = {}; /** Check if database should be opened to a new window * @param MouseEvent * @this HTMLSelectElement */ function dbMouseDown(event) { dbCtrl = isCtrl(event); if (dbPrevious[this.name] == undefined) { dbPrevious[this.name] = this.value; } } /** Load database after selecting it * @this HTMLSelectElement */ function dbChange() { if (dbCtrl) { this.form.target = '_blank'; } this.form.submit(); this.form.target = ''; if (dbCtrl && dbPrevious[this.name] != undefined) { this.value = dbPrevious[this.name]; dbPrevious[this.name] = undefined; } } /** Check whether the query will be executed with index * @this HTMLElement */ function selectFieldChange() { var form = this.form; var ok = (function () { var inputs = qsa('input', form); 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 = qsa('select', form); 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 * @param string * @param string * @param string * @return boolean */ function delimiterEqual(val, a, b) { return (val == a + '_' + b || val == a + b || val == a + b.charAt(0).toUpperCase() + b.substr(1)); } /** Escape string to use as identifier * @param string * @return string */ function idfEscape(s) { return s.replace(/`/, '``'); } /** Set up event handlers for edit_fields(). */ function editFields() { var els = qsa('[name$="[field]"]'); for (var i = 0; i < els.length; i++) { els[i].oninput = function () { editingNameChange.call(this); if (!this.defaultValue) { editingAddRow.call(this); } } } els = qsa('[name$="[length]"]'); for (var i = 0; i < els.length; i++) { mixin(els[i], {onfocus: editingLengthFocus, oninput: editingLengthChange}); } els = qsa('[name$="[type]"]'); for (var i = 0; i < els.length; i++) { mixin(els[i], { onfocus: function () { lastType = selectValue(this); }, onchange: editingTypeChange, onmouseover: function (event) { helpMouseover.call(this, event, getTarget(event).value, 1) }, onmouseout: helpMouseout }); } } /** Handle clicks on fields editing * @param MouseEvent * @return boolean false to cancel action */ function editingClick(event) { var el = getTarget(event); if (!isTag(el, 'input')) { el = parentTag(el, 'label'); el = el && qs('input', el); } if (el) { var name = el.name; if (/^add\[/.test(name)) { editingAddRow.call(el, 1); } else if (/^up\[/.test(name)) { editingMoveRow.call(el, 1); } else if (/^down\[/.test(name)) { editingMoveRow.call(el); } else if (/^drop_col\[/.test(name)) { editingRemoveRow.call(el, 'fields\$1[field]'); } else { if (name == 'auto_increment_col') { var field = el.form['fields[' + el.value + '][field]']; if (!field.value) { field.value = 'id'; field.oninput(); } } return; } return false; } } /** Handle input on fields editing * @param InputEvent */ function editingInput(event) { var el = getTarget(event); if (/\[default\]$/.test(el.name)) { el.previousSibling.checked = true; } } /** Detect foreign key * @this HTMLInputElement */ function editingNameChange() { var name = this.name.substr(0, this.name.length - 7); var type = formField(this.form, name + '[type]'); var opts = type.options; var candidate; // don't select anything with ambiguous match (like column `id`) var val = this.value; for (var i = opts.length; i--; ) { var match = /(.+)`(.+)/.exec(opts[i].value); if (!match) { // common type if (candidate && i == opts.length - 2 && val == opts[candidate].value.replace(/.+`/, '') && name == 'fields[1]') { // single target table, link to column, first field - probably `id` return; } break; } var table = match[1]; var column = match[2]; var tables = [ table, table.replace(/s$/, ''), table.replace(/es$/, '') ]; for (var j=0; j < tables.length; j++) { table = tables[j]; if (val == column || val == table || delimiterEqual(val, table, column) || delimiterEqual(val, column, table)) { if (candidate) { return; } candidate = i; break; } } } if (candidate) { type.selectedIndex = candidate; type.onchange(); } } /** Add table row for next field * @param [boolean] * @return boolean false * @this HTMLInputElement */ function editingAddRow(focus) { var match = /(\d+)(\.\d+)?/.exec(this.name); var x = match[0] + (match[2] ? added.substr(match[2].length) : added) + '1'; var row = parentTag(this, 'tr'); var row2 = cloneNode(row); var tags = qsa('select', row); var tags2 = qsa('select', row2); for (var i=0; i < tags.length; i++) { tags2[i].name = tags[i].name.replace(/[0-9.]+/, x); tags2[i].selectedIndex = tags[i].selectedIndex; } tags = qsa('input', row); tags2 = qsa('input', row2); var input = tags2[0]; // IE loose tags2 after insertBefore() for (var i=0; i < tags.length; i++) { if (tags[i].name == 'auto_increment_col') { tags2[i].value = x; tags2[i].checked = false; } tags2[i].name = tags[i].name.replace(/([0-9.]+)/, x); if (/\[(orig|field|comment|default)/.test(tags[i].name)) { tags2[i].value = ''; } if (/\[(has_default)/.test(tags[i].name)) { tags2[i].checked = false; } } tags[0].oninput = editingNameChange; row.parentNode.insertBefore(row2, row.nextSibling); if (focus) { input.oninput = editingNameChange; input.focus(); } added += '0'; rowCount++; return false; } /** Remove table row for field * @param string regular expression replacement * @return boolean false * @this HTMLInputElement */ function editingRemoveRow(name) { var field = formField(this.form, this.name.replace(/[^\[]+(.+)/, name)); field.parentNode.removeChild(field); parentTag(this, 'tr').style.display = 'none'; return false; } /** Move table row for field * @param [boolean] * @return boolean false for success * @this HTMLInputElement */ function editingMoveRow(up){ var row = parentTag(this, 'tr'); if (!('nextElementSibling' in row)) { return true; } row.parentNode.insertBefore(row, up ? row.previousElementSibling : row.nextElementSibling ? row.nextElementSibling.nextElementSibling : row.parentNode.firstChild); return false; } var lastType = ''; /** Clear length and hide collation or unsigned * @this HTMLSelectElement */ function editingTypeChange() { var type = this; var name = type.name.substr(0, type.name.length - 6); var text = selectValue(type); for (var i=0; i < type.form.elements.length; i++) { var el = type.form.elements[i]; if (el.name == name + '[length]') { if (!( (/(char|binary)$/.test(lastType) && /(char|binary)$/.test(text)) || (/(enum|set)$/.test(lastType) && /(enum|set)$/.test(text)) )) { el.value = ''; } el.oninput.apply(el); } if (lastType == 'timestamp' && el.name == name + '[has_default]' && /timestamp/i.test(formField(type.form, name + '[default]').value)) { el.checked = false; } if (el.name == name + '[collation]') { alterClass(el, 'hidden', !/(char|text|enum|set)$/.test(text)); } if (el.name == name + '[unsigned]') { alterClass(el, 'hidden', !/(^|[^o])int(?!er)|numeric|real|float|double|decimal|money/.test(text)); } if (el.name == name + '[on_update]') { alterClass(el, 'hidden', !/timestamp|datetime/.test(text)); // MySQL supports datetime since 5.6.5 } if (el.name == name + '[on_delete]') { alterClass(el, 'hidden', !/`/.test(text)); } } helpClose(); } /** Mark length as required * @this HTMLInputElement */ function editingLengthChange() { alterClass(this, 'required', !this.value.length && /var(char|binary)$/.test(selectValue(this.parentNode.previousSibling.firstChild))); } /** Edit enum or set * @this HTMLInputElement */ function editingLengthFocus() { var td = this.parentNode; if (/(enum|set)$/.test(selectValue(td.previousSibling.firstChild))) { var edit = qs('#enum-edit'); edit.value = enumValues(this.value); td.appendChild(edit); this.style.display = 'none'; edit.style.display = 'inline'; edit.focus(); } } /** Get enum values * @param string * @return string values separated by newlines */ function enumValues(s) { var re = /(^|,)\s*'(([^\\']|\\.|'')*)'\s*/g; var result = []; var offset = 0; var match; while (match = re.exec(s)) { if (offset != match.index) { break; } result.push(match[2].replace(/'(')|\\(.)/g, '$1$2')); offset += match[0].length; } return (offset == s.length ? result.join('\n') : s); } /** Finish editing of enum or set * @this HTMLTextAreaElement */ function editingLengthBlur() { var field = this.parentNode.firstChild; var val = this.value; field.value = (/^'[^\n]+'$/.test(val) ? val : val && "'" + val.replace(/\n+$/, '').replace(/'/g, "''").replace(/\\/g, '\\\\').replace(/\n/g, "','") + "'"); field.style.display = 'inline'; this.style.display = 'none'; } /** Show or hide selected table column * @param boolean * @param number */ function columnShow(checked, column) { var trs = qsa('tr', qs('#edit-fields')); for (var i=0; i < trs.length; i++) { alterClass(qsa('td', trs[i])[column], 'hidden', !checked); } } /** Display partition options * @this HTMLSelectElement */ function partitionByChange() { var partitionTable = /RANGE|LIST/.test(selectValue(this)); alterClass(this.form['partitions'], 'hidden', partitionTable || !this.selectedIndex); alterClass(qs('#partition-table'), 'hidden', !partitionTable); helpClose(); } /** Add next partition row * @this HTMLInputElement */ function partitionNameChange() { var row = cloneNode(parentTag(this, 'tr')); row.firstChild.firstChild.value = ''; parentTag(this, 'table').appendChild(row); this.oninput = function () {}; } /** Show or hide comment fields * @param HTMLInputElement * @param [boolean] whether to focus Comment if checked */ function editingCommentsClick(el, focus) { var comment = el.form['Comment']; columnShow(el.checked, 6); alterClass(comment, 'hidden', !el.checked); if (focus && el.checked) { comment.focus(); } } /** Uncheck 'all' checkbox * @param MouseEvent * @this HTMLTableElement */ function dumpClick(event) { var el = parentTag(getTarget(event), 'label'); if (el) { el = qs('input', el); var match = /(.+)\[\]$/.exec(el.name); if (match) { checkboxClick.call(el, event); formUncheck('check-' + match[1]); } } } /** Add row for foreign key * @this HTMLSelectElement */ function foreignAddRow() { var row = cloneNode(parentTag(this, 'tr')); this.onchange = function () { }; var selects = qsa('select', row); for (var i=0; i < selects.length; i++) { selects[i].name = selects[i].name.replace(/\]/, '1$&'); selects[i].selectedIndex = 0; } parentTag(this, 'table').appendChild(row); } /** Add row for indexes * @this HTMLSelectElement */ function indexesAddRow() { var row = cloneNode(parentTag(this, 'tr')); this.onchange = function () { }; var selects = qsa('select', row); for (var i=0; i < selects.length; i++) { selects[i].name = selects[i].name.replace(/indexes\[\d+/, '$&1'); selects[i].selectedIndex = 0; } var inputs = qsa('input', row); for (var i=0; i < inputs.length; i++) { inputs[i].name = inputs[i].name.replace(/indexes\[\d+/, '$&1'); inputs[i].value = ''; } parentTag(this, 'table').appendChild(row); } /** Change column in index * @param string name prefix * @this HTMLSelectElement */ function indexesChangeColumn(prefix) { var names = []; for (var tag in { 'select': 1, 'input': 1 }) { var columns = qsa(tag, parentTag(this, 'td')); for (var i=0; i < columns.length; i++) { if (/\[columns\]/.test(columns[i].name)) { var value = selectValue(columns[i]); if (value) { names.push(value); } } } } this.form[this.name.replace(/\].*/, '][name]')].value = prefix + names.join('_'); } /** Add column for index * @param string name prefix * @this HTMLSelectElement */ function indexesAddColumn(prefix) { var field = this; var select = field.form[field.name.replace(/\].*/, '][type]')]; if (!select.selectedIndex) { while (selectValue(select) != "INDEX" && select.selectedIndex < select.options.length) { select.selectedIndex++; } select.onchange(); } var column = cloneNode(field.parentNode); var selects = qsa('select', column); for (var i = 0; i < selects.length; i++) { select = selects[i]; select.name = select.name.replace(/\]\[\d+/, '$&1'); select.selectedIndex = 0; } field.onchange = partial(indexesChangeColumn, prefix); var inputs = qsa('input', column); for (var i = 0; i < inputs.length; i++) { var input = inputs[i]; input.name = input.name.replace(/\]\[\d+/, '$&1'); if (input.type != 'checkbox') { input.value = ''; } } parentTag(field, 'td').appendChild(column); field.onchange(); } /** Updates the form action * @param HTMLFormElement * @param string */ function sqlSubmit(form, root) { if (encodeURIComponent(form['query'].value).length < 2e3) { form.action = root + '&sql=' + encodeURIComponent(form['query'].value) + (form['limit'].value ? '&limit=' + +form['limit'].value : '') + (form['error_stops'].checked ? '&error_stops=1' : '') + (form['only_errors'].checked ? '&only_errors=1' : '') ; } } /** Handle changing trigger time or event * @param RegExp * @param string * @param HTMLFormElement */ function triggerChange(tableRe, table, form) { var formEvent = selectValue(form['Event']); if (tableRe.test(form['Trigger'].value)) { form['Trigger'].value = table + '_' + (selectValue(form['Timing']).charAt(0) + formEvent.charAt(0)).toLowerCase(); } alterClass(form['Of'], 'hidden', formEvent != 'UPDATE OF'); } var that, x, y; // em and tablePos defined in schema.inc.php /** Get mouse position * @param MouseEvent * @this HTMLElement */ function schemaMousedown(event) { if ((event.which ? event.which : event.button) == 1) { that = this; x = event.clientX - this.offsetLeft; y = event.clientY - this.offsetTop; } } /** Move object * @param MouseEvent */ function schemaMousemove(event) { if (that !== undefined) { var left = (event.clientX - x) / em; var top = (event.clientY - y) / em; var divs = qsa('div', that); var lineSet = { }; for (var i=0; i < divs.length; i++) { if (divs[i].className == 'references') { var div2 = qs('[id="' + (/^refs/.test(divs[i].id) ? 'refd' : 'refs') + divs[i].id.substr(4) + '"]'); var ref = (tablePos[divs[i].title] ? tablePos[divs[i].title] : [ div2.parentNode.offsetTop / em, 0 ]); var left1 = -1; var id = divs[i].id.replace(/^ref.(.+)-.+/, '$1'); if (divs[i].parentNode != div2.parentNode) { left1 = Math.min(0, ref[1] - left) - 1; divs[i].style.left = left1 + 'em'; divs[i].querySelector('div').style.width = -left1 + 'em'; var left2 = Math.min(0, left - ref[1]) - 1; div2.style.left = left2 + 'em'; div2.querySelector('div').style.width = -left2 + 'em'; } if (!lineSet[id]) { var line = qs('[id="' + divs[i].id.replace(/^....(.+)-.+$/, 'refl$1') + '"]'); var top1 = top + divs[i].offsetTop / em; var top2 = top + div2.offsetTop / em; if (divs[i].parentNode != div2.parentNode) { top2 += ref[0] - top; line.querySelector('div').style.height = Math.abs(top1 - top2) + 'em'; } line.style.left = (left + left1) + 'em'; line.style.top = Math.min(top1, top2) + 'em'; lineSet[id] = true; } } } that.style.left = left + 'em'; that.style.top = top + 'em'; } } /** Finish move * @param MouseEvent * @param string */ function schemaMouseup(event, db) { if (that !== undefined) { tablePos[that.firstChild.firstChild.firstChild.data] = [ (event.clientY - y) / em, (event.clientX - x) / em ]; that = undefined; var s = ''; for (var key in tablePos) { s += '_' + key + ':' + Math.round(tablePos[key][0] * 10000) / 10000 + 'x' + Math.round(tablePos[key][1] * 10000) / 10000; } s = encodeURIComponent(s.substr(1)); var link = qs('#schema-link'); link.href = link.href.replace(/[^=]+$/, '') + s; cookie('adminer_schema-' + db + '=' + s, 30); //! special chars in db } } var helpOpen, helpIgnore; // when mouse outs