1
0
mirror of https://github.com/vrana/adminer.git synced 2025-08-24 15:12:51 +02:00

Driver for SimpleDB

This commit is contained in:
Jakub Vrana
2013-07-06 10:31:21 -07:00
parent b7739dc0bd
commit d17b17e515
19 changed files with 610 additions and 78 deletions

View File

@@ -120,11 +120,14 @@ username.form['auth[driver]'].onchange();
*/
function selectLinks($tableStatus, $set = "") {
echo '<p class="links">';
$links = array("select" => lang('Select data'), "table" => lang('Show structure'));
if (is_view($tableStatus)) {
$links["view"] = lang('Alter view');
} else {
$links["create"] = lang('Alter table');
$links = array("select" => lang('Select data'));
if (support("table")) {
$links["table"] = lang('Show structure');
if (is_view($tableStatus)) {
$links["view"] = lang('Alter view');
} else {
$links["create"] = lang('Alter table');
}
}
if ($set !== null) {
$links["edit"] = lang('New item');
@@ -229,15 +232,15 @@ username.form['auth[driver]'].onchange();
global $functions, $grouping;
print_fieldset("select", lang('Select'), $select);
$i = 0;
$fun_group = array(lang('Functions') => $functions, lang('Aggregation') => $grouping);
$fun_group = array_filter(array(lang('Functions') => $functions, lang('Aggregation') => $grouping));
foreach ($select as $key => $val) {
$val = $_GET["columns"][$key];
echo "<div>" . html_select("columns[$i][fun]", array(-1 => "") + $fun_group, $val["fun"]);
echo "(<select name='columns[$i][col]' onchange='selectFieldChange(this.form);'><option>" . optionlist($columns, $val["col"], true) . "</select>)</div>\n";
echo "(" . select_input(" name='columns[$i][col]' onchange='selectFieldChange(this.form);'", $columns, $val["col"]) . ")</div>\n";
$i++;
}
echo "<div>" . html_select("columns[$i][fun]", array(-1 => "") + $fun_group, "", "this.nextSibling.nextSibling.onchange();");
echo "(<select name='columns[$i][col]' onchange='selectAddRow(this);'><option>" . optionlist($columns, null, true) . "</select>)</div>\n";
echo "(" . select_input(" name='columns[$i][col]' onchange='selectAddRow(this);'", $columns) . ")</div>\n";
echo "</div></fieldset>\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 "<div><select name='where[$i][col]' onchange='$change_next'><option value=''>(" . lang('anywhere') . ")" . optionlist($columns, $val["col"], true) . "</select>";
echo "<div>" . 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 "<input type='search' name='where[$i][val]' value='" . h($val["val"]) . "' onchange='" . ($val ? "selectFieldChange(this.form)" : "selectAddRow(this)") . ";' onsearch='selectSearchSearch(this);'></div>\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 "<div><select name='order[$i]' onchange='selectFieldChange(this.form);'><option>" . optionlist($columns, $val, true) . "</select>";
if ($val != "") {
echo "<div>" . select_input(" name='order[$i]' onchange='selectFieldChange(this.form);'", $columns, $val);
echo checkbox("desc[$i]", 1, isset($_GET["desc"][$key]), lang('descending')) . "</div>\n";
$i++;
}
}
echo "<div><select name='order[$i]' onchange='selectAddRow(this);'><option>" . optionlist($columns, null, true) . "</select>";
echo "<div>" . select_input(" name='order[$i]' onchange='selectAddRow(this);'", $columns);
echo checkbox("desc[$i]", 1, false, lang('descending')) . "</div>\n";
echo "</div></fieldset>\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 '<p class="links">' . ($_GET["ns"] == "" ? '<a href="' . h(ME) . 'database=">' . lang('Alter database') . "</a>\n" : "");
echo '<p class="links">' . ($_GET["ns"] == "" && support("database") ? '<a href="' . h(ME) . 'database=">' . lang('Alter database') . "</a>\n" : "");
echo (support("scheme") ? "<a href='" . h(ME) . "scheme='>" . ($_GET["ns"] != "" ? lang('Alter schema') : lang('Create schema')) . "</a>\n" : "");
echo ($_GET["ns"] !== "" ? '<a href="' . h(ME) . 'schema=">' . lang('Database schema') . "</a>\n" : "");
echo (support("privileges") ? "<a href='" . h(ME) . "privileges='>" . lang('Privileges') . "</a>\n" : "");
@@ -781,7 +786,7 @@ username.form['auth[driver]'].onchange();
$links[] = preg_quote($table, '/');
}
echo "<script type='text/javascript'>\n";
echo "var jushLinks = { $jush: [ '" . js_escape(ME) . "table=\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n";
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";
}
@@ -832,7 +837,11 @@ username.form['auth[driver]'].onchange();
echo "<p id='tables' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
foreach ($tables as $table => $status) {
echo '<a href="' . h(ME) . 'select=' . urlencode($table) . '"' . bold($_GET["select"] == $table || $_GET["edit"] == $table) . ">" . lang('select') . "</a> ";
echo '<a href="' . h(ME) . 'table=' . urlencode($table) . '"' . bold(in_array($table, array($_GET["table"], $_GET["create"], $_GET["indexes"], $_GET["foreign"], $_GET["trigger"]))) . " title='" . lang('Show structure') . "'>" . $this->tableName($status) . "</a><br>\n";
$name = $this->tableName($status);
echo (support("table")
? '<a href="' . h(ME) . 'table=' . urlencode($table) . '"' . bold(in_array($table, array($_GET["table"], $_GET["create"], $_GET["indexes"], $_GET["foreign"], $_GET["trigger"]))) . " title='" . lang('Show structure') . "'>$name</a>"
: $name
) . "<br>\n";
}
}

