diff --git a/.gitmodules b/.gitmodules index 9b4770cb..5c653ef1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "jush"] path = externals/jush - url = git://jush.git.sourceforge.net/gitroot/jush/jush + url = git://git.code.sf.net/p/jush/git [submodule "tinymce"] path = externals/tinymce url = git://github.com/tinymce/tinymce.git diff --git a/adminer/create.inc.php b/adminer/create.inc.php index 0c85ac44..d59451fa 100644 --- a/adminer/create.inc.php +++ b/adminer/create.inc.php @@ -94,7 +94,7 @@ if ($_POST && !process_fields($row["fields"]) && !$error) { } $name = trim($row["name"]); - queries_redirect(ME . "table=" . urlencode($name), $message, alter_table( + queries_redirect(ME . (support("table") ? "table=" : "select=") . urlencode($name), $message, alter_table( $TABLE, $name, ($jush == "sqlite" && ($use_all_fields || $foreign) ? $all_fields : $fields), @@ -154,11 +154,15 @@ foreach ($engines as $engine) {

+ : " autocapitalize="off"> "(" . lang('engine') . ")") + $engines, $row["Engine"]) : ""); ?> "(" . lang('collation') . ")") + $collations, $row["Collation"]) : ""); ?> + + +

+ + formnovalidate> homepage()) { foreach ($tables_list as $name => $type) { $view = ($type !== null && !eregi("table", $type)); echo '

' . checkbox(($view ? "views[]" : "tables[]"), $name, in_array($name, $tables_views, true), "", "formUncheck('check-all');"); - echo '' . h($name) . ''; + echo '' . (support("table") ? '' . h($name) . '' : h($name)); if ($view) { echo '' . lang('View') . ''; echo '?'; @@ -89,7 +89,11 @@ if ($adminer->homepage()) { "Auto_increment" => array("auto_increment=1&create", lang('Alter table')), "Rows" => array("select", lang('Select data')), ) as $key => $link) { - echo ($link ? "?" : " "); + $id = " id='$key-" . h($name) . "'"; + echo ($link ? "" . (support("table") || $key == "Rows" + ? "?" + : "?" + ) : " "); } } echo (support("comment") ? " " : ""); @@ -105,10 +109,11 @@ if ($adminer->homepage()) { echo "
\n"; echo "\n"; if (!information_schema(DB)) { - echo "

" . (ereg('^(sql|sqlite|pgsql)$', $jush) - ? ($jush != "sqlite" ? " " : "") - . " " : "" - ) . ($jush == "sql" ? " " : "") . " \n"; + echo "

" + . (ereg('^(sql|sqlite|pgsql)$', $jush) ? ($jush != "sqlite" ? " " : "") . " " : "") + . ($jush == "sql" ? " " : "") + . (support("table") ? " " : "") + . "\n"; $databases = (support("scheme") ? schemas() : $adminer->databases()); if (count($databases) != 1 && $jush != "sqlite") { $db = (isset($_POST["target"]) ? $_POST["target"] : (support("scheme") ? $_GET["ns"] : DB)); diff --git a/adminer/drivers/mssql.inc.php b/adminer/drivers/mssql.inc.php index 85545b69..6c518997 100644 --- a/adminer/drivers/mssql.inc.php +++ b/adminer/drivers/mssql.inc.php @@ -602,7 +602,7 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table) } function support($feature) { - return ereg('^(scheme|trigger|view|drop_col)$', $feature); //! routine| + return ereg('^(database|table|scheme|trigger|view|drop_col)$', $feature); //! routine| } $jush = "mssql"; diff --git a/adminer/drivers/mysql.inc.php b/adminer/drivers/mysql.inc.php index 21117f7b..d2c936c0 100644 --- a/adminer/drivers/mysql.inc.php +++ b/adminer/drivers/mysql.inc.php @@ -982,7 +982,7 @@ if (!defined("DRIVER")) { } /** Check whether a feature is supported - * @param string "comment", "copy", "drop_col", "dump", "event", "kill", "partitioning", "privileges", "procedure", "processlist", "routine", "scheme", "sequence", "status", "trigger", "type", "variables", "view" + * @param string "comment", "copy", "database", "drop_col", "dump", "event", "kill", "partitioning", "privileges", "procedure", "processlist", "routine", "scheme", "sequence", "status", "table", "trigger", "type", "variables", "view" * @return bool */ function support($feature) { diff --git a/adminer/drivers/oracle.inc.php b/adminer/drivers/oracle.inc.php index c5a30f1e..8991d817 100644 --- a/adminer/drivers/oracle.inc.php +++ b/adminer/drivers/oracle.inc.php @@ -376,7 +376,7 @@ ORDER BY PROCESS } function support($feature) { - return ereg("view|scheme|processlist|drop_col|variables|status", $feature); //! + return ereg("database|table|view|scheme|processlist|drop_col|variables|status", $feature); //! } $jush = "oracle"; diff --git a/adminer/drivers/pgsql.inc.php b/adminer/drivers/pgsql.inc.php index 41341eac..ea863de1 100644 --- a/adminer/drivers/pgsql.inc.php +++ b/adminer/drivers/pgsql.inc.php @@ -612,7 +612,7 @@ AND typelem = 0" } function support($feature) { - return ereg('^(comment|view|scheme|processlist|sequence|trigger|type|variables|drop_col)$', $feature); //! routine| + return ereg('^(database|table|comment|view|scheme|processlist|sequence|trigger|type|variables|drop_col)$', $feature); //! routine| } $jush = "pgsql"; diff --git a/adminer/drivers/simpledb.inc.php b/adminer/drivers/simpledb.inc.php new file mode 100644 index 00000000..b3dc34a5 --- /dev/null +++ b/adminer/drivers/simpledb.inc.php @@ -0,0 +1,428 @@ + $query, 'ConsistentRead' => 'true'); + if ($this->next) { + $params['NextToken'] = $this->next; + } + $result = sdb_request_all('Select', 'Item', $params, $this->timeout); //! respect $unbuffered + if ($result === false) { + return $result; + } + if (preg_match('~^\s*SELECT\s+COUNT\(~i', $query)) { + $sum = 0; + foreach ($result as $item) { + $sum += $item->Attribute->Value; + } + $result = array((object) array('Attribute' => array((object) array( + 'Name' => 'Count', + 'Value' => $sum, + )))); + } + return new Min_Result($result); + } + + function multi_query($query) { + return $this->_result = $this->query($query); + } + + function store_result() { + return $this->_result; + } + + function next_result() { + return false; + } + + function quote($string) { + return "'" . str_replace("'", "''", $string) . "'"; + } + + } + + class Min_Result { + var $num_rows, $_rows = array(), $_offset = 0; + + function Min_Result($result) { + foreach ($result as $item) { + $row = array(); + if ($item->Name != '') { // SELECT COUNT(*) + $row['itemName()'] = (string) $item->Name; + } + foreach ($item->Attribute as $attribute) { + $name = $this->_processValue($attribute->Name); + $row[$name] .= ($row[$name] != '' ? ',' : '') . $this->_processValue($attribute->Value); + } + $this->_rows[] = $row; + foreach ($row as $key => $val) { + if (!isset($this->_rows[0][$key])) { + $this->_rows[0][$key] = null; + } + } + } + $this->num_rows = count($this->_rows); + } + + function _processValue($element) { + return (is_object($element) && $element['encoding'] == 'base64' ? base64_decode($element) : (string) $element); + } + + function fetch_assoc() { + $row = current($this->_rows); + if (!$row) { + return $row; + } + $return = array(); + foreach ($this->_rows[0] as $key => $val) { + $return[$key] = $row[$key]; + } + next($this->_rows); + return $return; + } + + function fetch_row() { + $return = $this->fetch_assoc(); + if (!$return) { + return $return; + } + return array_values($return); + } + + function fetch_field() { + $keys = array_keys($this->_rows[0]); + return (object) array('name' => $keys[$this->_offset++]); + } + + } + } + + + + class Min_Driver { + + function _chunkRequest($ids, $action, $params, $expand = array()) { + foreach (array_chunk($ids, 25) as $chunk) { + $params2 = $params; + foreach ($chunk as $i => $id) { + $params2["Item.$i.ItemName"] = $id; + foreach ($expand as $key => $val) { + $params2["Item.$i.$key"] = $val; + } + } + if (!sdb_request($action, $params2)) { + return false; + } + } + return true; + } + + function _extractIds($queryWhere, $limit) { + $return = array(); + if (preg_match_all("~itemName\(\) = ('[^']*+')+~", $queryWhere, $matches)) { + $return = array_map('idf_unescape', $matches[1]); + } else { + foreach (sdb_request_all('Select', 'Item', array('SelectExpression' => 'SELECT itemName() FROM ' . table($table) . $queryWhere . ($limit ? " LIMIT 1" : ""))) as $item) { + $return[] = $item->Name; + } + } + return $return; + } + + function delete($table, $queryWhere, $limit = 0) { + return $this->_chunkRequest( + $this->_extractIds($queryWhere, $limit), + 'BatchDeleteAttributes', + array('DomainName' => $table) + ); + } + + function update($table, $set, $queryWhere, $limit = 0, $separator = "\n") { + $delete = array(); + $insert = array(); + $i = 0; + foreach ($set as $key => $val) { + $key = idf_unescape($key); + if ($val == "NULL") { + $delete["Attribute." . count($delete) . ".Name"] = $key; + } elseif ($key != "itemName()") { + $insert["Attribute.$i.Name"] = $key; + $insert["Attribute.$i.Value"] = idf_unescape($val); + $insert["Attribute.$i.Replace"] = "true"; + $i++; + } + } + $ids = $this->_extractIds($queryWhere, $limit); + $params = array('DomainName' => $table); + return (!$insert || $this->_chunkRequest($ids, 'BatchPutAttributes', $params, $insert)) + && (!$delete || $this->_chunkRequest($ids, 'BatchDeleteAttributes', $params, $delete)) + ; + } + + function insert($table, $set) { + $params = array("DomainName" => $table); + $i = 0; + foreach ($set as $name => $value) { + if ($value != "NULL") { + $name = idf_unescape($name); + $value = idf_unescape($value); + if ($name == "itemName()") { + $params["ItemName"] = $value; + } else { + $params["Attribute.$i.Name"] = $name; + $params["Attribute.$i.Value"] = $value; + $i++; + } + } + } + return sdb_request('PutAttributes', $params); + } + + } + + + + function connect() { + return new Min_DB; + } + + function support($feature) { + return false; + } + + function logged_user() { + global $adminer; + $credentials = $adminer->credentials(); + return $credentials[1]; + } + + function get_databases() { + return array("domain"); + } + + function collations() { + return array(); + } + + function db_collation($db, $collations) { + } + + function tables_list() { + global $connection; + $return = array(); + foreach (sdb_request_all('ListDomains', 'DomainName') as $table) { + $return[(string) $table] = 'table'; + } + if ($connection->error && defined("PAGE_HEADER")) { + 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 array(); + } + + 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) { + return false; + } + + 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" . ereg_replace('^https?://', '', $host) . "\n/\n$query", $secret, true))); + @ini_set('track_errors', 1); // @ - may be disabled + $file = @file_get_contents((ereg('^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 || !($xml = simplexml_load_string($file))) { + $connection->error = $php_errormsg; + 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(); +} diff --git a/adminer/drivers/sqlite.inc.php b/adminer/drivers/sqlite.inc.php index 888fa9e0..8a0604f7 100644 --- a/adminer/drivers/sqlite.inc.php +++ b/adminer/drivers/sqlite.inc.php @@ -676,7 +676,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) { } function support($feature) { - return ereg('^(view|trigger|variables|status|dump|move_col|drop_col)$', $feature); + return ereg('^(database|table|view|trigger|variables|status|dump|move_col|drop_col)$', $feature); } $jush = "sqlite"; diff --git a/adminer/edit.inc.php b/adminer/edit.inc.php index 245a7e98..4dd9ea82 100644 --- a/adminer/edit.inc.php +++ b/adminer/edit.inc.php @@ -21,6 +21,21 @@ if ($_POST && !$error && !isset($_GET["select"])) { $unique_array = unique_array($_GET["where"], $indexes); $query_where = "\nWHERE $where"; + if (!support("table")) { + foreach ($_POST["field_keys"] as $key => $val) { + if ($val != "") { + $_POST["fields"][bracket_escape($val)] = $_POST["field_vals"][$key]; + } + } + foreach ($_POST["fields"] as $key => $val) { + $name = bracket_escape($key, 1); // 1 - back + $fields[$name] = array("field" => $name); + if (isset($_POST["function"][$key])) { + $fields[$name]["null"] = true; + } + } + } + if (isset($_POST["delete"])) { queries_redirect( $location, @@ -33,7 +48,7 @@ if ($_POST && !$error && !isset($_GET["select"])) { foreach ($fields as $name => $field) { $val = process_input($field); if ($val !== false && $val !== null) { - $set[idf_escape($name)] = ($update ? "\n" . idf_escape($name) . " = $val" : $val); + $set[idf_escape($name)] = $val; } } @@ -85,12 +100,32 @@ if ($_POST["save"]) { } } $row = array(); + if (!support("table")) { + $select = array("*"); + } if ($select) { $rows = get_rows("SELECT" . limit(implode(", ", $select) . " FROM " . table($TABLE), " WHERE $where", (isset($_GET["select"]) ? 2 : 1))); $row = (isset($_GET["select"]) && count($rows) != 1 ? null : reset($rows)); } } +if (!support("table") && !$fields) { + if (!$where) { // insert + $row = reset(get_rows("SELECT * FROM " . table($TABLE) . " LIMIT 1")); + if (!$row) { + $row = array("itemName()" => ""); + } + } + if ($row) { + foreach ($row as $key => $val) { + if (!$_POST["save"] && !$where) { + $row[$key] = null; + } + $fields[$key] = array("field" => $key, "null" => ($key != "itemName()")); + } + } +} + if ($row === false) { echo "

" . lang('No rows.') . "\n"; } @@ -130,6 +165,10 @@ if (!$fields) { echo "\n"; } + if (!support("table")) { + echo " "; + } + echo "\n"; } ?> diff --git a/adminer/include/adminer.inc.php b/adminer/include/adminer.inc.php index dbcc0003..4aeec4af 100644 --- a/adminer/include/adminer.inc.php +++ b/adminer/include/adminer.inc.php @@ -120,11 +120,14 @@ username.form['auth[driver]'].onchange(); */ function selectLinks($tableStatus, $set = "") { echo '

" . html_select("columns[$i][fun]", array(-1 => "") + $fun_group, $val["fun"]); - echo "()
\n"; + echo "(" . select_input(" name='columns[$i][col]' onchange='selectFieldChange(this.form);'", $columns, $val["col"]) . ")\n"; $i++; } echo "
" . html_select("columns[$i][fun]", array(-1 => "") + $fun_group, "", "this.nextSibling.nextSibling.onchange();"); - echo "()
\n"; + echo "(" . select_input(" name='columns[$i][col]' onchange='selectAddRow(this);'", $columns) . ")\n"; echo "\n"; } @@ -263,7 +266,7 @@ username.form['auth[driver]'].onchange(); for ($i = 0; $i <= count($_GET["where"]); $i++) { list(, $val) = each($_GET["where"]); if (!$val || ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators))) { - echo "
"; + echo "
" . select_input(" name='where[$i][col]' onchange='$change_next'", $columns, $val["col"], "(" . lang('anywhere') . ")"); echo html_select("where[$i][op]", $this->operators, $val["op"], $change_next); echo "
\n"; } @@ -281,13 +284,13 @@ username.form['auth[driver]'].onchange(); print_fieldset("sort", lang('Sort'), $order); $i = 0; foreach ((array) $_GET["order"] as $key => $val) { - if (isset($columns[$val])) { - echo "
"; + if ($val != "") { + echo "
" . select_input(" name='order[$i]' onchange='selectFieldChange(this.form);'", $columns, $val); echo checkbox("desc[$i]", 1, isset($_GET["desc"][$key]), lang('descending')) . "
\n"; $i++; } } - echo "
"; + echo "
" . select_input(" name='order[$i]' onchange='selectAddRow(this);'", $columns); echo checkbox("desc[$i]", 1, false, lang('descending')) . "
\n"; echo "
\n"; } @@ -372,8 +375,8 @@ username.form['auth[driver]'].onchange(); $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" || (isset($columns[$val["col"]]) && (!$val["fun"] || in_array($val["fun"], $functions) || in_array($val["fun"], $grouping)))) { - $select[$key] = apply_sql_function($val["fun"], (isset($columns[$val["col"]]) ? idf_escape($val["col"]) : "*")); + 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]; } @@ -437,8 +440,10 @@ username.form['auth[driver]'].onchange(); function selectOrderProcess($fields, $indexes) { $return = array(); foreach ((array) $_GET["order"] as $key => $val) { - if (isset($fields[$val]) || preg_match('~^((COUNT\\(DISTINCT |[A-Z0-9_]+\\()(`(?:[^`]|``)+`|"(?:[^"]|"")+")\\)|COUNT\\(\\*\\))$~', $val)) { //! MS SQL uses [] - $return[] = (isset($fields[$val]) ? idf_escape($val) : $val) . (isset($_GET["desc"][$key]) ? " DESC" : ""); + 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; @@ -724,7 +729,7 @@ username.form['auth[driver]'].onchange(); * @return bool whether to print default homepage */ function homepage() { - echo '

\n"; + echo "

" . (support("database") ? "\n" : ""); echo "\n"; echo $refresh; echo "

\n"; diff --git a/adminer/include/driver.inc.php b/adminer/include/driver.inc.php index bec94e57..7886596b 100644 --- a/adminer/include/driver.inc.php +++ b/adminer/include/driver.inc.php @@ -23,23 +23,31 @@ /** Update data in table * @param string - * @param array + * @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) { - $query = table($table) . " SET" . implode(",", $set); + 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($query, $queryWhere) : " $query$queryWhere")); } /** Insert data into table * @param string - * @param array + * @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")); + return queries("INSERT INTO " . table($table) . ($set + ? " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")" + : "DEFAULT VALUES" + )); } /** Insert or update data in table diff --git a/adminer/include/functions.inc.php b/adminer/include/functions.inc.php index 4e65a196..491117b4 100644 --- a/adminer/include/functions.inc.php +++ b/adminer/include/functions.inc.php @@ -149,6 +149,20 @@ function html_select($name, $options, $value = "", $onchange = true) { return $return; } +/** Generate HTML if $options are empty + * @param string + * @param array + * @param string + * @param string + * @return string + */ +function select_input($attrs, $options, $value = "", $placeholder = "") { + return ($options + ? "