View File

@@ -63,6 +63,7 @@ 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/simpledb.inc.php";
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver
define("SERVER", $_GET[DRIVER]); // read from pgsql=localhost

View File

@@ -11,8 +11,9 @@ function connect_error() {
}
page_header(lang('Select database'), $error, false);
echo "<p class='links'><a href='" . h(ME) . "database='>" . lang('Create new database') . "</a>\n";
echo "<p class='links'>\n";
foreach (array(
'database' => lang('Create new database'),
'privileges' => lang('Privileges'),
'processlist' => lang('Process list'),
'variables' => lang('Variables'),
@@ -31,20 +32,21 @@ function connect_error() {
$collations = collations();
echo "<form action='' method='post'>\n";
echo "<table cellspacing='0' class='checkable' onclick='tableClick(event);' ondblclick='tableClick(event, true);'>\n";
echo "<thead><tr><td>&nbsp;<th>" . lang('Database') . "<td>" . lang('Collation') . "<td>" . lang('Tables') . "</thead>\n";
echo "<thead><tr>" . (support("database") ? "<td>&nbsp;" : "") . "<th>" . lang('Database') . "<td>" . lang('Collation') . "<td>" . lang('Tables') . "</thead>\n";
foreach ($databases as $db) {
$root = h(ME) . "db=" . urlencode($db);
echo "<tr" . odd() . "><td>" . checkbox("db[]", $db, in_array($db, (array) $_POST["db"]));
echo "<tr" . odd() . ">" . (support("database") ? "<td>" . checkbox("db[]", $db, in_array($db, (array) $_POST["db"])) : "");
echo "<th><a href='$root'>" . h($db) . "</a>";
echo "<td><a href='$root" . ($scheme ? "&amp;ns=" : "") . "&amp;database=' title='" . lang('Alter database') . "'>" . nbsp(db_collation($db, $collations)) . "</a>";
$collation = nbsp(db_collation($db, $collations));
echo "<td>" . (support("database") ? "<a href='$root" . ($scheme ? "&amp;ns=" : "") . "&amp;database=' title='" . lang('Alter database') . "'>$collation</a>" : $collation);
echo "<td align='right'><a href='$root&amp;schema=' id='tables-" . h($db) . "' title='" . lang('Database schema') . "'>?</a>";
echo "\n";
}
echo "</table>\n";
echo "<script type='text/javascript'>tableCheck();</script>\n";
echo "<p><input type='submit' name='drop' value='" . lang('Drop') . "'" . confirm("formChecked(this, /db/)") . ">\n";
echo "<p>" . (support("database") ? "<input type='submit' name='drop' value='" . lang('Drop') . "'" . confirm("formChecked(this, /db/)") . ">\n" : "");
echo "<input type='hidden' name='token' value='$token'>\n";
echo $refresh;
echo "</form>\n";

View File

@@ -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

View File

@@ -149,6 +149,20 @@ function html_select($name, $options, $value = "", $onchange = true) {
return $return;
}
/** Generate HTML <select> or <input> if $options are empty
* @param string
* @param array
* @param string
* @param string
* @return string
*/
function select_input($attrs, $options, $value = "", $placeholder = "") {
return ($options
? "<select$attrs><option value=''>$placeholder" . optionlist($options, $value, true) . "</select>"
: "<input$attrs value='" . h($value) . "' placeholder='$placeholder'>"
);
}
/** Get onclick confirmation
* @param string JavaScript expression
* @return string
@@ -264,15 +278,18 @@ function get_vals($query, $column = 0) {
/** Get keys from first column and values from second
* @param string
* @param Min_DB
* @param float
* @return array
*/
function get_key_vals($query, $connection2 = null) {
function get_key_vals($query, $connection2 = null, $timeout = 0) {
global $connection;
if (!is_object($connection2)) {
$connection2 = $connection;
}
$return = array();
$connection2->timeout = $timeout;
$result = $connection2->query($query);
$connection2->timeout = 0;
if (is_object($result)) {
while ($row = $result->fetch_row()) {
$return[$row[0]] = $row[1];
@@ -330,7 +347,7 @@ function unique_array($row, $indexes) {
function where($where, $fields = array()) {
global $jush;
$return = array();
$function_pattern = '(^[\w\(]+' . str_replace("_", ".*", preg_quote(idf_escape("_"))) . '\)+$)'; //! columns looking like functions
$function_pattern = '(^[\w\(]+(' . str_replace("_", ".*", preg_quote(idf_escape("_"))) . ')?\)+$)'; //! columns looking like functions
foreach ((array) $where["where"] as $key => $val) {
$key = bracket_escape($key, 1); // 1 - back
$column = (preg_match($function_pattern, $key) ? $key : idf_escape($key)); //! SQL injection
@@ -590,7 +607,10 @@ function remove_from_uri($param = "") {
* @return string
*/
function pagination($page, $current) {
return " " . ($page == $current ? $page + 1 : '<a href="' . h(remove_from_uri("page") . ($page ? "&page=$page" : "")) . '">' . ($page + 1) . "</a>");
return " " . ($page == $current
? $page + 1
: '<a href="' . h(remove_from_uri("page") . ($page ? "&page=$page" . ($_GET["next"] ? "&next=" . urlencode($_GET["next"]) : "") : "")) . '">' . ($page + 1) . "</a>"
);
}
/** Get file contents from $_FILES
@@ -1004,6 +1024,7 @@ function count_rows($table, $where, $is_group, $group) {
function slow_query($query) {
global $adminer, $token;
$db = $adminer->database();
$timeout = $adminer->queryTimeout();
if (support("kill") && is_object($connection2 = connect()) && ($db == "" || $connection2->select_db($db))) {
$kill = $connection2->result("SELECT CONNECTION_ID()"); // MySQL and MySQLi can use thread_id but it's not in PDO_MySQL
?>
@@ -1011,7 +1032,7 @@ function slow_query($query) {
var timeout = setTimeout(function () {
ajax('<?php echo js_escape(ME); ?>script=kill', function () {
}, 'token=<?php echo $token; ?>&kill=<?php echo $kill; ?>');
}, <?php echo 1000 * $adminer->queryTimeout(); ?>);
}, <?php echo 1000 * $timeout; ?>);
</script>
<?php
} else {
@@ -1019,7 +1040,7 @@ var timeout = setTimeout(function () {
}
ob_flush();
flush();
$return = @get_key_vals($query, $connection2); // @ - may be killed
$return = @get_key_vals($query, $connection2, $timeout); // @ - may be killed
if ($connection2) {
echo "<script type='text/javascript'>clearTimeout(timeout);</script>\n";
ob_flush();