Compare commits

...

139 Commits

Author SHA1 Message Date
Jakub Vrana
967647759e Release 5.0.5 2025-03-13 18:28:43 +01:00
Jakub Vrana
e4323ced55 Tests: Fix CockroachDB after 48308f3 2025-03-13 18:22:06 +01:00
Jakub Vrana
85c6af6f87 Compile: strip space after CSS comment 2025-03-13 18:00:54 +01:00
Jakub Vrana
9226804aa2 CSS: Move media selector to <link> 2025-03-13 17:55:42 +01:00
Jakub Vrana
041e7064ca php_shrink: Simplify test 2025-03-13 17:45:16 +01:00
Jakub Vrana
4c2a8b0050 Compile: Move ?><? removal to php_shrink 2025-03-13 17:43:20 +01:00
Jakub Vrana
9afbf1a465 Compile: dark.css 2025-03-13 17:33:19 +01:00
Jakub Vrana
352ef9c778 CSS: Don't use dark theme with adminer.css 2025-03-13 17:11:40 +01:00
Jakub Vrana
45107dc46e Don't highlight NULL as JSON 2025-03-13 16:55:17 +01:00
Jakub Vrana
21f3426adb Design: Update dark mode (by rmsoft) 2025-03-13 16:48:56 +01:00
Jakub Vrana
95dccfe9fb MongoDB: Rename file 2025-03-13 15:21:19 +01:00
Jakub Vrana
fe88f83c95 Elastic: Fix number of rows in group queries 2025-03-13 14:34:26 +01:00
Jakub Vrana
078957fe32 MongoDB: Move to plugin 2025-03-13 14:27:54 +01:00
Jakub Vrana
61f07867f9 Update readme 2025-03-13 14:09:45 +01:00
Jakub Vrana
0135dd5b81 Tests: Add tests for MS SQL 2025-03-13 14:07:31 +01:00
Jakub Vrana
773a2253d3 Export: Display unknown number of rows as ? 2025-03-13 13:29:10 +01:00
Jakub Vrana
272042a30e Fix skipOriginal after unconvertFunction 2025-03-13 13:13:06 +01:00
Jakub Vrana
48308f3357 CockroachDB: Recognize unique_rowid() as auto_increment 2025-03-13 13:09:05 +01:00
Jakub Vrana
c90033a962 Test PostgreSQL: SQL command 2025-03-13 13:03:24 +01:00
Jakub Vrana
8bd022f974 CockroachDB: Fix test 2025-03-13 13:02:53 +01:00
Jakub Vrana
b1550b052d MySQL: Simplify checking for MariaDB 2025-03-13 12:24:35 +01:00
Jakub Vrana
9862846a7c CockroachDB: Declare support 2025-03-13 12:15:37 +01:00
Jakub Vrana
f14e3e38f6 CockroachDB: Disable processlist 2025-03-13 12:12:44 +01:00
Jakub Vrana
95262c4215 CSS: Fix style 2025-03-13 12:08:01 +01:00
Jakub Vrana
dacfdc4608 Tests: Work with JUSH textarea 2025-03-13 12:07:49 +01:00
Jakub Vrana
7636c253fb CockroachDB: Display version 2025-03-13 11:51:03 +01:00
Jakub Vrana
44d26a9dd3 Tests: Add tests for CockroachDB 2025-03-13 11:08:42 +01:00
Jakub Vrana
b229e7b583 Tests: Add tests for MariaDB and PostgreSQL 2025-03-13 10:45:53 +01:00
Jakub Vrana
8e91417be1 MySQL: Display converting function for binary, bit or geometry fields 2025-03-13 07:50:20 +01:00
Peter Knut
db7202fcf0 MySQL: Fix saving string default value of json field 2025-03-13 07:19:27 +01:00
Jakub Vrana
260487fbc2 Designs: Update rmsoft (fix #911) 2025-03-13 07:10:23 +01:00
Jakub Vrana
3ae964c915 Designs: Fix price 2025-03-13 07:06:43 +01:00
Jakub Vrana
d56c8cbaae CSS: Simplify .odds 2025-03-13 07:03:42 +01:00
Jakub Vrana
d347f88c54 Design: Update rmsoft (fix #911) 2025-03-13 06:38:32 +01:00
Jakub Vrana
b9b4db0c8e Compile: Add more php_shrink tests 2025-03-13 06:10:58 +01:00
Jakub Vrana
818b9ad903 Compile: Strip public 2025-03-12 23:15:24 +01:00
Jakub Vrana
4a6436773f Compile: Add tests for php_shrink 2025-03-12 23:15:22 +01:00
Jakub Vrana
81594e4a2d Issues: Prefer MySQLi 2025-03-12 18:28:56 +01:00
Jakub Vrana
f0bdb0e6ca Designs: Update .odds 2025-03-12 17:50:24 +01:00
Jakub Vrana
b9e4806d3c CSS: lowercase color names 2025-03-12 17:43:58 +01:00
Jakub Vrana
7e708dae57 CSS: Add dark theme 2025-03-12 17:42:53 +01:00
Jakub Vrana
a0fe44ec18 CSS: Expand <code> in <pre> 2025-03-12 17:35:44 +01:00
Jakub Vrana
eb0f280776 CSS: Fix highlighting checked odd rows 2025-03-12 17:35:34 +01:00
Jakub Vrana
3b1189cd3c MySQL: Allow setting default values of json column 2025-03-12 14:25:19 +01:00
Jakub Vrana
434a8f7705 CSS: Disable odd on hover 2025-03-12 13:58:20 +01:00
Jakub Vrana
f9478c67d2 CSS: Merge rules 2025-03-12 12:57:59 +01:00
Jakub Vrana
f2ce6c0a71 Wrap long lines 2025-03-12 11:43:21 +01:00
Jakub Vrana
a50b3d6385 MS SQL: Fix editing rows with datetime column in primary key
Inspired by adminneo-org@b4afc08.
This fixes https://sourceforge.net/p/adminer/discussion/960418/thread/a547e79622/.
2025-03-12 09:28:22 +01:00
Jakub Vrana
e39deca4f1 Wrap Schema: in navigation to <span> (fix #907) 2025-03-12 09:26:04 +01:00
Jakub Vrana
ce69970f54 Update German translation (by @wintstar) 2025-03-12 09:09:09 +01:00
Jakub Vrana
51ac1312a1 MariaDB: Don't display NULL as default value 2025-03-12 08:51:25 +01:00
Jakub Vrana
4505544953 Code style: exclude removed extensions 2025-03-12 08:12:28 +01:00
Jakub Vrana
fa75213ff6 Coverage: Fix newlines 2025-03-12 06:15:47 +01:00
Jakub Vrana
63acb37ea6 Coverage: Display drivers 2025-03-12 06:09:18 +01:00
Jakub Vrana
3ad6c16f59 Coverage: Modernize HTML 2025-03-12 06:06:28 +01:00
Jakub Vrana
22d08b4a50 Add comment 2025-03-12 06:01:29 +01:00
Jakub Vrana
dd3cc4e683 Add plugin AdminerEditorViews (fix #905) 2025-03-12 05:22:57 +01:00
Jakub Vrana
5504a617d0 Compile: Support private static 2025-03-12 05:03:42 +01:00
Jakub Vrana
2fdebfda29 Ensure PHP 5.3 compatibility 2025-03-11 21:43:59 +01:00
Jakub Vrana
dc2e945aef MySQL: Convert binary default value to hex when editing 2025-03-11 20:25:52 +01:00
Jakub Vrana
43d86287c4 Fix focusing first field 2025-03-11 20:16:49 +01:00
Jakub Vrana
a94a727af7 PostgreSQL PDO: Escape bytea values (bug #218) 2025-03-11 19:42:10 +01:00
Jakub Vrana
c2d29a6937 MySQL: Display default values of binary columns 2025-03-11 19:25:42 +01:00
Jakub Vrana
c082136558 Rename variable 2025-03-11 18:40:34 +01:00
Jakub Vrana
7b1ea5fa2c AdminerDumpAlter: Use dumpFooter 2025-03-11 18:20:11 +01:00
Jakub Vrana
156839142e Fix plugin AdminerPrettyJsonColumn 2025-03-11 18:16:44 +01:00
Jakub Vrana
2ee4e3b2e1 Compile: Fix shortening in protected functions 2025-03-11 17:56:21 +01:00
Jakub Vrana
8b4c8b0156 Fix coverage 2025-03-11 14:37:08 +01:00
Jakub Vrana
9702878297 Develop 2025-03-11 14:00:37 +01:00
Jakub Vrana
4a54648995 Release 5.0.4 2025-03-11 13:52:53 +01:00
Jakub Vrana
2e5027a1aa Compile: Fix shortening in private methods 2025-03-11 13:50:36 +01:00
Jakub Vrana
5a4c4dd892 Release 5.0.3 2025-03-11 13:16:35 +01:00
Jakub Vrana
7ef009336f PostgreSQL: Fix where and order privileges (fix #902) 2025-03-11 13:07:50 +01:00
Jakub Vrana
1defc94d12 Fix $result visibility 2025-03-11 12:53:35 +01:00
Jakub Vrana
5d3376e620 Check more style 2025-03-11 12:21:07 +01:00
Jakub Vrana
d410cdc5be Mongo: Add helper method 2025-03-11 11:13:40 +01:00
Jakub Vrana
a44e625882 Set visibility to protected 2025-03-11 11:05:39 +01:00
Jakub Vrana
ae57d42105 SQLite: Fix calling private property 2025-03-11 11:05:10 +01:00
Jakub Vrana
199edfe11f Plugins: Add method dumpFooter() 2025-03-11 08:59:38 +01:00
Jakub Vrana
b02c3e1f7f Use private visibility 2025-03-11 08:36:35 +01:00
Jakub Vrana
98cb9b9aca Add comment 2025-03-11 08:29:01 +01:00
Jakub Vrana
514d64048d Disallow var 2025-03-11 08:17:02 +01:00
Jakub Vrana
1e963cf90f Change var to public 2025-03-11 08:17:00 +01:00
Jakub Vrana
0c15a9f42d Use private visibility on methods 2025-03-11 08:16:41 +01:00
Jakub Vrana
c454ea8430 Use protected visibility 2025-03-11 08:16:41 +01:00
Jakub Vrana
607febea8e Use private visibility 2025-03-11 08:16:39 +01:00
Jakub Vrana
ebd5f19dd4 Use protected visibility 2025-03-11 08:12:09 +01:00
Jakub Vrana
1b0984ff31 Compile: Change public to var 2025-03-11 07:16:20 +01:00
Jakub Vrana
b017928256 Revert accidental revert 2025-03-11 07:05:16 +01:00
Jakub Vrana
526077535e Update changes 2025-03-11 07:00:21 +01:00
Jakub Vrana
8274b2e0e8 Update bug template 2025-03-11 06:50:04 +01:00
Jakub Vrana
8f7d456887 Update changes 2025-03-11 06:45:38 +01:00
Jakub Vrana
91b735c576 Compile: Support \r\n line ends 2025-03-11 06:30:31 +01:00
Jakub Vrana
916b9e62de Fix double unescaping 2025-03-11 06:24:21 +01:00
Jakub Vrana
f25c65837f Add comment 2025-03-11 06:24:21 +01:00
Jakub Vrana
b0182834bf Fix typo 2025-03-11 06:24:21 +01:00
David Grudl
6bf0b85919 Compile: supports visibility modifiers 2025-03-11 06:24:07 +01:00
Jakub Vrana
37e63dd82f MySQL: Stop treating enum as set as numbers (bug #475) 2025-03-10 23:40:07 +01:00
Jakub Vrana
6fdde32f86 Remove check for PHP version 2025-03-10 23:03:20 +01:00
Jakub Vrana
aeac0a3329 MySQL: Allow setting default values of text column 2025-03-10 21:15:01 +01:00
Christian Weiske
fde7d7dde2 Elastic: Properly display sparse result rows
Result records in Elasticsearch do not always have all columns
that are defined in an index.
This often happens when multiple document types are stored in the same index.

The first row has columns ["_id", "html", "url"], while the second
misses the "html" column: ["_id", "url"].

Adminer expects that all result rows include all columns.
This leads to the problem that the "url" value in the 2nd example row
was rendered in the "html" column.

This patch fixes this problem by fetching the actual column list first
when all fields are to be shown, and using that field list
as base for all rows.
2025-03-10 21:14:54 +01:00
Christian Weiske
e993462412 Elastic: Fix record insertion on Elasticsearch 7
1. Make values NULLable by default, so that empty values do not
get submitted to the Elasticsearch server.
This helps e.g. with empty date fields - Elasticsearch would try to
convert the field type to string when the value is an empty string,
but that fails when there are documents with properly filled date fields

2. Remove _id from the POST array because this is not allowed.
The server fails if it is included with
> mapper_parsing_exception:
> Field [_id] is a metadata field and cannot be added inside a document.
> Use the index API request parameters.

3. Use the correct URL to create a document: "$index/_doc/"
and "$index/_doc/$id". This is the same for ES 7 and 8:
- https://www.elastic.co/guide/en/elasticsearch/reference/8.17/docs-index_.html#docs-index-api-request
- https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-index_.html#docs-index-api-request

4. Handle failed creations by checking for false

5. Return the "result" property string instead of the non-existing
"created" property.
2025-03-10 21:13:16 +01:00
Jakub Vrana
31f8f61d0e MySQL, MariaDB: Fix default values with ' (fix #895) 2025-03-10 21:01:21 +01:00
Jakub Vrana
e589ee3fde MariaDB: Fix creating and altering generated columns (fixes #897) 2025-03-10 19:18:14 +01:00
Jakub Vrána
35274f18bb Update issue templates 2025-03-10 19:09:56 +01:00
Jakub Vrana
f8b2640156 Fix gzip export (fixes #896) 2025-03-10 18:51:28 +01:00
Jakub Vrana
bb23546478 Use <datalist> for altering collations 2025-03-10 14:13:34 +01:00
Jakub Vrana
dddfc190a5 Split helper html_radios 2025-03-10 11:31:43 +01:00
Jakub Vrana
40760d153c Update changes 2025-03-10 09:09:09 +01:00
Peter Knut
4fe3d17255 Update Slovak translation 2025-03-10 09:09:09 +01:00
Jakub Vrana
6dcc5081e1 Fix importing multiple SQL files not terminated by semicolon
Inspired by adminneo-org/adminneo#1c08e86.
2025-03-10 09:09:09 +01:00
Jakub Vrana
df6fe6b108 Fix link 2025-03-10 09:09:09 +01:00
Jakub Vrana
e6339046ff Remove unused variable 2025-03-10 09:09:09 +01:00
Jakub Vrana
2c0cfbdd3f Develop 2025-03-10 09:09:09 +01:00
Christian Weiske
f13770c664 Make login to Elasticsearch work again
By partially reverting the changes made by
commit 2c9f380c64
> Elastic: Remove plugin for version 5
which removed the passwordless login plugin from adminer/elastic.php
2025-03-10 08:53:19 +01:00
Jakub Vrana
100a1f49bc Release 5.0.2 2025-03-10 07:18:15 +01:00
Jakub Vrana
47ccd9b44d Add comment 2025-03-09 18:29:02 +01:00
Dragsio
7512bc2d51 Wrap username in <span>
Username enclosed in tags for better use of custom themes (eg. vertical padding).
2025-03-09 18:28:50 +01:00
Jakub Vrana
4991817b0d Extract variable 2025-03-08 23:12:08 +01:00
Peter Knut
e883ad428e Add support for "order" field privilege
In Elasticsearch, text fields are not sortable.
2025-03-08 23:12:00 +01:00
Peter Knut
87d87248c1 Add support for "where" field privilege
In Elasticsearch, only indexed fields are searchable.
2025-03-08 23:05:16 +01:00
Jakub Vrana
862e5b4aa4 Move variable initialization 2025-03-08 21:45:21 +01:00
Jakub Vrana
ad2cbbf26e Use helper function 2025-03-08 19:59:32 +01:00
Jakub Vrana
afe7dd9ad9 Display explain on first click
Also remove extra newlines in explain
2025-03-08 18:18:58 +01:00
Jakub Vrana
3b2ef32349 Add missing namespace to plugin 2025-03-08 17:32:52 +01:00
Jakub Vrana
47b64f4752 Composer: Add script for cleaning 2025-03-08 17:10:21 +01:00
Jakub Vrana
a1c3e34e04 Translations: check fullstops in 'ja' and 'he' 2025-03-08 17:06:30 +01:00
Jakub Vrana
608eec89dd Translations: Add missing placeholders 2025-03-08 10:05:14 +01:00
Jakub Vrana
cfe39e48ca Update xx translation 2025-03-08 10:05:11 +01:00
Jakub Vrana
900a3c0d6a Translations: Fix fullstops 2025-03-08 08:09:29 +01:00
Jakub Vrana
ead6a9a36f Polish: Change link to web 2025-03-08 06:49:32 +01:00
Matthaiks
d05a758a88 Update Polish translation 2025-03-08 06:47:52 +01:00
Jakub Vrana
b0450d0d2a PostgreSQL: Fix setting NULL and original value on enum (bug #884) 2025-03-08 06:44:12 +01:00
Jakub Vrana
e7c3a046a7 Oracle: Fix Db::result 2025-03-08 06:14:26 +01:00
Jakub Vrana
d35c896b92 Add helper function 2025-03-08 06:13:18 +01:00
Jakub Vrana
4b71549ca0 CockroachDB: Add support via PostgreSQL driver
This fixes cockroachdb/cockroach#40391.
2025-03-08 05:56:49 +01:00
Jakub Vrana
ab0f07dd81 Don't create Driver with connection error 2025-03-08 05:37:01 +01:00
Jakub Vrana
c19e6f27f1 Move issues to GitHub 2025-03-07 19:42:21 +01:00
Jakub Vrana
14b257784b Develop 2025-03-07 13:19:34 +01:00
133 changed files with 2878 additions and 1181 deletions

14
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,14 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Adminer version:** please use latest published or Git
**Driver:** e.g. MySQLi
**Database version:** e.g. 10.2.12-MariaDB
Please provide reproducible steps including a SQL dump (with no personal information) if applicable.

View File

@@ -6,6 +6,6 @@ I support only the last published version and the last development version (last
## Reporting a Vulnerability
To report a vulnerability, create a private bug at https://sourceforge.net/p/adminer/bugs-and-features/new/?private=1.
To report a vulnerability, add a new draft security advisory at https://github.com/vrana/adminer/security/advisories/new.
I handle security issues with top priority. If you don't hear from me in a week then please ping the bug. Once I accept the bug, the fix should be available and new version released within days. I will mark the bug as public after releasing a new version or declining the bug.

View File

@@ -73,11 +73,8 @@ if ($in) {
echo "<tr><th>" . $adminer->fieldName($field);
$value = $_POST["fields"][$name];
if ($value != "") {
if ($field["type"] == "enum") {
$value = +$value;
}
if ($field["type"] == "set") {
$value = array_sum($value);
$value = implode(",", $value);
}
}
input($field, $value, (string) $_POST["function"][$name]); // param name can be empty

View File

@@ -83,17 +83,18 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
$partitioning = "";
if (support("partitioning")) {
if (isset($partition_by[$row["partition_by"]])) {
$params = array_filter($row, function ($key) {
return preg_match('~^partition~', $key);
}, ARRAY_FILTER_USE_KEY);
$params = array();
foreach ($row as $key => $val) {
if (preg_match('~^partition~', $key)) {
$params[$key] = $val;
}
}
foreach ($params["partition_names"] as $key => $name) {
if ($name == "") {
unset($params["partition_names"][$key]);
unset($params["partition_values"][$key]);
}
}
if ($params != get_partitions_info($TABLE)) {
$partitions = array();
if ($params["partition_by"] == 'RANGE' || $params["partition_by"] == 'LIST') {
@@ -102,7 +103,6 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
$partitions[] = "\n PARTITION " . idf_escape($name) . " VALUES " . ($params["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection
}
}
// $params["partition"] can be expression, not only column
$partitioning .= "\nPARTITION BY $params[partition_by]($params[partition])";
if ($partitions) {
@@ -182,8 +182,13 @@ foreach ($engines as $engine) {
<p>
<?php if (support("columns") || $TABLE == "") { ?>
<?php echo lang('Table name'); ?>: <input name="name"<?php echo ($TABLE == "" && !$_POST ? " autofocus" : ""); ?> data-maxlength="64" value="<?php echo h($row["name"]); ?>" autocapitalize="off">
<?php echo ($engines ? "<select name='Engine'>" . optionlist(array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . "</select>" . on_help("getTarget(event).value", 1) . script("qsl('select').onchange = helpClose;") : ""); ?>
<?php echo ($collations && !preg_match("~sqlite|mssql~", JUSH) ? html_select("Collation", array("" => "(" . lang('collation') . ")") + $collations, $row["Collation"]) : ""); ?>
<?php echo ($engines ? html_select("Engine", array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . on_help("getTarget(event).value", 1) . script("qsl('select').onchange = helpClose;") : ""); ?>
<?php
if ($collations) {
echo "<datalist id='collations'>" . optionlist($collations) . "</datalist>";
echo (preg_match("~sqlite|mssql~", JUSH) ? "" : "<input list='collations' name='Collation' value='" . h($row["Collation"]) . "' placeholder='(" . lang('collation') . ")'>");
}
?>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php } ?>
@@ -223,7 +228,7 @@ if (support("partitioning")) {
print_fieldset("partition", lang('Partition by'), $row["partition_by"]);
?>
<p>
<?php echo "<select name='partition_by'>" . optionlist(array("" => "") + $partition_by, $row["partition_by"]) . "</select>" . on_help("getTarget(event).value.replace(/./, 'PARTITION BY \$&')", 1) . script("qsl('select').onchange = partitionByChange;"); ?>
<?php echo html_select("partition_by", array("" => "") + $partition_by, $row["partition_by"]) . on_help("getTarget(event).value.replace(/./, 'PARTITION BY \$&')", 1) . script("qsl('select').onchange = partitionByChange;"); ?>
(<input name="partition" value="<?php echo h($row["partition"]); ?>">)
<?php echo lang('Partitions'); ?>: <input type="number" name="partitions" class="size<?php echo ($partition_table || !$row["partition_by"] ? " hidden" : ""); ?>" value="<?php echo h($row["partitions"]); ?>">
<table id="partition-table"<?php echo ($partition_table ? "" : " class='hidden'"); ?>>

View File

@@ -123,7 +123,7 @@ if ($adminer->homepage()) {
}
echo "<tr><td><th>" . lang('%d in total', count($tables_list));
echo "<td>" . h(JUSH == "sql" ? $connection->result("SELECT @@default_storage_engine") : "");
echo "<td>" . h(JUSH == "sql" ? get_val("SELECT @@default_storage_engine") : "");
echo "<td>" . h(db_collation(DB, collations()));
foreach (array("Data_length", "Index_length", "Data_free") as $key) {
echo "<td align='right' id='sum-$key'>";
@@ -232,7 +232,7 @@ if ($adminer->homepage()) {
echo '<td><a href="' . h(ME) . 'event=' . urlencode($row["Name"]) . '">' . lang('Alter') . '</a>';
}
echo "</table>\n";
$event_scheduler = $connection->result("SELECT @@event_scheduler");
$event_scheduler = get_val("SELECT @@event_scheduler");
if ($event_scheduler && $event_scheduler != "ON") {
echo "<p class='error'><code class='jush-sqlset'>event_scheduler</code>: " . h($event_scheduler) . "\n";
}

View File

@@ -13,9 +13,10 @@ if (isset($_GET["mssql"])) {
define('Adminer\DRIVER', "mssql");
if (extension_loaded("sqlsrv")) {
class Db {
var $extension = "sqlsrv", $_link, $_result, $server_info, $affected_rows, $errno, $error;
public $extension = "sqlsrv", $server_info, $affected_rows, $errno, $error;
private $link, $result;
function _get_error() {
private function get_error() {
$this->error = "";
foreach (sqlsrv_errors() as $error) {
$this->errno = $error["code"];
@@ -38,14 +39,14 @@ if (isset($_GET["mssql"])) {
if ($db != "") {
$connection_info["Database"] = $db;
}
$this->_link = @sqlsrv_connect(preg_replace('~:~', ',', $server), $connection_info);
if ($this->_link) {
$info = sqlsrv_server_info($this->_link);
$this->link = @sqlsrv_connect(preg_replace('~:~', ',', $server), $connection_info);
if ($this->link) {
$info = sqlsrv_server_info($this->link);
$this->server_info = $info['SQLServerVersion'];
} else {
$this->_get_error();
$this->get_error();
}
return (bool) $this->_link;
return (bool) $this->link;
}
function quote($string) {
@@ -58,20 +59,20 @@ if (isset($_GET["mssql"])) {
}
function query($query, $unbuffered = false) {
$result = sqlsrv_query($this->_link, $query); //! , array(), ($unbuffered ? array() : array("Scrollable" => "keyset"))
$result = sqlsrv_query($this->link, $query); //! , array(), ($unbuffered ? array() : array("Scrollable" => "keyset"))
$this->error = "";
if (!$result) {
$this->_get_error();
$this->get_error();
return false;
}
return $this->store_result($result);
}
function multi_query($query) {
$this->_result = sqlsrv_query($this->_link, $query);
$this->result = sqlsrv_query($this->link, $query);
$this->error = "";
if (!$this->_result) {
$this->_get_error();
if (!$this->result) {
$this->get_error();
return false;
}
return true;
@@ -79,7 +80,7 @@ if (isset($_GET["mssql"])) {
function store_result($result = null) {
if (!$result) {
$result = $this->_result;
$result = $this->result;
}
if (!$result) {
return false;
@@ -92,7 +93,7 @@ if (isset($_GET["mssql"])) {
}
function next_result() {
return $this->_result ? sqlsrv_next_result($this->_result) : null;
return $this->result ? sqlsrv_next_result($this->result) : null;
}
function result($query, $field = 0) {
@@ -106,14 +107,15 @@ if (isset($_GET["mssql"])) {
}
class Result {
var $_result, $_offset = 0, $_fields, $num_rows;
public $num_rows;
private $result, $offset = 0, $fields;
function __construct($result) {
$this->_result = $result;
$this->result = $result;
// $this->num_rows = sqlsrv_num_rows($result); // available only in scrollable results
}
function _convert($row) {
private function convert($row) {
foreach ((array) $row as $key => $val) {
if (is_a($val, 'DateTime')) {
$row[$key] = $val->format("Y-m-d H:i:s");
@@ -124,18 +126,18 @@ if (isset($_GET["mssql"])) {
}
function fetch_assoc() {
return $this->_convert(sqlsrv_fetch_array($this->_result, SQLSRV_FETCH_ASSOC));
return $this->convert(sqlsrv_fetch_array($this->result, SQLSRV_FETCH_ASSOC));
}
function fetch_row() {
return $this->_convert(sqlsrv_fetch_array($this->_result, SQLSRV_FETCH_NUMERIC));
return $this->convert(sqlsrv_fetch_array($this->result, SQLSRV_FETCH_NUMERIC));
}
function fetch_field() {
if (!$this->_fields) {
$this->_fields = sqlsrv_field_metadata($this->_result);
if (!$this->fields) {
$this->fields = sqlsrv_field_metadata($this->result);
}
$field = $this->_fields[$this->_offset++];
$field = $this->fields[$this->offset++];
$return = new \stdClass;
$return->name = $field["Name"];
$return->orgname = $field["Name"];
@@ -145,18 +147,18 @@ if (isset($_GET["mssql"])) {
function seek($offset) {
for ($i=0; $i < $offset; $i++) {
sqlsrv_fetch($this->_result); // SQLSRV_SCROLL_ABSOLUTE added in sqlsrv 1.1
sqlsrv_fetch($this->result); // SQLSRV_SCROLL_ABSOLUTE added in sqlsrv 1.1
}
}
function __destruct() {
sqlsrv_free_stmt($this->_result);
sqlsrv_free_stmt($this->result);
}
}
} elseif (extension_loaded("pdo_sqlsrv")) {
class Db extends PdoDb {
var $extension = "PDO_SQLSRV";
public $extension = "PDO_SQLSRV";
function connect($server, $username, $password) {
$this->dsn("sqlsrv:Server=" . str_replace(":", ",", $server), $username, $password);
@@ -171,7 +173,7 @@ if (isset($_GET["mssql"])) {
} elseif (extension_loaded("pdo_dblib")) {
class Db extends PdoDb {
var $extension = "PDO_DBLIB";
public $extension = "PDO_DBLIB";
function connect($server, $username, $password) {
$this->dsn("dblib:charset=utf8;host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\d)~', ';port=\1', $server)), $username, $password);
@@ -189,7 +191,7 @@ if (isset($_GET["mssql"])) {
static $possibleDrivers = array("SQLSRV", "PDO_SQLSRV", "PDO_DBLIB");
static $jush = "mssql";
var $editFunctions = array(
public $editFunctions = array(
array(
"date|time" => "getdate",
), array(
@@ -198,11 +200,11 @@ if (isset($_GET["mssql"])) {
)
);
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL");
var $functions = array("len", "lower", "round", "upper");
var $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
var $onActions = "NO ACTION|CASCADE|SET NULL|SET DEFAULT";
var $generated = array("PERSISTED", "VIRTUAL");
public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL");
public $functions = array("len", "lower", "round", "upper");
public $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
public $onActions = "NO ACTION|CASCADE|SET NULL|SET DEFAULT";
public $generated = array("PERSISTED", "VIRTUAL");
function __construct($connection) {
parent::__construct($connection);
@@ -304,8 +306,7 @@ if (isset($_GET["mssql"])) {
}
function db_collation($db, $collations) {
global $connection;
return $connection->result("SELECT collation_name FROM sys.databases WHERE name = " . q($db));
return get_val("SELECT collation_name FROM sys.databases WHERE name = " . q($db));
}
function engines() {
@@ -313,8 +314,7 @@ if (isset($_GET["mssql"])) {
}
function logged_user() {
global $connection;
return $connection->result("SELECT SUSER_NAME()");
return get_val("SELECT SUSER_NAME()");
}
function tables_list() {
@@ -326,7 +326,7 @@ if (isset($_GET["mssql"])) {
$return = array();
foreach ($databases as $db) {
$connection->select_db($db);
$return[$db] = $connection->result("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES");
$return[$db] = get_val("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES");
}
return $return;
}
@@ -355,10 +355,9 @@ WHERE schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND type IN ('S', 'U', 'V')
}
function fields($table) {
global $connection;
$comments = get_key_vals("SELECT objname, cast(value as varchar(max)) FROM fn_listextendedproperty('MS_DESCRIPTION', 'schema', " . q(get_schema()) . ", 'table', " . q($table) . ", 'column', NULL)");
$return = array();
$table_id = $connection->result("SELECT object_id FROM sys.all_objects WHERE schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND type IN ('S', 'U', 'V') AND name = " . q($table));
$table_id = get_val("SELECT object_id FROM sys.all_objects WHERE schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND type IN ('S', 'U', 'V') AND name = " . q($table));
foreach (
get_rows("SELECT c.max_length, c.precision, c.scale, c.name, c.is_nullable, c.is_identity, c.collation_name, t.name type, CAST(d.definition as text) [default], d.name default_constraint, i.is_primary_key
FROM sys.all_columns c
@@ -383,7 +382,7 @@ WHERE c.object_id = " . q($table_id)) as $row
"null" => $row["is_nullable"],
"auto_increment" => $row["is_identity"],
"collation" => $row["collation_name"],
"privileges" => array("insert" => 1, "select" => 1, "update" => 1),
"privileges" => array("insert" => 1, "select" => 1, "update" => 1, "where" => 1, "order" => 1),
"primary" => $row["is_primary_key"],
"comment" => $comments[$row["name"]],
);
@@ -415,8 +414,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
}
function view($name) {
global $connection;
return array("select" => preg_replace('~^(?:[^[]|\[[^]]*])*\s+AS\s+~isU', '', $connection->result("SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = SCHEMA_NAME() AND TABLE_NAME = " . q($name))));
return array("select" => preg_replace('~^(?:[^[]|\[[^]]*])*\s+AS\s+~isU', '', get_val("SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = SCHEMA_NAME() AND TABLE_NAME = " . q($name))));
}
function collations() {
@@ -511,7 +509,16 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
foreach ($comments as $key => $val) {
$comment = substr($val, 9); // 9 - strlen(" COMMENT ")
queries("EXEC sp_dropextendedproperty @name = N'MS_Description', @level0type = N'Schema', @level0name = " . q(get_schema()) . ", @level1type = N'Table', @level1name = " . q($name) . ", @level2type = N'Column', @level2name = " . q($key));
queries("EXEC sp_addextendedproperty @name = N'MS_Description', @value = " . $comment . ", @level0type = N'Schema', @level0name = " . q(get_schema()) . ", @level1type = N'Table', @level1name = " . q($name) . ", @level2type = N'Column', @level2name = " . q($key));
queries("EXEC sp_addextendedproperty
@name = N'MS_Description',
@value = $comment,
@level0type = N'Schema',
@level0name = " . q(get_schema()) . ",
@level1type = N'Table',
@level1name = " . q($name) . ",
@level2type = N'Column',
@level2name = " . q($key))
;
}
return true;
}
@@ -541,8 +548,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
}
function last_id() {
global $connection;
return $connection->result("SELECT SCOPE_IDENTITY()"); // @@IDENTITY can return trigger INSERT
return get_val("SELECT SCOPE_IDENTITY()"); // @@IDENTITY can return trigger INSERT
}
function explain($connection, $query) {
@@ -635,11 +641,10 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)) as $row
}
function get_schema() {
global $connection;
if ($_GET["ns"] != "") {
return $_GET["ns"];
}
return $connection->result("SELECT SCHEMA_NAME()");
return get_val("SELECT SCHEMA_NAME()");
}
function set_schema($schema) {

View File

@@ -8,7 +8,7 @@ if (!defined('Adminer\DRIVER')) {
// MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable
if (extension_loaded("mysqli")) {
class Db extends \MySQLi {
var $extension = "MySQLi";
public $extension = "MySQLi";
function __construct() {
parent::init();
@@ -60,14 +60,14 @@ if (!defined('Adminer\DRIVER')) {
} elseif (extension_loaded("mysql") && !((ini_bool("sql.safe_mode") || ini_bool("mysql.allow_local_infile")) && extension_loaded("pdo_mysql"))) {
class Db {
var
public
$extension = "MySQL", ///< @var string extension name
$server_info, ///< @var string server version
$affected_rows, ///< @var int number of affected rows
$errno, ///< @var int last error code
$error, ///< @var string last error message
$_link, $_result ///< @access private
$error ///< @var string last error message
;
private $link, $result;
/** Connect to server
* @param string
@@ -80,19 +80,19 @@ if (!defined('Adminer\DRIVER')) {
$this->error = lang('Disable %s or enable %s or %s extensions.', "'mysql.allow_local_infile'", "MySQLi", "PDO_MySQL");
return false;
}
$this->_link = @mysql_connect(
$this->link = @mysql_connect(
($server != "" ? $server : ini_get("mysql.default_host")),
("$server$username" != "" ? $username : ini_get("mysql.default_user")),
("$server$username$password" != "" ? $password : ini_get("mysql.default_password")),
true,
131072 // CLIENT_MULTI_RESULTS for CALL
);
if ($this->_link) {
$this->server_info = mysql_get_server_info($this->_link);
if ($this->link) {
$this->server_info = mysql_get_server_info($this->link);
} else {
$this->error = mysql_error();
}
return (bool) $this->_link;
return (bool) $this->link;
}
/** Sets the client character set
@@ -101,11 +101,11 @@ if (!defined('Adminer\DRIVER')) {
*/
function set_charset($charset) {
if (function_exists('mysql_set_charset')) {
if (mysql_set_charset($charset, $this->_link)) {
if (mysql_set_charset($charset, $this->link)) {
return true;
}
// the client library may not support utf8mb4
mysql_set_charset('utf8', $this->_link);
mysql_set_charset('utf8', $this->link);
}
return $this->query("SET NAMES $charset");
}
@@ -115,7 +115,7 @@ if (!defined('Adminer\DRIVER')) {
* @return string escaped string enclosed in '
*/
function quote($string) {
return "'" . mysql_real_escape_string($string, $this->_link) . "'";
return "'" . mysql_real_escape_string($string, $this->link) . "'";
}
/** Select database
@@ -123,7 +123,7 @@ if (!defined('Adminer\DRIVER')) {
* @return bool
*/
function select_db($database) {
return mysql_select_db($database, $this->_link);
return mysql_select_db($database, $this->link);
}
/** Send query
@@ -132,16 +132,16 @@ if (!defined('Adminer\DRIVER')) {
* @return mixed bool or Result
*/
function query($query, $unbuffered = false) {
$result = @($unbuffered ? mysql_unbuffered_query($query, $this->_link) : mysql_query($query, $this->_link)); // @ - mute mysql.trace_mode
$result = @($unbuffered ? mysql_unbuffered_query($query, $this->link) : mysql_query($query, $this->link)); // @ - mute mysql.trace_mode
$this->error = "";
if (!$result) {
$this->errno = mysql_errno($this->_link);
$this->error = mysql_error($this->_link);
$this->errno = mysql_errno($this->link);
$this->error = mysql_error($this->link);
return false;
}
if ($result === true) {
$this->affected_rows = mysql_affected_rows($this->_link);
$this->info = mysql_info($this->_link);
$this->affected_rows = mysql_affected_rows($this->link);
$this->info = mysql_info($this->link);
return true;
}
return new Result($result);
@@ -152,14 +152,14 @@ if (!defined('Adminer\DRIVER')) {
* @return bool
*/
function multi_query($query) {
return $this->_result = $this->query($query);
return $this->result = $this->query($query);
}
/** Get current resultset
* @return Result
*/
function store_result() {
return $this->_result;
return $this->result;
}
/** Fetch next resultset
@@ -177,24 +177,19 @@ if (!defined('Adminer\DRIVER')) {
*/
function result($query, $field = 0) {
$result = $this->query($query);
if (!$result || !$result->num_rows) {
return false;
}
return mysql_result($result->_result, 0, $field);
return ($result ? $result->fetch_column($field) : false);
}
}
class Result {
var
$num_rows, ///< @var int number of rows in the result
$_result, $_offset = 0 ///< @access private
;
public $num_rows; ///< @var int number of rows in the result
private $result, $offset = 0;
/** Constructor
* @param resource
*/
function __construct($result) {
$this->_result = $result;
$this->result = $result;
$this->num_rows = mysql_num_rows($result);
}
@@ -202,21 +197,29 @@ if (!defined('Adminer\DRIVER')) {
* @return array
*/
function fetch_assoc() {
return mysql_fetch_assoc($this->_result);
return mysql_fetch_assoc($this->result);
}
/** Fetch next row as numbered array
* @return array
*/
function fetch_row() {
return mysql_fetch_row($this->_result);
return mysql_fetch_row($this->result);
}
/** Fetch a single column
* @param int
* @return string or false if there are no rows
*/
function fetch_column($field) {
return ($this->num_rows ? mysql_result($this->result, 0, $field) : false);
}
/** Fetch next field
* @return object properties: name, type, orgtable, orgname, charsetnr
*/
function fetch_field() {
$return = mysql_fetch_field($this->_result, $this->_offset++); // offset required under certain conditions
$return = mysql_fetch_field($this->result, $this->offset++); // offset required under certain conditions
$return->orgtable = $return->table;
$return->orgname = $return->name;
$return->charsetnr = ($return->blob ? 63 : 0);
@@ -226,13 +229,13 @@ if (!defined('Adminer\DRIVER')) {
/** Free result set
*/
function __destruct() {
mysql_free_result($this->_result);
mysql_free_result($this->result);
}
}
} elseif (extension_loaded("pdo_mysql")) {
class Db extends PdoDb {
var $extension = "PDO_MySQL";
public $extension = "PDO_MySQL";
function connect($server, $username, $password) {
global $adminer;
@@ -284,10 +287,10 @@ if (!defined('Adminer\DRIVER')) {
static $possibleDrivers = array("MySQLi", "MySQL", "PDO_MySQL");
static $jush = "sql"; ///< @var string JUSH identifier
var $unsigned = array("unsigned", "zerofill", "unsigned zerofill");
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "FIND_IN_SET", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL");
var $functions = array("char_length", "date", "from_unixtime", "lower", "round", "floor", "ceil", "sec_to_time", "time_to_sec", "upper");
var $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
public $unsigned = array("unsigned", "zerofill", "unsigned zerofill");
public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "FIND_IN_SET", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL");
public $functions = array("char_length", "date", "from_unixtime", "lower", "round", "floor", "ceil", "sec_to_time", "time_to_sec", "upper");
public $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
function __construct($connection) {
parent::__construct($connection);
@@ -327,6 +330,13 @@ if (!defined('Adminer\DRIVER')) {
}
}
function unconvertFunction($field) {
return (preg_match("~binary~", $field["type"]) ? "<code class='jush-sql'>UNHEX</code>"
: ($field["type"] == "bit" ? doc_link(array('sql' => 'bit-value-literals.html'), "<code>b''</code>")
: (preg_match("~geometry|point|linestring|polygon~", $field["type"]) ? "<code class='jush-sql'>GeomFromText</code>"
: "")));
}
function insert($table, $set) {
return ($set ? parent::insert($table, $set) : queries("INSERT INTO " . table($table) . " ()\nVALUES ()"));
}
@@ -358,7 +368,7 @@ if (!defined('Adminer\DRIVER')) {
function slowQuery($query, $timeout) {
if (min_version('5.7.8', '10.1.2')) {
if (preg_match('~MariaDB~', $this->_conn->server_info)) {
if ($this->conn->maria) {
return "SET STATEMENT max_statement_time=$timeout FOR $query";
} elseif (preg_match('~^(SELECT\b)(.+)~is', $query, $match)) {
return "$match[1] /*+ MAX_EXECUTION_TIME(" . ($timeout * 1000) . ") */ $match[2]";
@@ -368,13 +378,13 @@ if (!defined('Adminer\DRIVER')) {
function convertSearch($idf, $val, $field) {
return (preg_match('~char|text|enum|set~', $field["type"]) && !preg_match("~^utf8~", $field["collation"]) && preg_match('~[\x80-\xFF]~', $val['val'])
? "CONVERT($idf USING " . charset($this->_conn) . ")"
? "CONVERT($idf USING " . charset($this->conn) . ")"
: $idf
);
}
function warnings() {
$result = $this->_conn->query("SHOW WARNINGS");
$result = $this->conn->query("SHOW WARNINGS");
if ($result && $result->num_rows) {
ob_start();
select($result); // select() usually needs to print a big table progressively
@@ -383,7 +393,7 @@ if (!defined('Adminer\DRIVER')) {
}
function tableHelp($name, $is_view = false) {
$maria = preg_match('~MariaDB~', $this->_conn->server_info);
$maria = $this->conn->maria;
if (information_schema(DB)) {
return strtolower("information-schema-" . ($maria ? "$name-table/" : str_replace("_", "-", $name) . "-table.html"));
}
@@ -395,7 +405,7 @@ if (!defined('Adminer\DRIVER')) {
function hasCStyleEscapes() {
static $c_style;
if ($c_style === null) {
$sql_mode = $this->_conn->result("SHOW VARIABLES LIKE 'sql_mode'", 1);
$sql_mode = $this->conn->result("SHOW VARIABLES LIKE 'sql_mode'", 1);
$c_style = (strpos($sql_mode, 'NO_BACKSLASH_ESCAPES') === false);
}
return $c_style;
@@ -429,6 +439,7 @@ if (!defined('Adminer\DRIVER')) {
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
$connection->set_charset(charset($connection)); // available in MySQLi since PHP 5.0.5
$connection->query("SET sql_quote_show_create = 1, autocommit = 1");
$connection->maria = preg_match('~MariaDB~', $connection->server_info);
return $connection;
}
$return = $connection->error;
@@ -484,9 +495,8 @@ if (!defined('Adminer\DRIVER')) {
* @return string
*/
function db_collation($db, $collations) {
global $connection;
$return = null;
$create = $connection->result("SHOW CREATE DATABASE " . idf_escape($db), 1);
$create = get_val("SHOW CREATE DATABASE " . idf_escape($db), 1);
if (preg_match('~ COLLATE ([^ ]+)~', $create, $match)) {
$return = $match[1];
} elseif (preg_match('~ CHARACTER SET ([^ ]+)~', $create, $match)) {
@@ -513,8 +523,7 @@ if (!defined('Adminer\DRIVER')) {
* @return string
*/
function logged_user() {
global $connection;
return $connection->result("SELECT USER()");
return get_val("SELECT USER()");
}
/** Get tables list
@@ -586,36 +595,51 @@ if (!defined('Adminer\DRIVER')) {
/** Get information about fields
* @param string
* @return array [$name => ["field" => , "full_type" => , "type" => , "length" => , "unsigned" => , "default" => , "null" => , "auto_increment" => , "on_update" => , "collation" => , "privileges" => , "comment" => , "primary" => , "generated" => ]]
* @return array [$name => ["field" =>, "full_type" =>, "type" =>, "length" =>, "unsigned" =>, "default" =>, "null" =>, "auto_increment" =>, "on_update" =>, "collation" =>, "privileges" =>, "comment" =>, "primary" =>, "generated" =>]]
*/
function fields($table) {
global $connection;
$maria = $connection->maria;
$return = array();
foreach (get_rows("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . q($table) . " ORDER BY ORDINAL_POSITION") as $row) {
$field = $row["COLUMN_NAME"];
$default = $row["COLUMN_DEFAULT"];
$type = $row["COLUMN_TYPE"];
$generation = $row["GENERATION_EXPRESSION"];
$extra = $row["EXTRA"];
// https://mariadb.com/kb/en/library/show-columns/, https://github.com/vrana/adminer/pull/359#pullrequestreview-276677186
preg_match('~^(VIRTUAL|PERSISTENT|STORED)~', $extra, $generated);
preg_match('~^([^( ]+)(?:\((.+)\))?( unsigned)?( zerofill)?$~', $type, $match);
preg_match('~^([^( ]+)(?:\((.+)\))?( unsigned)?( zerofill)?$~', $type, $match_type);
$default = $row["COLUMN_DEFAULT"];
if ($default != "") {
$is_text = preg_match('~text|json~', $match_type[1]);
if (!$maria && $is_text) {
// default value a'b of text column is stored as _utf8mb4\'a\\\'b\' in MySQL
$default = preg_replace("~^(_\w+)?('.*')$~", '\2', stripslashes($default));
}
if ($maria || $is_text) {
$default = ($default == "NULL" ? null : preg_replace_callback("~^'(.*)'$~", function ($match) {
return stripslashes(str_replace("''", "'", $match[1]));
}, $default));
}
if (!$maria && preg_match('~binary~', $match_type[1]) && preg_match('~^0x(\w*)$~', $default, $match)) {
$default = pack("H*", $match[1]);
}
}
$return[$field] = array(
"field" => $field,
"full_type" => $type,
"type" => $match[1],
"length" => $match[2],
"unsigned" => ltrim($match[3] . $match[4]),
"type" => $match_type[1],
"length" => $match_type[2],
"unsigned" => ltrim($match_type[3] . $match_type[4]),
"default" => ($generated
? $row["GENERATION_EXPRESSION"]
: ($default != "" || preg_match("~char|set~", $match[1])
? (preg_match('~text~', $match[1]) ? stripslashes(preg_replace("~^'(.*)'\$~", '\1', $default)) : $default)
: null
)
? ($maria ? $generation : stripslashes($generation))
: $default
),
"null" => ($row["IS_NULLABLE"] == "YES"),
"auto_increment" => ($extra == "auto_increment"),
"on_update" => (preg_match('~\bon update (\w+)~i', $extra, $match) ? $match[1] : ""), //! available since MySQL 5.1.23
"collation" => $row["COLLATION_NAME"],
"privileges" => array_flip(explode(",", $row["PRIVILEGES"])),
"privileges" => array_flip(explode(",", "$row[PRIVILEGES],where,order")),
"comment" => $row["COLUMN_COMMENT"],
"primary" => ($row["COLUMN_KEY"] == "PRI"),
"generated" => ($generated[1] == "PERSISTENT" ? "STORED" : $generated[1]),
@@ -646,12 +670,17 @@ if (!defined('Adminer\DRIVER')) {
* @return array [$name => ["db" => , "ns" => , "table" => , "source" => [], "target" => [], "on_delete" => , "on_update" => ]]
*/
function foreign_keys($table) {
global $connection, $driver;
global $driver;
static $pattern = '(?:`(?:[^`]|``)+`|"(?:[^"]|"")+")';
$return = array();
$create_table = $connection->result("SHOW CREATE TABLE " . table($table), 1);
$create_table = get_val("SHOW CREATE TABLE " . table($table), 1);
if ($create_table) {
preg_match_all("~CONSTRAINT ($pattern) FOREIGN KEY ?\\(((?:$pattern,? ?)+)\\) REFERENCES ($pattern)(?:\\.($pattern))? \\(((?:$pattern,? ?)+)\\)(?: ON DELETE ($driver->onActions))?(?: ON UPDATE ($driver->onActions))?~", $create_table, $matches, PREG_SET_ORDER);
preg_match_all(
"~CONSTRAINT ($pattern) FOREIGN KEY ?\\(((?:$pattern,? ?)+)\\) REFERENCES ($pattern)(?:\\.($pattern))? \\(((?:$pattern,? ?)+)\\)(?: ON DELETE ($driver->onActions))?(?: ON UPDATE ($driver->onActions))?~",
$create_table,
$matches,
PREG_SET_ORDER
);
foreach ($matches as $match) {
preg_match_all("~$pattern~", $match[2], $source);
preg_match_all("~$pattern~", $match[5], $target);
@@ -673,8 +702,7 @@ if (!defined('Adminer\DRIVER')) {
* @return array ["select" => ]
*/
function view($name) {
global $connection;
return array("select" => preg_replace('~^(?:[^`]|`[^`]*`)*\s+AS\s+~isU', '', $connection->result("SHOW CREATE VIEW " . table($name), 1)));
return array("select" => preg_replace('~^(?:[^`]|`[^`]*`)*\s+AS\s+~isU', '', get_val("SHOW CREATE VIEW " . table($name), 1)));
}
/** Get sorted grouped list of collations
@@ -789,12 +817,14 @@ if (!defined('Adminer\DRIVER')) {
* @return bool
*/
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
global $connection;
$alter = array();
foreach ($fields as $field) {
if ($field[1]) {
$default = $field[1][3];
if (preg_match('~ GENERATED~', $default)) {
$field[1][3] = $field[1][2];
// swap default and null
$field[1][3] = ($connection->maria ? "" : $field[1][2]); // MariaDB doesn't support NULL on virtual columns
$field[1][2] = $default;
}
$alter[] = ($table != "" ? ($field[0] != "" ? "CHANGE " . idf_escape($field[0]) : "ADD") : " ") . " " . implode($field[1]) . ($table != "" ? $field[2] : "");
@@ -967,12 +997,14 @@ if (!defined('Adminer\DRIVER')) {
* @return array ["fields" => ["field" => , "type" => , "length" => , "unsigned" => , "inout" => , "collation" => ], "returns" => , "definition" => , "language" => ]
*/
function routine($name, $type) {
global $connection, $driver;
global $driver;
$aliases = array("bool", "boolean", "integer", "double precision", "real", "dec", "numeric", "fixed", "national char", "national varchar");
$space = "(?:\\s|/\\*[\s\S]*?\\*/|(?:#|-- )[^\n]*\n?|--\r?\n)";
$type_pattern = "((" . implode("|", array_merge(array_keys($driver->types()), $aliases)) . ")\\b(?:\\s*\\(((?:[^'\")]|$driver->enumLength)++)\\))?\\s*(zerofill\\s*)?(unsigned(?:\\s+zerofill)?)?)(?:\\s*(?:CHARSET|CHARACTER\\s+SET)\\s*['\"]?([^'\"\\s,]+)['\"]?)?";
$enum = $driver->enumLength;
$type_pattern = "((" . implode("|", array_merge(array_keys($driver->types()), $aliases)) . ")\\b(?:\\s*\\(((?:[^'\")]|$enum)++)\\))?"
. "\\s*(zerofill\\s*)?(unsigned(?:\\s+zerofill)?)?)(?:\\s*(?:CHARSET|CHARACTER\\s+SET)\\s*['\"]?([^'\"\\s,]+)['\"]?)?";
$pattern = "$space*(" . ($type == "FUNCTION" ? "" : $driver->inout) . ")?\\s*(?:`((?:[^`]|``)*)`\\s*|\\b(\\S+)\\s+)$type_pattern";
$create = $connection->result("SHOW CREATE $type " . idf_escape($name), 2);
$create = get_val("SHOW CREATE $type " . idf_escape($name), 2);
preg_match("~\\(((?:$pattern\\s*,?)*)\\)\\s*" . ($type == "FUNCTION" ? "RETURNS\\s+$type_pattern\\s+" : "") . "(.*)~is", $create, $match);
$fields = array();
preg_match_all("~$pattern\\s*,?~is", $match[1], $matches, PREG_SET_ORDER);
@@ -980,7 +1012,7 @@ if (!defined('Adminer\DRIVER')) {
$fields[] = array(
"field" => str_replace("``", "`", $param[2]) . $param[3],
"type" => strtolower($param[5]),
"length" => preg_replace_callback("~$driver->enumLength~s", 'Adminer\normalize_enum', $param[6]),
"length" => preg_replace_callback("~$enum~s", 'Adminer\normalize_enum', $param[6]),
"unsigned" => strtolower(preg_replace('~\s+~', ' ', trim("$param[8] $param[7]"))),
"null" => 1,
"full_type" => $param[4],
@@ -990,7 +1022,7 @@ if (!defined('Adminer\DRIVER')) {
}
return array(
"fields" => $fields,
"comment" => $connection->result("SELECT ROUTINE_COMMENT FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = DATABASE() AND ROUTINE_NAME = " . q($name)),
"comment" => get_val("SELECT ROUTINE_COMMENT FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = DATABASE() AND ROUTINE_NAME = " . q($name)),
) + ($type != "FUNCTION" ? array("definition" => $match[11]) : array(
"returns" => array("type" => $match[12], "length" => $match[13], "unsigned" => $match[15], "collation" => $match[16]),
"definition" => $match[17],
@@ -1025,8 +1057,7 @@ if (!defined('Adminer\DRIVER')) {
* @return string
*/
function last_id() {
global $connection;
return $connection->result("SELECT LAST_INSERT_ID()"); // mysql_insert_id() truncates bigint
return get_val("SELECT LAST_INSERT_ID()"); // mysql_insert_id() truncates bigint
}
/** Explain select
@@ -1089,8 +1120,7 @@ if (!defined('Adminer\DRIVER')) {
* @return string
*/
function create_sql($table, $auto_increment, $style) {
global $connection;
$return = $connection->result("SHOW CREATE TABLE " . table($table), 1);
$return = get_val("SHOW CREATE TABLE " . table($table), 1);
if (!$auto_increment) {
$return = preg_replace('~ AUTO_INCREMENT=\d+~', '', $return); //! skip comments
}
@@ -1164,7 +1194,7 @@ if (!defined('Adminer\DRIVER')) {
/** Convert value in edit after applying functions back
* @param array one element from fields()
* @param string
* @param string SQL expression
* @return string
*/
function unconvert_field($field, $return) {
@@ -1182,7 +1212,7 @@ if (!defined('Adminer\DRIVER')) {
}
/** Check whether a feature is supported
* @param string "check", "comment", "copy", "database", "descidx", "drop_col", "dump", "event", "indexes", "kill", "materializedview", "partitioning", "privileges", "procedure", "processlist", "routine", "scheme", "sequence", "status", "table", "trigger", "type", "variables", "view", "view_trigger"
* @param string "check|comment|copy|database|descidx|drop_col|dump|event|indexes|kill|materializedview|partitioning|privileges|procedure|processlist|routine|scheme|sequence|status|table|trigger|type|variables|view|view_trigger"
* @return bool
*/
function support($feature) {
@@ -1208,7 +1238,6 @@ if (!defined('Adminer\DRIVER')) {
* @return int
*/
function max_connections() {
global $connection;
return $connection->result("SELECT @@max_connections");
return get_val("SELECT @@max_connections");
}
}

View File

@@ -7,8 +7,9 @@ if (isset($_GET["oracle"])) {
define('Adminer\DRIVER', "oracle");
if (extension_loaded("oci8")) {
class Db {
var $extension = "oci8", $_link, $_result, $server_info, $affected_rows, $errno, $error;
var $_current_db;
public $extension = "oci8", $server_info, $affected_rows, $errno, $error;
public $_current_db;
private $link, $result;
function _error($errno, $error) {
if (ini_bool("html_errors")) {
@@ -19,9 +20,9 @@ if (isset($_GET["oracle"])) {
}
function connect($server, $username, $password) {
$this->_link = @oci_new_connect($username, $password, $server, "AL32UTF8");
if ($this->_link) {
$this->server_info = oci_server_version($this->_link);
$this->link = @oci_new_connect($username, $password, $server, "AL32UTF8");
if ($this->link) {
$this->server_info = oci_server_version($this->link);
return true;
}
$error = oci_error();
@@ -39,10 +40,10 @@ if (isset($_GET["oracle"])) {
}
function query($query, $unbuffered = false) {
$result = oci_parse($this->_link, $query);
$result = oci_parse($this->link, $query);
$this->error = "";
if (!$result) {
$error = oci_error($this->_link);
$error = oci_error($this->link);
$this->errno = $error["code"];
$this->error = $error["message"];
return false;
@@ -61,34 +62,32 @@ if (isset($_GET["oracle"])) {
}
function multi_query($query) {
return $this->_result = $this->query($query);
return $this->result = $this->query($query);
}
function store_result() {
return $this->_result;
return $this->result;
}
function next_result() {
return false;
}
function result($query, $field = 1) {
function result($query, $field = 0) {
$result = $this->query($query);
if (!is_object($result) || !oci_fetch($result->_result)) {
return false;
}
return oci_result($result->_result, $field);
return (is_object($result) ? $result->fetch_column($field) : false);
}
}
class Result {
var $_result, $_offset = 1, $num_rows;
public $num_rows;
private $result, $offset = 1;
function __construct($result) {
$this->_result = $result;
$this->result = $result;
}
function _convert($row) {
private function convert($row) {
foreach ((array) $row as $key => $val) {
if (is_a($val, 'OCI-Lob')) {
$row[$key] = $val->load();
@@ -98,32 +97,36 @@ if (isset($_GET["oracle"])) {
}
function fetch_assoc() {
return $this->_convert(oci_fetch_assoc($this->_result));
return $this->convert(oci_fetch_assoc($this->result));
}
function fetch_row() {
return $this->_convert(oci_fetch_row($this->_result));
return $this->convert(oci_fetch_row($this->result));
}
function fetch_column($field) {
return (oci_fetch($this->result) ? oci_result($this->result, $field + 1) : false);
}
function fetch_field() {
$column = $this->_offset++;
$column = $this->offset++;
$return = new \stdClass;
$return->name = oci_field_name($this->_result, $column);
$return->name = oci_field_name($this->result, $column);
$return->orgname = $return->name;
$return->type = oci_field_type($this->_result, $column);
$return->type = oci_field_type($this->result, $column);
$return->charsetnr = (preg_match("~raw|blob|bfile~", $return->type) ? 63 : 0); // 63 - binary
return $return;
}
function __destruct() {
oci_free_statement($this->_result);
oci_free_statement($this->result);
}
}
} elseif (extension_loaded("pdo_oci")) {
class Db extends PdoDb {
var $extension = "PDO_OCI";
var $_current_db;
public $extension = "PDO_OCI";
public $_current_db;
function connect($server, $username, $password) {
$this->dsn("oci:dbname=//$server;charset=AL32UTF8", $username, $password);
@@ -144,7 +147,7 @@ if (isset($_GET["oracle"])) {
static $possibleDrivers = array("OCI8", "PDO_OCI");
static $jush = "oracle";
var $editFunctions = array(
public $editFunctions = array(
array( //! no parentheses
"date" => "current_date",
"timestamp" => "current_timestamp",
@@ -155,9 +158,9 @@ if (isset($_GET["oracle"])) {
)
);
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL");
var $functions = array("length", "lower", "round", "upper");
var $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL");
public $functions = array("length", "lower", "round", "upper");
public $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
function __construct($connection) {
parent::__construct($connection);
@@ -241,8 +244,7 @@ ORDER BY 1"
}
function db_collation($db, $collations) {
global $connection;
return $connection->result("SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET'"); //! respect $db
return get_val("SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET'"); //! respect $db
}
function engines() {
@@ -250,8 +252,7 @@ ORDER BY 1"
}
function logged_user() {
global $connection;
return $connection->result("SELECT USER FROM DUAL");
return get_val("SELECT USER FROM DUAL");
}
function get_current_db() {
@@ -284,10 +285,9 @@ ORDER BY 1"
}
function count_tables($databases) {
global $connection;
$return = array();
foreach ($databases as $db) {
$return[$db] = $connection->result("SELECT COUNT(*) FROM all_tables WHERE tablespace_name = " . q($db));
$return[$db] = get_val("SELECT COUNT(*) FROM all_tables WHERE tablespace_name = " . q($db));
}
return $return;
}
@@ -337,7 +337,7 @@ ORDER BY 1") as $row
"null" => ($row["NULLABLE"] == "Y"),
//! "auto_increment" => false,
//! "collation" => $row["CHARACTER_SET_NAME"],
"privileges" => array("insert" => 1, "select" => 1, "update" => 1),
"privileges" => array("insert" => 1, "select" => 1, "update" => 1, "where" => 1, "order" => 1),
//! "comment" => $row["Comment"],
//! "primary" => ($row["Key"] == "PRI"),
);
@@ -505,8 +505,7 @@ AND c_src.TABLE_NAME = " . q($table);
}
function get_schema() {
global $connection;
return $connection->result("SELECT sys_context('USERENV', 'SESSION_USER') FROM dual");
return get_val("SELECT sys_context('USERENV', 'SESSION_USER') FROM dual");
}
function set_schema($scheme, $connection2 = null) {
@@ -522,7 +521,16 @@ AND c_src.TABLE_NAME = " . q($table);
}
function process_list() {
return get_rows('SELECT sess.process AS "process", sess.username AS "user", sess.schemaname AS "schema", sess.status AS "status", sess.wait_class AS "wait_class", sess.seconds_in_wait AS "seconds_in_wait", sql.sql_text AS "sql_text", sess.machine AS "machine", sess.port AS "port"
return get_rows('SELECT
sess.process AS "process",
sess.username AS "user",
sess.schemaname AS "schema",
sess.status AS "status",
sess.wait_class AS "wait_class",
sess.seconds_in_wait AS "seconds_in_wait",
sql.sql_text AS "sql_text",
sess.machine AS "machine",
sess.port AS "port"
FROM v$session sess LEFT OUTER JOIN v$sql sql
ON sql.sql_id = sess.sql_id
WHERE sess.type = \'USER\'

View File

@@ -7,7 +7,8 @@ if (isset($_GET["pgsql"])) {
define('Adminer\DRIVER', "pgsql");
if (extension_loaded("pgsql")) {
class Db {
var $extension = "PgSQL", $_link, $_result, $_string, $_database = true, $server_info, $affected_rows, $error, $timeout;
public $extension = "PgSQL", $server_info, $affected_rows, $error, $timeout;
private $link, $result, $string, $database = true;
function _error($errno, $error) {
if (ini_bool("html_errors")) {
@@ -21,59 +22,58 @@ if (isset($_GET["pgsql"])) {
global $adminer;
$db = $adminer->database();
set_error_handler(array($this, '_error'));
$this->_string = "host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' user='" . addcslashes($username, "'\\") . "' password='" . addcslashes($password, "'\\") . "'";
$this->string = "host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' user='" . addcslashes($username, "'\\") . "' password='" . addcslashes($password, "'\\") . "'";
$ssl = $adminer->connectSsl();
if (isset($ssl["mode"])) {
$this->_string .= " sslmode='" . $ssl["mode"] . "'";
$this->string .= " sslmode='" . $ssl["mode"] . "'";
}
$this->_link = @pg_connect("$this->_string dbname='" . ($db != "" ? addcslashes($db, "'\\") : "postgres") . "'", PGSQL_CONNECT_FORCE_NEW);
if (!$this->_link && $db != "") {
$this->link = @pg_connect("$this->string dbname='" . ($db != "" ? addcslashes($db, "'\\") : "postgres") . "'", PGSQL_CONNECT_FORCE_NEW);
if (!$this->link && $db != "") {
// try to connect directly with database for performance
$this->_database = false;
$this->_link = @pg_connect("$this->_string dbname='postgres'", PGSQL_CONNECT_FORCE_NEW);
$this->database = false;
$this->link = @pg_connect("$this->string dbname='postgres'", PGSQL_CONNECT_FORCE_NEW);
}
restore_error_handler();
if ($this->_link) {
$version = pg_version($this->_link);
if ($this->link) {
$version = pg_version($this->link);
$this->server_info = $version["server"];
pg_set_client_encoding($this->_link, "UTF8");
pg_set_client_encoding($this->link, "UTF8");
}
return (bool) $this->_link;
return (bool) $this->link;
}
function quote($string) {
return pg_escape_literal($this->_link, $string);
return (function_exists('pg_escape_literal')
? pg_escape_literal($this->link, $string) // available since PHP 5.4.4
: "'" . pg_escape_string($this->link, $string) . "'"
);
}
function value($val, $field) {
return ($field["type"] == "bytea" && $val !== null ? pg_unescape_bytea($val) : $val);
}
function quoteBinary($string) {
return "'" . pg_escape_bytea($this->_link, $string) . "'";
}
function select_db($database) {
global $adminer;
if ($database == $adminer->database()) {
return $this->_database;
return $this->database;
}
$return = @pg_connect("$this->_string dbname='" . addcslashes($database, "'\\") . "'", PGSQL_CONNECT_FORCE_NEW);
$return = @pg_connect("$this->string dbname='" . addcslashes($database, "'\\") . "'", PGSQL_CONNECT_FORCE_NEW);
if ($return) {
$this->_link = $return;
$this->link = $return;
}
return $return;
}
function close() {
$this->_link = @pg_connect("$this->_string dbname='postgres'");
$this->link = @pg_connect("$this->string dbname='postgres'");
}
function query($query, $unbuffered = false) {
$result = @pg_query($this->_link, $query);
$result = @pg_query($this->link, $query);
$this->error = "";
if (!$result) {
$this->error = pg_last_error($this->_link);
$this->error = pg_last_error($this->link);
$return = false;
} elseif (!pg_num_fields($result)) {
$this->affected_rows = pg_affected_rows($result);
@@ -89,11 +89,11 @@ if (isset($_GET["pgsql"])) {
}
function multi_query($query) {
return $this->_result = $this->query($query);
return $this->result = $this->query($query);
}
function store_result() {
return $this->_result;
return $this->result;
}
function next_result() {
@@ -103,54 +103,56 @@ if (isset($_GET["pgsql"])) {
function result($query, $field = 0) {
$result = $this->query($query);
if (!$result || !$result->num_rows) {
return false;
}
return pg_fetch_result($result->_result, 0, $field);
return ($result ? $result->fetch_column($field) : false);
}
function warnings() {
return h(pg_last_notice($this->_link)); // second parameter is available since PHP 7.1.0
return h(pg_last_notice($this->link)); // second parameter is available since PHP 7.1.0
}
}
class Result {
var $_result, $_offset = 0, $num_rows;
public $num_rows;
private $result, $offset = 0;
function __construct($result) {
$this->_result = $result;
$this->result = $result;
$this->num_rows = pg_num_rows($result);
}
function fetch_assoc() {
return pg_fetch_assoc($this->_result);
return pg_fetch_assoc($this->result);
}
function fetch_row() {
return pg_fetch_row($this->_result);
return pg_fetch_row($this->result);
}
function fetch_column($field) {
return ($this->num_rows ? pg_fetch_result($this->result, 0, $field) : false);
}
function fetch_field() {
$column = $this->_offset++;
$column = $this->offset++;
$return = new \stdClass;
if (function_exists('pg_field_table')) {
$return->orgtable = pg_field_table($this->_result, $column);
$return->orgtable = pg_field_table($this->result, $column);
}
$return->name = pg_field_name($this->_result, $column);
$return->name = pg_field_name($this->result, $column);
$return->orgname = $return->name;
$return->type = pg_field_type($this->_result, $column);
$return->type = pg_field_type($this->result, $column);
$return->charsetnr = ($return->type == "bytea" ? 63 : 0); // 63 - binary
return $return;
}
function __destruct() {
pg_free_result($this->_result);
pg_free_result($this->result);
}
}
} elseif (extension_loaded("pdo_pgsql")) {
class Db extends PdoDb {
var $extension = "PDO_PgSQL", $timeout;
public $extension = "PDO_PgSQL", $timeout;
function connect($server, $username, $password) {
global $adminer;
@@ -170,10 +172,6 @@ if (isset($_GET["pgsql"])) {
return ($adminer->database() == $database);
}
function quoteBinary($s) {
return q($s);
}
function query($query, $unbuffered = false) {
$return = parent::query($query, $unbuffered);
if ($this->timeout) {
@@ -199,9 +197,9 @@ if (isset($_GET["pgsql"])) {
static $possibleDrivers = array("PgSQL", "PDO_PgSQL");
static $jush = "pgsql";
var $operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "ILIKE", "ILIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"); // no "SQL" to avoid CSRF
var $functions = array("char_length", "lower", "round", "to_hex", "to_timestamp", "upper");
var $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
public $operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "ILIKE", "ILIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"); // no "SQL" to avoid CSRF
public $functions = array("char_length", "lower", "round", "to_hex", "to_timestamp", "upper");
public $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
function __construct($connection) {
parent::__construct($connection);
@@ -234,6 +232,11 @@ if (isset($_GET["pgsql"])) {
}
}
function enumLength($field) {
$enum = $this->types[lang('User types')][$field["type"]];
return ($enum ? type_values($enum) : "");
}
function setUserTypes($types) {
$this->types[lang('User types')] = array_flip($types);
}
@@ -260,8 +263,8 @@ if (isset($_GET["pgsql"])) {
}
function slowQuery($query, $timeout) {
$this->_conn->query("SET statement_timeout = " . (1000 * $timeout));
$this->_conn->timeout = 1000 * $timeout;
$this->conn->query("SET statement_timeout = " . (1000 * $timeout));
$this->conn->timeout = 1000 * $timeout;
return $query;
}
@@ -275,11 +278,11 @@ if (isset($_GET["pgsql"])) {
}
function quoteBinary($s) {
return $this->_conn->quoteBinary($s);
return "'\\x" . bin2hex($s) . "'"; // available since PostgreSQL 8.1
}
function warnings() {
return $this->_conn->warnings();
return $this->conn->warnings();
}
function tableHelp($name, $is_view = false) {
@@ -294,13 +297,14 @@ if (isset($_GET["pgsql"])) {
}
function supportsIndex($table_status) {
// returns true for "materialized view"
return $table_status["Engine"] != "view";
}
function hasCStyleEscapes() {
static $c_style;
if ($c_style === null) {
$c_style = ($this->_conn->result("SHOW standard_conforming_strings") == "off");
$c_style = ($this->conn->result("SHOW standard_conforming_strings") == "off");
}
return $c_style;
}
@@ -322,6 +326,8 @@ if (isset($_GET["pgsql"])) {
if (min_version(9, 0, $connection)) {
$connection->query("SET application_name = 'Adminer'");
}
$crdb_version = $connection->result("SHOW crdb_version");
$connection->server_info .= ($crdb_version ? "-" . preg_replace('~ \(.*~', '', $crdb_version) : "");
return $connection;
}
return $connection->error;
@@ -345,8 +351,7 @@ ORDER BY datname");
}
function db_collation($db, $collations) {
global $connection;
return $connection->result("SELECT datcollate FROM pg_database WHERE datname = " . q($db));
return get_val("SELECT datcollate FROM pg_database WHERE datname = " . q($db));
}
function engines() {
@@ -354,8 +359,7 @@ ORDER BY datname");
}
function logged_user() {
global $connection;
return $connection->result("SELECT user");
return get_val("SELECT user");
}
function tables_list() {
@@ -384,13 +388,18 @@ ORDER BY 1";
}
function table_status($name = "") {
static $has_size;
if ($has_size === null) {
// https://github.com/cockroachdb/cockroach/issues/40391
$has_size = get_val("SELECT 'pg_table_size'::regproc");
}
$return = array();
foreach (
get_rows("SELECT
c.relname AS \"Name\",
CASE c.relkind WHEN 'r' THEN 'table' WHEN 'm' THEN 'materialized view' ELSE 'view' END AS \"Engine\",
CASE c.relkind WHEN 'r' THEN 'table' WHEN 'm' THEN 'materialized view' ELSE 'view' END AS \"Engine\"" . ($has_size ? ",
pg_table_size(c.oid) AS \"Data_length\",
pg_indexes_size(c.oid) AS \"Index_length\",
pg_indexes_size(c.oid) AS \"Index_length\"" : "") . ",
obj_description(c.oid, 'pg_class') AS \"Comment\",
" . (min_version(12) ? "''" : "CASE WHEN c.relhasoids THEN 'oid' ELSE '' END") . " AS \"Oid\",
c.reltuples as \"Rows\",
@@ -420,7 +429,14 @@ WHERE relkind IN ('r', 'm', 'v', 'f', 'p')
'timestamp with time zone' => 'timestamptz',
);
foreach (
get_rows("SELECT a.attname AS field, format_type(a.atttypid, a.atttypmod) AS full_type, pg_get_expr(d.adbin, d.adrelid) AS default, a.attnotnull::int, col_description(c.oid, a.attnum) AS comment" . (min_version(10) ? ", a.attidentity" . (min_version(12) ? ", a.attgenerated" : "") : "") . "
get_rows("SELECT
a.attname AS field,
format_type(a.atttypid, a.atttypmod) AS full_type,
pg_get_expr(d.adbin, d.adrelid) AS default,
a.attnotnull::int,
col_description(c.oid, a.attnum) AS comment" . (min_version(10) ? ",
a.attidentity" . (min_version(12) ? ",
a.attgenerated" : "") : "") . "
FROM pg_class c
JOIN pg_namespace n ON c.relnamespace = n.oid
JOIN pg_attribute a ON c.oid = a.attrelid
@@ -448,8 +464,9 @@ ORDER BY a.attnum") as $row
}
$row["generated"] = ($row["attgenerated"] == "s" ? "STORED" : "");
$row["null"] = !$row["attnotnull"];
$row["auto_increment"] = $row['attidentity'] || preg_match('~^nextval\(~i', $row["default"]);
$row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1);
$row["auto_increment"] = $row['attidentity'] || preg_match('~^nextval\(~i', $row["default"])
|| preg_match('~^unique_rowid\(~', $row["default"]); // CockroachDB
$row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1, "where" => 1, "order" => 1);
if (preg_match('~(.+)::[^,)]+(.*)~', $row["default"], $match)) {
$row["default"] = ($match[1] == "NULL" ? null : idf_unescape($match[1]) . $match[2]);
}
@@ -466,7 +483,12 @@ ORDER BY a.attnum") as $row
$return = array();
$table_oid = $connection2->result("SELECT oid FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema()) AND relname = " . q($table));
$columns = get_key_vals("SELECT attnum, attname FROM pg_attribute WHERE attrelid = $table_oid AND attnum > 0", $connection2);
foreach (get_rows("SELECT relname, indisunique::int, indisprimary::int, indkey, indoption, (indpred IS NOT NULL)::int as indispartial FROM pg_index i, pg_class ci WHERE i.indrelid = $table_oid AND ci.oid = i.indexrelid ORDER BY indisprimary DESC, indisunique DESC", $connection2) as $row) {
foreach (
get_rows("SELECT relname, indisunique::int, indisprimary::int, indkey, indoption, (indpred IS NOT NULL)::int as indispartial
FROM pg_index i, pg_class ci
WHERE i.indrelid = $table_oid AND ci.oid = i.indexrelid
ORDER BY indisprimary DESC, indisunique DESC", $connection2) as $row
) {
$relname = $row["relname"];
$return[$relname]["type"] = ($row["indispartial"] ? "INDEX" : ($row["indisprimary"] ? "PRIMARY" : ($row["indisunique"] ? "UNIQUE" : "INDEX")));
$return[$relname]["columns"] = array();
@@ -510,8 +532,7 @@ ORDER BY conkey, conname") as $row
}
function view($name) {
global $connection;
return array("select" => trim($connection->result("SELECT pg_get_viewdef(" . $connection->result("SELECT oid FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema()) AND relname = " . q($name)) . ")")));
return array("select" => trim(get_val("SELECT pg_get_viewdef(" . get_val("SELECT oid FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema()) AND relname = " . q($name)) . ")")));
}
function collations() {
@@ -651,7 +672,6 @@ ORDER BY conkey, conname") as $row
function truncate_tables($tables) {
return queries("TRUNCATE " . implode(", ", array_map('Adminer\table', $tables)));
return true;
}
function drop_views($views) {
@@ -688,7 +708,12 @@ ORDER BY conkey, conname") as $row
$columns[] = $row["event_object_column"];
}
$return = array();
foreach (get_rows('SELECT trigger_name AS "Trigger", action_timing AS "Timing", event_manipulation AS "Event", \'FOR EACH \' || action_orientation AS "Type", action_statement AS "Statement" FROM information_schema.triggers ' . "$where ORDER BY event_manipulation DESC") as $row) {
foreach (
get_rows('SELECT trigger_name AS "Trigger", action_timing AS "Timing", event_manipulation AS "Event", \'FOR EACH \' || action_orientation AS "Type", action_statement AS "Statement"
FROM information_schema.triggers' . "
$where
ORDER BY event_manipulation DESC") as $row
) {
if ($columns && $row["Event"] == "UPDATE") {
$row["Event"] .= " OF";
}
@@ -759,8 +784,7 @@ ORDER BY SPECIFIC_NAME');
}
function found_rows($table_status, $where) {
global $connection;
if (preg_match("~ rows=([0-9]+)~", $connection->result("EXPLAIN SELECT * FROM " . idf_escape($table_status["Name"]) . ($where ? " WHERE " . implode(" AND ", $where) : "")), $regs)) {
if (preg_match("~ rows=([0-9]+)~", get_val("EXPLAIN SELECT * FROM " . idf_escape($table_status["Name"]) . ($where ? " WHERE " . implode(" AND ", $where) : "")), $regs)) {
return $regs[1];
}
return false;
@@ -787,8 +811,7 @@ AND typelem = 0"
}
function get_schema() {
global $connection;
return $connection->result("SELECT current_schema()");
return get_val("SELECT current_schema()");
}
function set_schema($schema, $connection2 = null) {
@@ -930,7 +953,11 @@ AND typelem = 0"
}
function support($feature) {
return preg_match('~^(check|database|table|columns|sql|indexes|descidx|comment|view|' . (min_version(9.3) ? 'materializedview|' : '') . 'scheme|routine|processlist|sequence|trigger|type|variables|drop_col|kill|dump)$~', $feature);
global $connection;
return ($feature == "processlist"
? !preg_match('~CockroachDB~', $connection->server_info) // https://github.com/cockroachdb/cockroach/issues/24745
: preg_match('~^(check|database|table|columns|sql|indexes|descidx|comment|view|' . (min_version(9.3) ? 'materializedview|' : '') . 'scheme|routine|sequence|trigger|type|variables|drop_col|kill|dump)$~', $feature)
);
}
function kill_process($val) {
@@ -942,7 +969,6 @@ AND typelem = 0"
}
function max_connections() {
global $connection;
return $connection->result("SHOW max_connections");
return get_val("SHOW max_connections");
}
}

View File

@@ -8,37 +8,38 @@ if (isset($_GET["sqlite"])) {
if (class_exists("SQLite3")) {
class SqliteDb {
var $extension = "SQLite3", $server_info, $affected_rows, $errno, $error, $_link;
public $extension = "SQLite3", $server_info, $affected_rows, $errno, $error;
private $link;
function __construct($filename) {
$this->_link = new \SQLite3($filename);
$version = $this->_link->version();
$this->link = new \SQLite3($filename);
$version = $this->link->version();
$this->server_info = $version["versionString"];
}
function query($query) {
$result = @$this->_link->query($query);
$result = @$this->link->query($query);
$this->error = "";
if (!$result) {
$this->errno = $this->_link->lastErrorCode();
$this->error = $this->_link->lastErrorMsg();
$this->errno = $this->link->lastErrorCode();
$this->error = $this->link->lastErrorMsg();
return false;
} elseif ($result->numColumns()) {
return new Result($result);
}
$this->affected_rows = $this->_link->changes();
$this->affected_rows = $this->link->changes();
return true;
}
function quote($string) {
return (is_utf8($string)
? "'" . $this->_link->escapeString($string) . "'"
? "'" . $this->link->escapeString($string) . "'"
: "x'" . reset(unpack('H*', $string)) . "'"
);
}
function store_result() {
return $this->_result;
return $this->result;
}
function result($query, $field = 0) {
@@ -46,44 +47,45 @@ if (isset($_GET["sqlite"])) {
if (!is_object($result)) {
return false;
}
$row = $result->_result->fetchArray();
$row = $result->fetch_row();
return $row ? $row[$field] : false;
}
}
class Result {
var $_result, $_offset = 0, $num_rows;
public $num_rows;
private $result, $offset = 0;
function __construct($result) {
$this->_result = $result;
$this->result = $result;
}
function fetch_assoc() {
return $this->_result->fetchArray(SQLITE3_ASSOC);
return $this->result->fetchArray(SQLITE3_ASSOC);
}
function fetch_row() {
return $this->_result->fetchArray(SQLITE3_NUM);
return $this->result->fetchArray(SQLITE3_NUM);
}
function fetch_field() {
$column = $this->_offset++;
$type = $this->_result->columnType($column);
$column = $this->offset++;
$type = $this->result->columnType($column);
return (object) array(
"name" => $this->_result->columnName($column),
"name" => $this->result->columnName($column),
"type" => $type,
"charsetnr" => ($type == SQLITE3_BLOB ? 63 : 0), // 63 - binary
);
}
function __desctruct() {
return $this->_result->finalize();
function __destruct() {
return $this->result->finalize();
}
}
} elseif (extension_loaded("pdo_sqlite")) {
class SqliteDb extends PdoDb {
var $extension = "PDO_SQLite";
public $extension = "PDO_SQLite";
function __construct($filename) {
$this->dsn(DRIVER . ":$filename", "", "");
@@ -115,7 +117,7 @@ if (isset($_GET["sqlite"])) {
}
function multi_query($query) {
return $this->_result = $this->query($query);
return $this->result = $this->query($query);
}
function next_result() {
@@ -132,7 +134,7 @@ if (isset($_GET["sqlite"])) {
protected $types = array(array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0));
var $editFunctions = array(
public $editFunctions = array(
array(
// "text" => "date('now')/time('now')/datetime('now')",
), array(
@@ -142,9 +144,9 @@ if (isset($_GET["sqlite"])) {
)
);
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"); // REGEXP can be user defined function
var $functions = array("hex", "length", "lower", "round", "unixepoch", "upper");
var $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"); // REGEXP can be user defined function
public $functions = array("hex", "length", "lower", "round", "unixepoch", "upper");
public $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
function __construct($connection) {
parent::__construct($connection);
@@ -175,7 +177,7 @@ if (isset($_GET["sqlite"])) {
}
function checkConstraints($table) {
preg_match_all('~ CHECK *(\( *(((?>[^()]*[^() ])|(?1))*) *\))~', $this->_conn->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table)), $matches); //! could be inside a comment
preg_match_all('~ CHECK *(\( *(((?>[^()]*[^() ])|(?1))*) *\))~', $this->conn->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table)), $matches); //! could be inside a comment
return array_combine($matches[2], $matches[2]);
}
}
@@ -207,16 +209,14 @@ if (isset($_GET["sqlite"])) {
}
function limit1($table, $query, $where, $separator = "\n") {
global $connection;
return (preg_match('~^INTO~', $query) || $connection->result("SELECT sqlite_compileoption_used('ENABLE_UPDATE_DELETE_LIMIT')")
return (preg_match('~^INTO~', $query) || get_val("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
return get_val("PRAGMA encoding"); // there is no database list so $db == DB
}
function engines() {
@@ -236,10 +236,9 @@ if (isset($_GET["sqlite"])) {
}
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"]));
$row["Rows"] = get_val("SELECT COUNT(*) FROM " . idf_escape($row["Name"]));
$return[$row["Name"]] = $row;
}
foreach (get_rows("SELECT * FROM sqlite_sequence", null, "") as $row) {
@@ -253,12 +252,10 @@ if (isset($_GET["sqlite"])) {
}
function fk_support($table_status) {
global $connection;
return !$connection->result("SELECT sqlite_compileoption_used('OMIT_FOREIGN_KEY')");
return !get_val("SELECT sqlite_compileoption_used('OMIT_FOREIGN_KEY')");
}
function fields($table) {
global $connection;
$return = array();
$primary = "";
foreach (get_rows("PRAGMA table_" . (min_version(3.31) ? "x" : "") . "info(" . table($table) . ")") as $row) {
@@ -271,7 +268,7 @@ if (isset($_GET["sqlite"])) {
"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),
"privileges" => array("select" => 1, "insert" => 1, "update" => 1, "where" => 1, "order" => 1),
"primary" => $row["pk"],
);
if ($row["pk"]) {
@@ -283,7 +280,7 @@ if (isset($_GET["sqlite"])) {
$primary = $name;
}
}
$sql = $connection->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table));
$sql = get_val("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table));
$idf = '(("[^"]*+")+|[a-z0-9_]+)';
preg_match_all('~' . $idf . '\s+text\s+COLLATE\s+(\'[^\']+\'|\S+)~i', $sql, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
@@ -362,8 +359,7 @@ if (isset($_GET["sqlite"])) {
}
function view($name) {
global $connection;
return array("select" => preg_replace('~^(?:[^`"[]+|`[^`]*`|"[^"]*")* AS\s+~iU', '', $connection->result("SELECT sql FROM sqlite_master WHERE type = 'view' AND name = " . q($name)))); //! identifiers may be inside []
return array("select" => preg_replace('~^(?:[^`"[]+|`[^`]*`|"[^"]*")* AS\s+~iU', '', get_val("SELECT sql FROM sqlite_master WHERE type = 'view' AND name = " . q($name)))); //! identifiers may be inside []
}
function collations() {
@@ -492,7 +488,7 @@ if (isset($_GET["sqlite"])) {
* @return bool
*/
function recreate_table($table, $name, $fields, $originals, $foreign, $auto_increment = 0, $indexes = array(), $drop_check = "", $add_check = "") {
global $connection, $driver;
global $driver;
if ($table != "") {
if (!$fields) {
foreach (fields($table) as $key => $field) {
@@ -578,7 +574,7 @@ if (isset($_GET["sqlite"])) {
$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
$auto_increment = $auto_increment ? 0 : get_val("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)))
@@ -642,7 +638,6 @@ if (isset($_GET["sqlite"])) {
}
function trigger($name) {
global $connection;
if ($name == "") {
return array("Statement" => "BEGIN\n\t;\nEND");
}
@@ -650,7 +645,7 @@ if (isset($_GET["sqlite"])) {
$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)),
get_val("SELECT sql FROM sqlite_master WHERE type = 'trigger' AND name = " . q($name)),
$match
);
$of = $match[3];
@@ -686,8 +681,7 @@ if (isset($_GET["sqlite"])) {
}
function last_id() {
global $connection;
return $connection->result("SELECT LAST_INSERT_ROWID()");
return get_val("SELECT LAST_INSERT_ROWID()");
}
function explain($connection, $query) {
@@ -702,8 +696,7 @@ if (isset($_GET["sqlite"])) {
}
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));
$return = get_val("SELECT sql FROM sqlite_master WHERE type IN ('table', 'view') AND name = " . q($table));
foreach (indexes($table) as $name => $index) {
if ($name == '') {
continue;

View File

@@ -42,7 +42,7 @@ SET foreign_key_checks = 0;
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))) {
if ($is_sql && preg_match('~CREATE~', $style) && ($create = get_val("SHOW CREATE DATABASE " . idf_escape($db), 1))) {
set_utf8mb4($create);
if ($style == "DROP+CREATE") {
echo "DROP DATABASE IF EXISTS " . idf_escape($db) . ";\n";
@@ -79,7 +79,7 @@ SET foreign_key_checks = 0;
if ($_POST["events"]) {
foreach (get_rows("SHOW EVENTS", null, "-- ") as $row) {
$create = remove_definer($connection->result("SHOW CREATE EVENT " . idf_escape($row["Name"]), 3));
$create = remove_definer(get_val("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";
}
@@ -140,9 +140,7 @@ SET foreign_key_checks = 0;
}
}
if ($is_sql) {
echo "-- " . gmdate("Y-m-d H:i:s e") . "\n";
}
$adminer->dumpFooter();
exit;
}
@@ -167,9 +165,9 @@ if (!isset($row["events"])) { // backwards compatibility
$row["triggers"] = $row["table_style"];
}
echo "<tr><th>" . lang('Output') . "<td>" . html_select("output", $adminer->dumpOutput(), $row["output"], 0) . "\n"; // 0 - radio
echo "<tr><th>" . lang('Output') . "<td>" . html_radios("output", $adminer->dumpOutput(), $row["output"]) . "\n";
echo "<tr><th>" . lang('Format') . "<td>" . html_select("format", $adminer->dumpFormat(), $row["format"], 0) . "\n"; // 0 - radio
echo "<tr><th>" . lang('Format') . "<td>" . html_radios("format", $adminer->dumpFormat(), $row["format"]) . "\n";
echo (JUSH == "sqlite" ? "" : "<tr><th>" . lang('Database') . "<td>" . html_select('db_style', $db_style, $row["db_style"])
. (support("type") ? checkbox("types", 1, $row["types"], lang('User types')) : "")

View File

@@ -68,13 +68,7 @@ if ($_POST["save"]) {
$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);
}
$as = ($_POST["clone"] && $field["auto_increment"] ? "''" : convert_field($field));
$select[] = ($as ? "$as AS " : "") . idf_escape($name);
}
}

View File

@@ -2,8 +2,13 @@
// To create Adminer just for Elasticsearch, run `../compile.php elastic`.
function adminer_object() {
include_once "../plugins/plugin.php";
include_once "../plugins/login-password-less.php";
include_once "../plugins/drivers/elastic.php";
return new Adminer\Adminer;
return new AdminerPlugin(array(
// TODO: inline the result of password_hash() so that the password is not visible in source codes
new AdminerLoginPasswordLess(password_hash("YOUR_PASSWORD_HERE", PASSWORD_DEFAULT)),
));
}
include "./index.php";

View File

@@ -9,6 +9,9 @@ if ($_GET["file"] == "favicon.ico") {
} elseif ($_GET["file"] == "default.css") {
header("Content-Type: text/css; charset=utf-8");
echo lzw_decompress(compile_file('../adminer/static/default.css;../externals/jush/jush.css', 'minify_css'));
} elseif ($_GET["file"] == "dark.css") {
header("Content-Type: text/css; charset=utf-8");
echo lzw_decompress(compile_file('../adminer/static/dark.css', 'minify_css'));
} elseif ($_GET["file"] == "functions.js") {
header("Content-Type: text/javascript; charset=utf-8");
echo lzw_decompress(compile_file('../adminer/static/functions.js;static/editing.js', 'minify_js'));

View File

@@ -94,8 +94,8 @@ if (support("scheme")) {
$j = 0;
foreach ($row["source"] as $key => $val) {
echo "<tr>";
echo "<td>" . html_select("source[" . (+$key) . "]", array(-1 => "") + $source, $val, ($j == count($row["source"]) - 1 ? "foreignAddRow.call(this);" : 1), "label-source");
echo "<td>" . html_select("target[" . (+$key) . "]", $target, $row["target"][$key], 1, "label-target");
echo "<td>" . html_select("source[" . (+$key) . "]", array(-1 => "") + $source, $val, ($j == count($row["source"]) - 1 ? "foreignAddRow.call(this);" : ""), "label-source");
echo "<td>" . html_select("target[" . (+$key) . "]", $target, $row["target"][$key], "", "label-target");
$j++;
}
?>

View File

@@ -5,7 +5,7 @@ namespace Adminer;
class Adminer {
/** @var array operators used in select, null for all operators */
var $operators;
public $operators;
/** Name in title and navigation
* @return string HTML code
@@ -98,7 +98,7 @@ class Adminer {
*/
function head() {
?>
<link rel="stylesheet" type="text/css" href="../externals/jush/jush.css">
<link rel="stylesheet" href="../externals/jush/jush.css">
<?php
return true;
}
@@ -289,13 +289,14 @@ class Adminer {
* @return string
*/
function selectVal($val, $link, $field, $original) {
$return = ($val === null ? "<i>NULL</i>" : (preg_match("~char|binary|boolean~", $field["type"]) && !preg_match("~var~", $field["type"]) ? "<code>$val</code>" : $val));
$return = ($val === null ? "<i>NULL</i>"
: (preg_match("~char|binary|boolean~", $field["type"]) && !preg_match("~var~", $field["type"]) ? "<code>$val</code>"
: (preg_match('~json~', $field["type"]) ? "<code class='jush-js'>$val</code>"
: $val)
));
if (preg_match('~blob|bytea|raw|file~', $field["type"]) && !is_utf8($val)) {
$return = "<i>" . lang('%d byte(s)', strlen($original)) . "</i>";
}
if (preg_match('~json~', $field["type"])) {
$return = "<code class='jush-js'>$return</code>";
}
return ($link ? "<a href='" . h($link) . "'" . (is_url($link) ? target_blank() : "") . ">$return</a>" : $return);
}
@@ -374,8 +375,7 @@ class Adminer {
$val["col"],
($key !== "" ? "selectFieldChange" : "selectAddRow")
);
echo "<div>" . ($driver->functions || $driver->grouping ? "<select name='columns[$i][fun]'>"
. optionlist(array(-1 => "") + array_filter(array(lang('Functions') => $driver->functions, lang('Aggregation') => $driver->grouping)), $val["fun"]) . "</select>"
echo "<div>" . ($driver->functions || $driver->grouping ? html_select("columns[$i][fun]", array(-1 => "") + array_filter(array(lang('Functions') => $driver->functions, lang('Aggregation') => $driver->grouping)), $val["fun"])
. 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) . "</div>\n";
@@ -572,7 +572,8 @@ class Adminer {
$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"]))
isset($field["privileges"]["where"])
&& (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"]))
&& (!preg_match('~date|timestamp~', $field["type"]) || preg_match('~^\d+-\d+-\d+~', $val["val"]))
) {
@@ -937,11 +938,23 @@ class Adminer {
($ext == "sql" || $output != "file" ? "text/plain" : "text/csv") . "; charset=utf-8"
)));
if ($output == "gz") {
ob_start('ob_gzencode', 1e6);
ob_start(function ($string) {
// ob_start() callback receives an optional parameter $phase but gzencode() accepts optional parameter $level
return gzencode($string);
}, 1e6);
}
return $ext;
}
/** Print text after export
* @return null prints data
*/
function dumpFooter() {
if ($_POST["format"] == "sql") {
echo "-- " . gmdate("Y-m-d H:i:s e") . "\n";
}
}
/** Set the path of the file for webserver load
* @return string path of the sql dump file
*/
@@ -1018,9 +1031,8 @@ class Adminer {
echo "jushLinks.$val = jushLinks." . JUSH . ";\n";
}
}
$server_info = $connection->server_info;
?>
bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '\1', $server_info) : ""); ?>'<?php echo (preg_match('~MariaDB~', $server_info) ? ", true" : ""); ?>);
bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '\1', $connection->server_info) : ""); ?>'<?php echo ($connection->maria ? ", true" : ""); ?>);
</script>
<?php
}
@@ -1064,14 +1076,14 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
<?php
hidden_fields_get();
$db_events = script("mixin(qsl('select'), {onmousedown: dbMouseDown, onchange: dbChange});");
echo "<span title='" . lang('Database') . "'>" . lang('DB') . "</span>: " . ($databases
? "<select name='db'>" . optionlist(array("" => "") + $databases, DB) . "</select>$db_events"
echo "<span title='" . lang('Database') . "'>" . lang('DB') . ":</span> " . ($databases
? html_select("db", array("" => "") + $databases, DB) . $db_events
: "<input name='db' value='" . h(DB) . "' autocapitalize='off' size='19'>\n"
);
echo "<input type='submit' value='" . lang('Use') . "'" . ($databases ? " class='hidden'" : "") . ">\n";
if (support("scheme")) {
if ($missing != "db" && DB != "" && $connection->select_db(DB)) {
echo "<br>" . lang('Schema') . ": <select name='ns'>" . optionlist(array("" => "") + $adminer->schemas(), $_GET["ns"]) . "</select>$db_events";
echo "<br><span>" . lang('Schema') . ":</span> " . html_select("ns", array("" => "") + $adminer->schemas(), $_GET["ns"]) . $db_events;
if ($_GET["ns"] != "") {
set_schema($_GET["ns"]);
}

View File

@@ -164,9 +164,11 @@ if (isset($_GET["username"]) && is_string(get_password())) {
}
check_invalid_login();
$connection = connect($adminer->credentials());
$driver = new Driver($connection);
if ($adminer->operators === null) {
$adminer->operators = $driver->operators;
if (is_object($connection)) {
$driver = new Driver($connection);
if ($adminer->operators === null) {
$adminer->operators = $driver->operators;
}
}
}

View File

@@ -62,7 +62,6 @@ if (function_exists("get_magic_quotes_runtime") && 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";
@@ -73,7 +72,6 @@ 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/mongo.inc.php";
include "./include/adminer.inc.php";
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver

View File

@@ -8,7 +8,13 @@ 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 != ""
? $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);

View File

@@ -28,15 +28,22 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
<meta name="robots" content="noindex">
<meta name="viewport" content="width=device-width">
<title><?php echo $title_page; ?></title>
<link rel="stylesheet" type="text/css" href="../adminer/static/default.css">
<?php echo script_src("../adminer/static/functions.js"); ?>
<?php echo script_src("static/editing.js"); ?>
<link rel="stylesheet" href="../adminer/static/default.css">
<?php
$css = $adminer->css();
if ($css) {
foreach ($css as $val) {
echo "<link rel='stylesheet' href='" . h($val) . "'>\n";
}
} else {
echo "<link rel='stylesheet' media='(prefers-color-scheme: dark)' href='../adminer/static/dark.css'>\n";
}
echo script_src("../adminer/static/functions.js");
echo script_src("static/editing.js");
?>
<?php if ($adminer->head()) { ?>
<link rel="shortcut icon" type="image/x-icon" href="../adminer/static/favicon.ico">
<link rel="apple-touch-icon" href="../adminer/static/favicon.ico">
<?php foreach ($adminer->css() as $css) { ?>
<link rel="stylesheet" type="text/css" href="<?php echo h($css); ?>">
<?php } ?>
<?php } ?>
<body class="<?php echo lang('ltr'); ?> nojs">
@@ -192,7 +199,7 @@ function page_footer($missing = "") {
<?php if ($missing != "auth") { ?>
<form action="" method="post">
<p class="logout">
<?php echo h($_GET["username"]) . "\n"; ?>
<span><?php echo h($_GET["username"]) . "\n"; ?></span>
<input type="submit" name="logout" value="<?php echo lang('Logout'); ?>" id="logout">
<input type="hidden" name="token" value="<?php echo $token; ?>">
</p>

View File

@@ -13,36 +13,35 @@ function add_driver($id, $name) {
$drivers[$id] = $name;
}
/** Get driver name
* @param string
* @return string
/** Get driver
* @return Driver
*/
function get_driver($id) {
global $drivers;
return $drivers[$id];
function get_driver() {
global $driver;
return $driver;
}
abstract class SqlDriver {
static $possibleDrivers = array();
static $jush; ///< @var string JUSH identifier
var $_conn;
protected $conn;
protected $types = array(); ///< @var array [$description => [$type => $maximum_unsigned_length, ...], ...]
var $editFunctions = array(); ///< @var array of ["$type|$type2" => "$function/$function2"] functions used in editing, [0] - edit and insert, [1] - edit only
var $unsigned = array(); ///< @var array number variants
var $operators = array(); ///< @var array operators used in select
var $functions = array(); ///< @var array functions used in select
var $grouping = array(); ///< @var array grouping functions used in select
var $onActions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; ///< @var string used in foreign_keys()
var $inout = "IN|OUT|INOUT";
var $enumLength = "'(?:''|[^'\\\\]|\\\\.)*'";
var $generated = array();
public $editFunctions = array(); ///< @var array of ["$type|$type2" => "$function/$function2"] functions used in editing, [0] - edit and insert, [1] - edit only
public $unsigned = array(); ///< @var array number variants
public $operators = array(); ///< @var array operators used in select
public $functions = array(); ///< @var array functions used in select
public $grouping = array(); ///< @var array grouping functions used in select
public $onActions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; ///< @var string used in foreign_keys()
public $inout = "IN|OUT|INOUT"; ///< @var string used in routines
public $enumLength = "'(?:''|[^'\\\\]|\\\\.)*'"; ///< @var string regular expression for parsing enum lengths
public $generated = array(); ///< @var array allowed types of generated columns
/** Create object for performing database operations
* @param Db
*/
function __construct($connection) {
$this->_conn = $connection;
$this->conn = $connection;
}
/** Get all types
@@ -59,6 +58,20 @@ abstract class SqlDriver {
return array_map('array_keys', $this->types);
}
/** Get enum values
* @param array
* @return string or null
*/
function enumLength($field) {
}
/** Function used to convert the value inputted by user
* @param array
* @return string or null
*/
function unconvertFunction($field) {
}
/** Select data from table
* @param string
* @param array result of $adminer->selectColumnsProcess()[0]
@@ -84,7 +97,7 @@ abstract class SqlDriver {
);
}
$start = microtime(true);
$return = $this->_conn->query($query);
$return = $this->conn->query($query);
if ($print) {
echo $adminer->selectQuery($query, $start, !$return);
}
@@ -194,8 +207,8 @@ abstract class SqlDriver {
* @return string
*/
function value($val, $field) {
return (method_exists($this->_conn, 'value')
? $this->_conn->value($val, $field)
return (method_exists($this->conn, 'value')
? $this->conn->value($val, $field)
: (is_resource($val) ? stream_get_contents($val) : $val)
);
}

View File

@@ -224,13 +224,19 @@ function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_ty
size="3"
<?php echo (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : ""); //! type="number" with enabled JavaScript ?>
aria-labelledby="label-length"><td class="options"><?php
echo ($collations ? "<select name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>' : '');
echo ($collations
? "<input list='collations' name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . " value='" . h($field["collation"]) . "' placeholder='(" . lang('collation') . ")'>"
: ''
);
echo ($driver->unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist($driver->unsigned, $field["unsigned"]) . '</select>' : '');
echo (isset($field['on_update']) ? "<select name='" . h($key) . "[on_update]'" . (preg_match('~timestamp|datetime~', $type) ? "" : " class='hidden'") . '>'
. optionlist(array("" => "(" . lang('ON UPDATE') . ")", "CURRENT_TIMESTAMP"), (preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"]) ? "CURRENT_TIMESTAMP" : $field["on_update"]))
. '</select>' : ''
);
echo ($foreign_keys ? "<select name='" . h($key) . "[on_delete]'" . (preg_match("~`~", $type) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", $driver->onActions), $field["on_delete"]) . "</select> " : " "); // space for IE
echo ($foreign_keys
? "<select name='" . h($key) . "[on_delete]'" . (preg_match("~`~", $type) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", $driver->onActions), $field["on_delete"]) . "</select> "
: " " // space for IE
);
}
/** Get partition info
@@ -307,8 +313,8 @@ function default_value($field) {
$generated = $field["generated"];
return ($default === null ? "" : (in_array($generated, $driver->generated)
? (JUSH == "mssql" ? " AS ($default)" . ($generated == "VIRTUAL" ? "" : " $generated") . "" : " GENERATED ALWAYS AS ($default) $generated")
: " DEFAULT " . (!preg_match('~^GENERATED ~i', $default) && (preg_match('~char|binary|text|enum|set~', $field["type"]) || preg_match('~^(?![a-z])~i', $default))
? q($default)
: " DEFAULT " . (!preg_match('~^GENERATED ~i', $default) && (preg_match('~char|binary|text|json|enum|set~', $field["type"]) || preg_match('~^(?![a-z])~i', $default))
? (JUSH == "sql" && preg_match('~text|json~', $field["type"]) ? "(" . q($default) . ")" : q($default)) // MySQL requires () around default value of text column
: str_ireplace("current_timestamp()", "CURRENT_TIMESTAMP", (JUSH == "sqlite" ? "($default)" : $default))
)
));
@@ -386,7 +392,7 @@ function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = arra
<td><?php echo checkbox("fields[$i][null]", 1, $field["null"], "", "", "block", "label-null"); ?>
<td><label class="block"><input type="radio" name="auto_increment_col" value="<?php echo $i; ?>"<?php echo ($field["auto_increment"] ? " checked" : ""); ?> aria-labelledby="label-ai"></label><td<?php echo $default_class; ?>><?php
echo ($driver->generated
? "<select name='fields[$i][generated]'>" . optionlist(array_merge(array("", "DEFAULT"), $driver->generated), $field["generated"]) . "</select> "
? html_select("fields[$i][generated]", array_merge(array("", "DEFAULT"), $driver->generated), $field["generated"]) . " "
: checkbox("fields[$i][generated]", 1, $field["generated"], "", "", "", "label-default")
);
?>
@@ -624,22 +630,13 @@ function doc_link($paths, $text = "<sup>?</sup>") {
'mssql' => "https://learn.microsoft.com/en-us/sql/",
'oracle' => "https://www.oracle.com/pls/topic/lookup?ctx=db" . preg_replace('~^.* (\d+)\.(\d+)\.\d+\.\d+\.\d+.*~s', '\1\2', $server_info) . "&id=",
);
if (preg_match('~MariaDB~', $server_info)) {
if ($connection->maria) {
$urls['sql'] = "https://mariadb.com/kb/en/";
$paths['sql'] = (isset($paths['mariadb']) ? $paths['mariadb'] : str_replace(".html", "/", $paths['sql']));
}
return ($paths[JUSH] ? "<a href='" . h($urls[JUSH] . $paths[JUSH] . (JUSH == 'mssql' ? "?view=sql-server-ver$version" : "")) . "'" . target_blank() . ">$text</a>" : "");
}
/** Wrap gzencode() for usage in ob_start()
* @param string
* @return string
*/
function ob_gzencode($string) {
// ob_start() callback receives an optional parameter $phase but gzencode() accepts optional parameter $level
return gzencode($string);
}
/** Compute size of database
* @param string
* @return string formatted

View File

@@ -217,22 +217,29 @@ function optionlist($options, $selected = null, $use_keys = false) {
return $return;
}
/** Generate HTML <select>
* @param string
* @param array
* @param string
* @param string
* @param string
* @return string
*/
function html_select($name, $options, $value = "", $onchange = "", $labelled_by = "") {
return "<select name='" . h($name) . "'"
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
. ">" . optionlist($options, $value) . "</select>"
. ($onchange ? script("qsl('select').onchange = function () { $onchange };", "") : "")
;
}
/** Generate HTML radio list
* @param string
* @param array
* @param string
* @param string true for no onchange, false for radio
* @param string
* @return string
*/
function html_select($name, $options, $value = "", $onchange = true, $labelled_by = "") {
if ($onchange) {
return "<select name='" . h($name) . "'"
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
. ">" . optionlist($options, $value) . "</select>"
. (is_string($onchange) ? script("qsl('select').onchange = function () { $onchange };", "") : "")
;
}
function html_radios($name, $options, $value = "") {
$return = "";
foreach ($options as $key => $val) {
$return .= "<label><input type='radio' name='" . h($name) . "' value='" . h($key) . "'" . ($key == $value ? " checked" : "") . ">" . h($val) . "</label>";
@@ -337,6 +344,16 @@ function q($string) {
return $connection->quote($string);
}
/** Get single value from database
* @param string
* @param int
* @return string or false if error
*/
function get_val($query, $field = 0) {
global $connection;
return $connection->result($query, $field);
}
/** Get list of values from database
* @param string
* @param mixed
@@ -442,14 +459,15 @@ function where($where, $fields = array()) {
foreach ((array) $where["where"] as $key => $val) {
$key = bracket_escape($key, 1); // 1 - back
$column = escape_key($key);
$field_type = $fields[$key]["type"];
$return[] = $column
. (JUSH == "sql" && $fields[$key]["type"] == "json" ? " = CAST(" . q($val) . " AS JSON)"
. (JUSH == "sql" && $field_type == "json" ? " = CAST(" . q($val) . " AS JSON)"
: (JUSH == "sql" && is_numeric($val) && preg_match('~\.~', $val) ? " LIKE " . q($val) // LIKE because of floats but slow with ints
: (JUSH == "mssql" ? " LIKE " . q(preg_replace('~[_%[]~', '[\0]', $val)) // LIKE because of text
: (JUSH == "mssql" && strpos($field_type, "datetime") === false ? " LIKE " . q(preg_replace('~[_%[]~', '[\0]', $val)) // LIKE because of text but it does not work with datetime
: " = " . unconvert_field($fields[$key], q($val))
)))
; //! enum and set
if (JUSH == "sql" && preg_match('~char|text~', $fields[$key]["type"]) && preg_match("~[^ -@]~", $val)) { // not just [a-z] to catch non-ASCII characters
if (JUSH == "sql" && preg_match('~char|text~', $field_type) && preg_match("~[^ -@]~", $val)) { // not just [a-z] to catch non-ASCII characters
$return[] = "$column = " . q($val) . " COLLATE " . charset($connection) . "_bin";
}
}
@@ -718,9 +736,10 @@ function pagination($page, $current) {
/** Get file contents from $_FILES
* @param string
* @param bool
* @param string
* @return mixed int for error, string otherwise
*/
function get_file($key, $decompress = false) {
function get_file($key, $decompress = false, $delimiter = "") {
$file = $_FILES[$key];
if (!$file) {
return null;
@@ -742,17 +761,17 @@ function get_file($key, $decompress = false) {
); //! may not be reachable because of open_basedir
if ($decompress) {
$start = substr($content, 0, 3);
if (function_exists("iconv") && preg_match("~^\xFE\xFF|^\xFF\xFE~", $start, $regs)) { // not ternary operator to save memory
if (function_exists("iconv") && preg_match("~^\xFE\xFF|^\xFF\xFE~", $start)) { // not ternary operator to save memory
$content = iconv("utf-16", "utf-8", $content);
} elseif ($start == "\xEF\xBB\xBF") { // UTF-8 BOM
$content = substr($content, 3);
}
$return .= $content . "\n\n";
} else {
$return .= $content;
}
$return .= $content;
if ($delimiter) {
$return .= (preg_match("($delimiter\\s*\$)", $content) ? "" : $delimiter) . "\n\n";
}
}
//! support SQL files not ending with semicolon
return $return;
}
@@ -873,18 +892,18 @@ function column_foreign_keys($table) {
* @param string "radio"|"checkbox"
* @param string
* @param array
* @param mixed int|string|array
* @param mixed string|array
* @param string
* @return null
*/
function enum_input($type, $attrs, $field, $value, $empty = null) {
global $adminer;
preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
$return = ($empty !== null ? "<label><input type='$type'$attrs value='$empty'" . ((is_array($value) ? in_array($empty, $value) : $value === 0) ? " checked" : "") . "><i>" . lang('empty') . "</i></label>" : "");
$return = ($empty !== null ? "<label><input type='$type'$attrs value='$empty'" . ((is_array($value) ? in_array($empty, $value) : $value === $empty) ? " checked" : "") . "><i>" . lang('empty') . "</i></label>" : "");
foreach ($matches[1] as $i => $val) {
$val = stripcslashes(str_replace("''", "'", $val));
$checked = (is_int($value) ? $value == $i+1 : (is_array($value) ? in_array($i+1, $value) : $value === $val));
$return .= " <label><input type='$type'$attrs value='" . (JUSH == "sql" ? $i+1 : h($val)) . "'" . ($checked ? ' checked' : '') . '>' . h($adminer->editVal($val, $field)) . '</label>';
$checked = (is_array($value) ? in_array($val, $value) : $value === $val);
$return .= " <label><input type='$type'$attrs value='" . h($val) . "'" . ($checked ? ' checked' : '') . '>' . h($adminer->editVal($val, $field)) . '</label>';
}
return $return;
}
@@ -900,11 +919,7 @@ function input($field, $value, $function) {
$name = h(bracket_escape($field["field"]));
echo "<td class='function'>";
if (is_array($value) && !$function) {
$args = array($value);
if (version_compare(PHP_VERSION, 5.4) >= 0) {
$args[] = JSON_PRETTY_PRINT;
}
$value = call_user_func_array('json_encode', $args); //! requires PHP 5.2
$value = json_encode($value, 128); // 128 - JSON_PRETTY_PRINT available since PHP 5.4
$function = "json";
}
$reset = (JUSH == "mssql" && $field["auto_increment"]);
@@ -914,15 +929,12 @@ function input($field, $value, $function) {
$functions = (isset($_GET["select"]) || $reset ? array("orig" => lang('original')) : array()) + $adminer->editFunctions($field);
$disabled = stripos($field["default"], "GENERATED ALWAYS AS ") === 0 ? " disabled=''" : "";
$attrs = " name='fields[$name]'$disabled";
$types = $driver->types();
$structured_types = $driver->structuredTypes();
if (in_array($field["type"], (array) $structured_types[lang('User types')])) {
$enums = type_values($types[$field["type"]]);
if ($enums) {
$field["type"] = "enum";
$field["length"] = $enums;
}
$enums = $driver->enumLength($field);
if ($enums) {
$field["type"] = "enum";
$field["length"] = $enums;
}
echo $driver->unconvertFunction($field) . " ";
if ($field["type"] == "enum") {
echo h($functions[""]) . "<td>" . $adminer->editInput($_GET["edit"], $field, $attrs, $value);
} else {
@@ -939,12 +951,12 @@ function input($field, $value, $function) {
} elseif (preg_match('~bool~', $field["type"])) {
echo "<input type='hidden'$attrs value='0'>"
. "<input type='checkbox'" . (preg_match('~^(1|t|true|y|yes|on)$~i', $value) ? " checked='checked'" : "") . "$attrs value='1'>";
} elseif ($field["type"] == "set") { //! 64 bits
} elseif ($field["type"] == "set") {
preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
foreach ($matches[1] as $i => $val) {
$val = stripcslashes(str_replace("''", "'", $val));
$checked = (is_int($value) ? ($value >> $i) & 1 : in_array($val, explode(",", $value), true));
echo " <label><input type='checkbox' name='fields[$name][$i]' value='" . (1 << $i) . "'" . ($checked ? ' checked' : '') . ">" . h($adminer->editVal($val, $field)) . '</label>';
$checked = in_array($val, explode(",", $value), true);
echo " <label><input type='checkbox' name='fields[$name][$i]' value='" . h($val) . "'" . ($checked ? ' checked' : '') . ">" . h($adminer->editVal($val, $field)) . '</label>';
}
} elseif (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
echo "<input type='file' name='fields-$name'>";
@@ -960,6 +972,7 @@ function input($field, $value, $function) {
echo "<textarea$attrs cols='50' rows='12' class='jush-js'>" . h($value) . '</textarea>';
} else {
// int(3) is only a display hint
$types = $driver->types();
$maxlength = (!preg_match('~int~', $field["type"]) && preg_match('~^(\d+)(,(\d+))?$~', $field["length"], $match)
? ((preg_match("~binary~", $field["type"]) ? 2 : 1) * $match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0))
: ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0)
@@ -1004,14 +1017,13 @@ function process_input($field) {
$idf = bracket_escape($field["field"]);
$function = $_POST["function"][$idf];
$value = $_POST["fields"][$idf];
if ($field["type"] == "enum") {
if ($field["type"] == "enum" || $driver->enumLength($field)) {
if ($value == -1) {
return false;
}
if ($value == "") {
return "NULL";
}
return +$value;
}
if ($field["auto_increment"] && $value == "") {
return null;
@@ -1023,7 +1035,7 @@ function process_input($field) {
return "NULL";
}
if ($field["type"] == "set") {
return array_sum((array) $value);
$value = implode(",", (array) $value);
}
if ($function == "json") {
$function = "";
@@ -1060,7 +1072,7 @@ function fields_from_edit() {
$name = bracket_escape($key, 1); // 1 - back
$return[$name] = array(
"field" => $name,
"privileges" => array("insert" => 1, "update" => 1),
"privileges" => array("insert" => 1, "update" => 1, "where" => 1, "order" => 1),
"null" => 1,
"auto_increment" => ($key == $driver->primary),
);
@@ -1302,6 +1314,7 @@ function slow_query($query) {
$db = $adminer->database();
$timeout = $adminer->queryTimeout();
$slow_query = $driver->slowQuery($query, $timeout);
$connection2 = null;
if (!$slow_query && support("kill") && is_object($connection2 = connect($adminer->credentials())) && ($db == "" || $connection2->select_db($db))) {
$kill = $connection2->result(connection_id()); // MySQL and MySQLi can use thread_id but it's not in PDO_MySQL
?>
@@ -1312,8 +1325,6 @@ var timeout = setTimeout(function () {
}, <?php echo 1000 * $timeout; ?>);
</script>
<?php
} else {
$connection2 = null;
}
ob_flush();
flush();
@@ -1413,11 +1424,12 @@ function edit_form($table, $fields, $row, $update) {
?>
<form action="" method="post" enctype="multipart/form-data" id="form">
<?php
$first = 0;
$is_first = true;
if (!$fields) {
echo "<p class='error'>" . lang('You have no privileges to update this table.') . "\n";
} else {
echo "<table class='layout'>" . script("qsl('table').onkeydown = editingKeydown;");
$first = 0;
foreach ($fields as $name => $field) {
echo "<tr><th>" . $adminer->fieldName($field);
$default = $_GET["set"][bracket_escape($name)];
@@ -1426,10 +1438,13 @@ function edit_form($table, $fields, $row, $update) {
if ($field["type"] == "bit" && preg_match("~^b'([01]*)'\$~", $default, $regs)) {
$default = $regs[1];
}
if (JUSH == "sql" && preg_match('~binary~', $field["type"])) {
$default = bin2hex($default); // same as UNHEX
}
}
$value = ($row !== null
? ($row[$name] != "" && JUSH == "sql" && preg_match("~enum|set~", $field["type"])
? (is_array($row[$name]) ? array_sum($row[$name]) : +$row[$name])
? ($row[$name] != "" && JUSH == "sql" && preg_match("~enum|set~", $field["type"]) && is_array($row[$name])
? implode(",", $row[$name])
: (is_bool($row[$name]) ? +$row[$name] : $row[$name])
)
: (!$update && $field["auto_increment"]
@@ -1458,8 +1473,10 @@ function edit_form($table, $fields, $row, $update) {
$value = "";
$function = "uuid";
}
if ($field["auto_increment"] || $function == "now" || $function == "uuid") {
if ($is_first && ($field["auto_increment"] || $function == "now" || $function == "uuid")) {
$first++;
} else {
$is_first = false;
}
input($field, $value, $function);
echo "\n";

View File

@@ -74,7 +74,7 @@ function lang($idf, $number = null) {
: ($LANG == 'sl' ? ($number % 100 == 1 ? 0 : ($number % 100 == 2 ? 1 : ($number % 100 == 3 || $number % 100 == 4 ? 2 : 3))) // different forms for 1, 2, 3-4, other
: ($LANG == 'lt' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1, 12-19, other
: ($LANG == 'lv' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number ? 1 : 2)) // different forms for 1 except 11, other, 0
: ($LANG == 'bs' || $LANG == 'ru' || $LANG == 'sr' || $LANG == 'uk' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1 except 11, 2-4 except 12-14, other
: (in_array($LANG, array('bs', 'ru', 'sr', 'uk')) ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1 except 11, 2-4 except 12-14, other
: 1 // different forms for 1, other
)))))))); // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
$translation = $translation[$pos];

View File

@@ -4,7 +4,9 @@ namespace Adminer;
// PDO can be used in several database drivers
if (extension_loaded('pdo')) {
abstract class PdoDb {
var $_result, $server_info, $affected_rows, $errno, $error, $pdo;
public $server_info, $affected_rows, $errno, $error;
protected $pdo;
private $result;
function dsn($dsn, $username, $password, $options = array()) {
$options[\PDO::ATTR_ERRMODE] = \PDO::ERRMODE_SILENT;
@@ -38,12 +40,12 @@ if (extension_loaded('pdo')) {
}
function multi_query($query) {
return $this->_result = $this->query($query);
return $this->result = $this->query($query);
}
function store_result($result = null) {
if (!$result) {
$result = $this->_result;
$result = $this->result;
if (!$result) {
return false;
}
@@ -57,11 +59,11 @@ if (extension_loaded('pdo')) {
}
function next_result() {
if (!$this->_result) {
if (!$this->result) {
return false;
}
$this->_result->_offset = 0;
return @$this->_result->nextRowset(); // @ - PDO_PgSQL doesn't support it
$this->result->_offset = 0;
return @$this->result->nextRowset(); // @ - PDO_PgSQL doesn't support it
}
function result($query, $field = 0) {
@@ -75,7 +77,7 @@ if (extension_loaded('pdo')) {
}
class PdoDbStatement extends \PDOStatement {
var $_offset = 0, $num_rows;
public $_offset = 0, $num_rows;
function fetch_assoc() {
return $this->fetch(\PDO::FETCH_ASSOC);

View File

@@ -2,8 +2,7 @@
namespace Adminer;
class TmpFile {
var $handler;
var $size;
private $handler, $size;
function __construct() {
$this->handler = tmpfile();

View File

@@ -1,4 +1,4 @@
<?php
namespace Adminer;
$VERSION = "5.0.1";
$VERSION = "5.0.5";

View File

@@ -126,7 +126,7 @@ if ($primary) {
$j = 1;
foreach ($row["indexes"] as $index) {
if (!$_POST["drop_col"] || $j != key($_POST["drop_col"])) {
echo "<tr><td>" . html_select("indexes[$j][type]", array(-1 => "") + $index_types, $index["type"], ($j == count($row["indexes"]) ? "indexesAddRow.call(this);" : 1), "label-type");
echo "<tr><td>" . html_select("indexes[$j][type]", array(-1 => "") + $index_types, $index["type"], ($j == count($row["indexes"]) ? "indexesAddRow.call(this);" : ""), "label-type");
echo "<td>";
ksort($index["columns"]);

View File

@@ -77,7 +77,7 @@ $translations = array(
'Routine has been called, %d row(s) affected.' => 'تم استدعاء الروتين, عدد الأسطر المعدلة %d.',
'Call' => 'استدعاء',
'No extension' => 'امتداد غير موجود',
'None of the supported PHP extensions (%s) are available.' => 'إمتدادات php المدعومة غير موجودة.',
'None of the supported PHP extensions (%s) are available.' => 'إمتدادات php (%s) المدعومة غير موجودة.',
'Session support must be enabled.' => 'عليك تفعيل نظام الجلسات.',
'Session expired, please login again.' => 'إنتهت الجلسة، من فضلك أعد تسجيل الدخول.',
'Text length' => 'طول النص',
@@ -171,8 +171,8 @@ $translations = array(
'Tables and views' => 'الجداول و العروض',
'Engine' => 'المحرك',
'Collation' => 'ترتيب',
'Data Length' => 'طول المعطيات.',
'Index Length' => 'طول المؤشر.',
'Data Length' => 'طول المعطيات',
'Index Length' => 'طول المؤشر',
'Data Free' => 'المساحة الحرة',
'Rows' => 'الأسطر',
',' => ',',
@@ -192,7 +192,7 @@ $translations = array(
'Partitions' => 'التقسيمات',
'Partition name' => 'اسم التقسيم',
'Values' => 'القيم',
'%d row(s) have been imported.' => 'تم استيراد %d سطرا',
'%d row(s) have been imported.' => 'تم استيراد %d سطرا.',
'anywhere' => 'في اي مكان',
'Import' => 'استيراد',
'Stop on error' => 'أوقف في حالة حدوث خطأ',
@@ -251,8 +251,8 @@ $translations = array(
'Network' => 'شبكة',
'Geometry' => 'هندسة',
'File exists.' => 'الملف موجود.',
'Attachments' => 'ملفات مرفقة.',
'Item%s has been inserted.' => 'تم إدراج العنصر.',
'Attachments' => 'ملفات مرفقة',
'Item%s has been inserted.' => '%sتم إدراج العنصر.',
'now' => 'الآن',
'%d query(s) executed OK.' => array('تم تنفيذ الاستعلام %d بنجاح.', 'تم تنفيذ الاستعلامات %d بنجاح.'),
'Show only errors' => 'إظهار الأخطاء فقط',

View File

@@ -38,7 +38,7 @@ $translations = array(
'select' => 'নির্বাচন',
'Item has been deleted.' => 'বিষয়বস্তু মুছে ফেলা হয়েছে।',
'Item has been updated.' => 'বিষয়বস্তু হালনাগাদ করা হয়েছে।',
'Item%s has been inserted.' => 'বিষয়বস্তুসমূহ সংযোজন করা হয়েছে।',
'Item%s has been inserted.' => 'বিষয়বস্তুসমূহ%s সংযোজন করা হয়েছে।',
'Edit' => 'সম্পাদনা',
'Insert' => 'সংযোজন',
'Save and insert next' => 'সংরক্ষন ও পরবর্তী সংযোজন করুন',
@@ -61,7 +61,7 @@ $translations = array(
'edit' => 'সম্পাদনা',
'Page' => 'পৃষ্ঠা',
'Query executed OK, %d row(s) affected.' => array('কোয়্যারী সম্পাদন হয়েছে, %d সারি প্রভাবিত হয়েছে।', 'কোয়্যারী সম্পাদন হয়েছে, %d সারি প্রভাবিত হয়েছে।'),
'Error in query' => 'অনুসন্ধানে ভুল আছে',
'Error in query' => 'অনুসন্ধানে ভুল আছে',
'Execute' => 'সম্পাদন করো',
'Table' => 'টেবিল',
'Foreign keys' => 'ফরেন কী',
@@ -139,7 +139,7 @@ $translations = array(
'Routine' => 'রুটিন',
'Grant' => 'অনুমতি',
'Revoke' => 'প্রত্যাহার',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'খুব বড় POST ডাটা। ডাটা সংক্ষিপ্ত করো অথবা %s কনফিগারেশন নির্দেশ বৃদ্ধি করো',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'খুব বড় POST ডাটা। ডাটা সংক্ষিপ্ত করো অথবা %s কনফিগারেশন নির্দেশ বৃদ্ধি করো',
'Logged as: %s' => '%s হিসাবে লগড',
'Move up' => 'উপরে স্থানান্তর',
'Move down' => 'নীচে স্থানান্তর',
@@ -175,7 +175,7 @@ $translations = array(
'Check' => 'পরীক্ষা',
'Repair' => 'মেরামত',
'Truncate' => 'ছাঁটাই',
'Tables have been truncated.' => 'টেবিল ছাঁটাই করা হয়েছে',
'Tables have been truncated.' => 'টেবিল ছাঁটাই করা হয়েছে',
'Rows' => 'সারিসমূহ',
',' => ',',
'0123456789' => '০১২৩৪৫৬৭৮৯',
@@ -186,7 +186,7 @@ $translations = array(
'Save and continue edit' => 'সংরক্ষণ করুন এবং সম্পাদনা চালিয়ে যান',
'original' => 'প্রকৃত',
'Tables have been dropped.' => 'টেবিলসমূহ মুছে ফেলা হয়েছে।',
'%d item(s) have been affected.' => '%d টি বিষয়বস্তু প্রভাবিত হয়েছে',
'%d item(s) have been affected.' => '%d টি বিষয়বস্তু প্রভাবিত হয়েছে',
'Whole result' => 'সম্পূর্ণ ফলাফল',
'Clone' => 'ক্লোন',
'Maximum number of allowed fields exceeded. Please increase %s.' => 'অনুমোদিত ফিল্ড এর সর্বাধিক সংখ্যা অতিক্রম করে গেছে। অনুগ্রহপূর্বক %s বৃদ্ধি করুন।',
@@ -207,7 +207,7 @@ $translations = array(
'Relations' => 'সম্পর্ক',
'Run file' => 'ফাইল চালাও',
'Clear' => 'সাফ করো',
'Maximum allowed file size is %sB.' => 'সর্বাধিক অনুমোদিত ফাইল সাইজ %sB.',
'Maximum allowed file size is %sB.' => 'সর্বাধিক অনুমোদিত ফাইল সাইজ %sB',
'Numbers' => 'সংখ্যা',
'Date and time' => 'তারিখ এবং সময়',
'Strings' => 'স্ট্রিং',
@@ -253,7 +253,7 @@ $translations = array(
'Geometry' => 'জ্যামিতি',
'File exists.' => 'ফাইল রয়েছে।',
'Attachments' => 'সংযুক্তিগুলো',
'%d query(s) executed OK.' => array('SQL-অনুসন্ধান সফলভাবে সম্পন্ন হয়েছে', '%d SQL-অনুসন্ধানসমূহ সফলভাবে সম্পন্ন হয়েছে'),
'%d query(s) executed OK.' => array('SQL-অনুসন্ধান সফলভাবে সম্পন্ন হয়েছে', '%d SQL-অনুসন্ধানসমূহ সফলভাবে সম্পন্ন হয়েছে'),
'Show only errors' => 'শুধুমাত্র ত্রুটিগুলো দেখান',
'Refresh' => 'রিফ্রেশ',
'Invalid schema.' => 'অবৈধ স্কিমা।',

View File

@@ -16,7 +16,7 @@ $translations = array(
'Language' => 'Jezik',
'Invalid CSRF token. Send the form again.' => 'Nevažeći CSRF kod. Proslijedite ponovo formu.',
'No extension' => 'Bez dodataka',
'None of the supported PHP extensions (%s) are available.' => 'Nijedan od podržanih PHP dodataka nije dostupan.',
'None of the supported PHP extensions (%s) are available.' => 'Nijedan od podržanih PHP dodataka (%s) nije dostupan.',
'Session support must be enabled.' => 'Morate omogućiti podršku za sesije.',
'Session expired, please login again.' => 'Vaša sesija je istekla, prijavite se ponovo.',
'%s version: %s through PHP extension %s' => '%s verzija: %s pomoću PHP dodatka je %s',

View File

@@ -4,7 +4,7 @@ namespace Adminer;
$translations = array(
'Login' => 'Login',
'Logout successful.' => 'Abmeldung erfolgreich.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Danke, dass Sie Adminer genutzt haben. <a href="https://www.adminer.org/de/donation/">Spenden willkommen!</a>',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Danke, dass Sie Adminer genutzt haben. <a href="https://www.adminer.org/de/donation/">Spenden willkommen!</a>.',
'Invalid credentials.' => 'Ungültige Anmelde-Informationen.',
'Server' => 'Server',
'Username' => 'Benutzer',
@@ -302,4 +302,10 @@ $translations = array(
'Unknown error.' => 'Unbekannter Fehler.',
'Database does not support password.' => 'Die Datenbank unterstützt kein Passwort.',
'Disable %s or enable %s or %s extensions.' => 'Deaktivieren Sie %s oder aktivieren Sie die Erweiterungen %s oder %s.',
'Check has been dropped.' => 'Check wurde abgebrochen.',
'Check has been altered.' => 'Check wurde geändert.',
'Check has been created.' => 'Check wurde erstellt.',
'Alter check' => 'Check ändern',
'Create check' => 'Check erstellen',
'Checks' => 'Checks',
);

View File

@@ -146,7 +146,7 @@ $translations = array(
'Tables' => 'جدولها',
'Tables and views' => 'جدولها و نمایه ها',
'Table' => 'جدول',
'No tables.' => 'جدولی وجود ندارد',
'No tables.' => 'جدولی وجود ندارد.',
'Alter table' => 'ویرایش جدول',
'Create table' => 'ایجاد جدول',
'Table has been dropped.' => 'جدول حذف شد.',
@@ -238,7 +238,7 @@ $translations = array(
'Action' => 'عملیات',
'Full table scan' => 'اسکن کامل جدول',
'Unable to select the table' => 'قادر به انتخاب جدول نیستید',
'No rows.' => 'سطری وجود ندارد',
'No rows.' => 'سطری وجود ندارد.',
'%d / ' => '%d / ',
'%d row(s)' => array('%d سطر', '%d سطر'),
'Page' => 'صفحه',

View File

@@ -298,7 +298,7 @@ $translations = array(
'The action will be performed after successful login with the same credentials.' => 'Cette action sera exécutée après s\'être connecté avec les mêmes données de connexion.',
'Connecting to privileged ports is not allowed.' => 'La connexion aux ports privilégiés n\'est pas autorisée.',
'There is a space in the input password which might be the cause.' => 'Il y a un espace dans le mot de passe entré qui pourrait en être la cause.',
'Unknown error.' => 'Erreur inconnue',
'Database does not support password.' => 'La base de données ne support pas les mots de passe',
'Unknown error.' => 'Erreur inconnue.',
'Database does not support password.' => 'La base de données ne support pas les mots de passe.',
'Disable %s or enable %s or %s extensions.' => 'Désactiver %s ou activer %s or %s extensions.',
);

View File

@@ -266,11 +266,11 @@ $translations = array(
'Permanent link' => 'Ligazón permanente',
'Edit all' => 'Editar todo',
'HH:MM:SS' => 'HH:MM:SS',
'Tables have been optimized.' => 'Optimizáronse as táboas',
'Tables have been optimized.' => 'Optimizáronse as táboas.',
'Materialized view' => 'Vista materializada',
'Vacuum' => 'Baleirar',
'Selected' => 'Selección',
'File must be in UTF-8 encoding.' => 'O ficheiro ten que estar codificado con UTF-8',
'File must be in UTF-8 encoding.' => 'O ficheiro ten que estar codificado con UTF-8.',
'Modify' => 'Modificar',
'Loading' => 'Cargando',
'Load more data' => 'Cargar máis datos',
@@ -278,14 +278,14 @@ $translations = array(
'Limit rows' => 'Limitar filas',
'Default value' => 'Valor por defecto',
'Full table scan' => 'Escaneo completo da táboa',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Demasiados intentos de conexión, intentao de novo en %d minuto', 'Demasiados intentos de conexión, intentao de novo en %d minutos'),
'Too many unsuccessful logins, try again in %d minute(s).' => array('Demasiados intentos de conexión, intentao de novo en %d minuto.', 'Demasiados intentos de conexión, intentao de novo en %d minutos.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'O contrasinal principal caducou. <a href="https://www.adminer.org/en/extension/"%s>Implementa</a> o método %s para facelo permanente.',
'If you did not send this request from Adminer then close this page.' => 'Se non enviaches esta petición dende o Adminer entón pecha esta páxina',
'You can upload a big SQL file via FTP and import it from server.' => 'Podes subir un ficheiro SQL de gran tamaño vía FTP e importalo dende o servidor',
'If you did not send this request from Adminer then close this page.' => 'Se non enviaches esta petición dende o Adminer entón pecha esta páxina.',
'You can upload a big SQL file via FTP and import it from server.' => 'Podes subir un ficheiro SQL de gran tamaño vía FTP e importalo dende o servidor.',
'Size' => 'Tamaño',
'Compute' => 'Calcular',
'You are offline.' => 'Non tes conexión',
'You have no privileges to update this table.' => 'Non tes privilexios para actualizar esta táboa',
'You are offline.' => 'Non tes conexión.',
'You have no privileges to update this table.' => 'Non tes privilexios para actualizar esta táboa.',
'Saving' => 'Gardando',
'yes' => 'si',
'no' => 'non',

View File

@@ -280,7 +280,7 @@ $translations = array(
'Default value' => 'ערך ברירת מחדל',
'Full table scan' => 'סריקה טבלה מלאה',
'Too many unsuccessful logins, try again in %d minute(s).' => 'יותר מידי נסיונות כניסה נכשלו, אנא נסה עוד %d דקות',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'תודה שהשתמש ב-adminer אנא שקול <a href="https://www.adminer.org/en/donation/">לתרום</a>.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'תודה שהשתמש ב-adminer אנא שקול <a href="https://www.adminer.org/en/donation/">לתרום</a>',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'סיסמת המאסטר פגה <a href="https://www.adminer.org/en/extension/"%s>התקן תוסף</a> על מנת להפוך את זה לתמידי',
'If you did not send this request from Adminer then close this page.' => 'אם לא אתה שלחת בקשה ל-Adminer הינך יכול לסגור חלון זה',
'You can upload a big SQL file via FTP and import it from server.' => 'ניתן לעלות קבצים ב-FTP ואז למשוך אותם מהשרת',

View File

@@ -267,7 +267,7 @@ $translations = array(
'Edit all' => 'Modifica tutto',
'HH:MM:SS' => 'HH:MM:SS',
'Drop %s?' => 'Scartare %s?',
'Tables have been optimized.' => 'Le tabelle sono state ottimizzate',
'Tables have been optimized.' => 'Le tabelle sono state ottimizzate.',
'Materialized view' => 'Vista materializzata',
'Vacuum' => 'Aspira',
'Selected' => 'Selezionato',
@@ -296,7 +296,7 @@ $translations = array(
'You are offline.' => 'Sei disconnesso.',
'You have no privileges to update this table.' => 'Non hai i privilegi per aggiornare questa tabella.',
'Saving' => 'Salvataggio',
'Unknown error.' => 'Errore sconosciuto',
'Unknown error.' => 'Errore sconosciuto.',
'Database does not support password.' => 'Il database non supporta password.',
'Disable %s or enable %s or %s extensions.' => 'Disabilita %s o abilita %s oppure %s estensioni.',
'yes' => 'si',

View File

@@ -122,7 +122,7 @@ $translations = array(
'Indexes have been altered.' => '색인을 변경했습니다.',
'Indexes' => '색인',
'Insert' => '삽입',
'Invalid credentials.' => '잘못된 로그인',
'Invalid credentials.' => '잘못된 로그인.',
'Invalid CSRF token. Send the form again.' => '잘못된 CSRF 토큰입니다. 다시 보내주십시오.',
'Invalid database.' => '잘못된 데이터베이스입니다.',
'Invalid schema.' => '잘못된 스키마입니다.',
@@ -143,7 +143,7 @@ $translations = array(
'Logout successful.' => '로그아웃을 성공했습니다.',
'Logout' => '로그아웃',
'ltr' => 'ltr',
'Maximum allowed file size is %sB.' => '파일의 최대 크기 %sB',
'Maximum allowed file size is %sB.' => '파일의 최대 크기 %sB.',
'Maximum number of allowed fields exceeded. Please increase %s.' => '정의 가능한 최대 필드 수를 초과했습니다. %s(을)를 늘리십시오.',
'Modify' => '수정',
'Move down' => '아래로',
@@ -154,7 +154,7 @@ $translations = array(
'Network' => '네트워크 형',
'New item' => '항목 만들기',
'No commands to execute.' => '실행할 수 있는 명령이 없습니다.',
'No extension' => '확장이 없습니다.',
'No extension' => '확장이 없습니다',
'No rows.' => '행이 없습니다.',
'No tables.' => '테이블이 없습니다.',
'None of the supported PHP extensions (%s) are available.' => 'PHP 확장(%s)이 설치되어 있지 않습니다.',
@@ -206,8 +206,8 @@ $translations = array(
'Schema' => '스키마',
'Search data in tables' => '테이블 내 데이터 검색',
'Search' => '검색',
'Select data' => '데이터를 선택하십시오.',
'Select database' => '데이터베이스를 선택하십시오.',
'Select data' => '데이터를 선택하십시오',
'Select database' => '데이터베이스를 선택하십시오',
'Select' => '선택',
'select' => '선택',
'Selected' => '선택됨',
@@ -238,7 +238,7 @@ $translations = array(
'Table name' => '테이블 이름',
'Table' => '테이블',
'Tables and views' => '테이블과 뷰',
'Tables have been copied.' => '테이블을 복사했습니다',
'Tables have been copied.' => '테이블을 복사했습니다.',
'Tables have been dropped.' => '테이블을 삭제했습니다.',
'Tables have been moved.' => '테이블을 옮겼습니다.',
'Tables have been truncated.' => '테이블의 데이터 내용만 지웠습니다.',
@@ -256,7 +256,7 @@ $translations = array(
'Type has been created.' => '유형을 추가했습니다.',
'Type has been dropped.' => '유형을 삭제했습니다.',
'Type' => '형',
'Unable to select the table' => '테이블을 선택할 수 없습니다.',
'Unable to select the table' => '테이블을 선택할 수 없습니다',
'Unable to upload a file.' => '파일을 업로드 할 수 없습니다.',
'Use edit link to modify this value.' => '이 값을 수정하려면 편집 링크를 사용하십시오.',
'Use' => '사용',

View File

@@ -38,7 +38,7 @@ $translations = array(
'select' => 'izvēlēties',
'Item has been deleted.' => 'Ieraksts dzests.',
'Item has been updated.' => 'Ieraksts atjaunots.',
'Item%s has been inserted.' => 'Ieraksti tika ievietoti.',
'Item%s has been inserted.' => 'Ieraksti%s tika ievietoti.',
'Edit' => 'Rediģēt',
'Insert' => 'Ievietot',
'Save and insert next' => 'Saglabāt un ievietot nākamo',

View File

@@ -254,7 +254,7 @@ $translations = array(
'Geometry' => 'Geometrie',
'File exists.' => 'Bestand bestaat reeds.',
'Attachments' => 'Bijlagen',
'%d query(s) executed OK.' => array('%d query succesvol uitgevoerd.', '%d querys succesvol uitgevoerd'),
'%d query(s) executed OK.' => array('%d query succesvol uitgevoerd.', '%d querys succesvol uitgevoerd.'),
'Show only errors' => 'Enkel fouten tonen',
'Refresh' => 'Vernieuwen',
'Invalid schema.' => 'Ongeldig schema.',
@@ -277,7 +277,7 @@ $translations = array(
'Modify' => 'Aanpassen',
'Load more data' => 'Meer data inladen',
'Loading' => 'Aan het laden',
'ATTACH queries are not supported.' => 'ATTACH queries worden niet ondersteund',
'ATTACH queries are not supported.' => 'ATTACH queries worden niet ondersteund.',
'Warnings' => 'Waarschuwingen',
'%d / ' => '%d / ',
'Limit rows' => 'Rijen beperken',
@@ -286,7 +286,7 @@ $translations = array(
'Full table scan' => 'Full table scan',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Teveel foutieve aanmeldpogingen, probeer opnieuw binnen %d minuut.', 'Teveel foutieve aanmeldpogingen, probeer opnieuw binnen %d minuten.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master wachtwoord verlopen. <a href="https://www.adminer.org/en/extension/"%s>Implementeer</a> de %s methode om het permanent te maken.',
'The action will be performed after successful login with the same credentials.' => 'Deze actie zal uitgevoerd worden na het succesvol aanmelden met dezelfde gebruikersgegevens',
'The action will be performed after successful login with the same credentials.' => 'Deze actie zal uitgevoerd worden na het succesvol aanmelden met dezelfde gebruikersgegevens.',
'Connecting to privileged ports is not allowed.' => 'Verbindingen naar geprivilegieerde poorten is niet toegestaan.',
'There is a space in the input password which might be the cause.' => 'Er staat een spatie in het wachtwoord, wat misschien de oorzaak is.',
'If you did not send this request from Adminer then close this page.' => 'Als u deze actie niet via Adminer hebt gedaan, gelieve deze pagina dan te sluiten.',
@@ -296,7 +296,7 @@ $translations = array(
'You are offline.' => 'U bent offline.',
'You have no privileges to update this table.' => 'U bent niet gemachtigd om deze tabel aan te passen.',
'Saving' => 'Opslaan',
'Unknown error.' => 'Onbekende fout',
'Unknown error.' => 'Onbekende fout.',
'Database does not support password.' => 'Database ondersteunt het wachtwoord niet.',
'Disable %s or enable %s or %s extensions.' => 'Schakel %s uit or schakel extensies %s of %s in.',
'yes' => 'ja',

View File

@@ -9,11 +9,14 @@ $translations = array(
'Password' => 'Hasło',
'Permanent login' => 'Zapamiętaj sesję',
'Login' => 'Zaloguj się',
'Logout' => 'Wyloguj',
'Logout' => 'Wyloguj się',
'Logged as: %s' => 'Zalogowany jako: %s',
'Logout successful.' => 'Wylogowano pomyślnie.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Dziękujemy za używanie Adminera, rozważ proszę <a href="https://www.adminer.org/pl/donation/">dotację</a>.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Dziękujemy za używanie Adminera, rozważ <a href="https://www.adminer.org/pl/donation/">dotację</a>.',
'Invalid credentials.' => 'Nieprawidłowe dane logowania.',
'There is a space in the input password which might be the cause.' => 'W haśle wejściowym znajduje się spacja, która może być przyczyną.',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer nie obsługuje dostępu do bazy danych bez hasła, <a href="https://www.adminer.org/pl/password/"%s>więcej informacji</a>.',
'Database does not support password.' => 'Baza danych nie obsługuje hasła.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Za dużo nieudanych prób logowania, spróbuj ponownie za %d minutę.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minuty.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minut.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Ważność hasła głównego wygasła. <a href="https://www.adminer.org/pl/extension/"%s>Zaimplementuj</a> własną metodę %s, aby ustawić je na stałe.',
'Language' => 'Język',
@@ -22,8 +25,10 @@ $translations = array(
'No extension' => 'Brak rozszerzenia',
'None of the supported PHP extensions (%s) are available.' => 'Żadne z rozszerzeń PHP umożliwiających połączenie się z bazą danych (%s) nie jest dostępne.',
'Connecting to privileged ports is not allowed.' => 'Łączenie do portów uprzywilejowanych jest niedozwolone.',
'Disable %s or enable %s or %s extensions.' => 'Wyłącz %s lub włącz rozszerzenia %s lub %s.',
'Session support must be enabled.' => 'Wymagana jest obsługa sesji w PHP.',
'Session expired, please login again.' => 'Sesja wygasła, zaloguj się ponownie.',
'The action will be performed after successful login with the same credentials.' => 'Czynność zostanie wykonana po pomyślnym zalogowaniu przy użyciu tych samych danych logowania.',
'%s version: %s through PHP extension %s' => 'Wersja %s: %s za pomocą %s',
'Refresh' => 'Odśwież',
@@ -53,6 +58,8 @@ $translations = array(
'Query executed OK, %d row(s) affected.' => array('Zapytanie wykonane pomyślnie, zmieniono %d rekord.', 'Zapytanie wykonane pomyślnie, zmieniono %d rekordy.', 'Zapytanie wykonane pomyślnie, zmieniono %d rekordów.'),
'No commands to execute.' => 'Nic do wykonania.',
'Error in query' => 'Błąd w zapytaniu',
'Unknown error.' => 'Nieznany błąd.',
'Warnings' => 'Ostrzeżenia',
'ATTACH queries are not supported.' => 'Zapytania ATTACH są niewspierane.',
'Execute' => 'Wykonaj',
'Stop on error' => 'Zatrzymaj w przypadku błędu',
@@ -75,7 +82,7 @@ $translations = array(
'You can upload a big SQL file via FTP and import it from server.' => 'Większe pliki SQL możesz wgrać na serwer poprzez FTP przed zaimportowaniem.',
'You are offline.' => 'Jesteś offline.',
'Export' => 'Eksport',
'Export' => 'Eksportuj',
'Output' => 'Rezultat',
'open' => 'otwórz',
'save' => 'zapisz',
@@ -83,6 +90,7 @@ $translations = array(
'Data' => 'Dane',
'Database' => 'Baza danych',
'DB' => 'BD',
'Use' => 'Wybierz',
'Select database' => 'Wybierz bazę danych',
'Invalid database.' => 'Nie znaleziono bazy danych.',
@@ -120,6 +128,7 @@ $translations = array(
'Tables have been moved.' => 'Tabele zostały przeniesione.',
'Copy' => 'Kopiuj',
'Tables have been copied.' => 'Tabele zostały skopiowane.',
'overwrite' => 'nadpisz',
'Routines' => 'Procedury i funkcje',
'Routine has been called, %d row(s) affected.' => array('Procedura została uruchomiona, zmieniono %d rekord.', 'Procedura została uruchomiona, zmieniono %d rekordy.', 'Procedura została uruchomiona, zmieniono %d rekordów.'),
@@ -165,15 +174,15 @@ $translations = array(
'Column name' => 'Nazwa kolumny',
'Type' => 'Typ',
'Length' => 'Długość',
'Auto Increment' => 'Auto Increment',
'Auto Increment' => 'Automatyczny przyrost',
'Options' => 'Opcje',
'Comment' => 'Komentarz',
'Default value' => 'Wartość domyślna',
'Default values' => 'Wartości domyślne',
'Drop' => 'Usuń',
'Drop %s?' => 'Usunąć %s?',
'Are you sure?' => 'Czy jesteś pewien?',
'Size' => 'Wielkość',
'Are you sure?' => 'Czy na pewno?',
'Size' => 'Rozmiar',
'Compute' => 'Oblicz',
'Move up' => 'Przesuń w górę',
'Move down' => 'Przesuń w dół',
@@ -253,14 +262,14 @@ $translations = array(
'Whole result' => 'Wybierz wszystkie',
'%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtów'),
'Import' => 'Import',
'Import' => 'Importuj',
'%d row(s) have been imported.' => array('%d rekord został zaimportowany.', '%d rekordy zostały zaimportowane.', '%d rekordów zostało zaimportowanych.'),
'File must be in UTF-8 encoding.' => 'Kodowanie pliku musi być ustawione na UTF-8.',
// in-place editing in select
'Modify' => 'Zmień',
'Ctrl+click on a value to modify it.' => 'Ctrl+kliknij wartość, aby ją edytować.',
'Use edit link to modify this value.' => 'Użyj linku edycji aby zmienić tę wartość.',
'Use edit link to modify this value.' => 'Użyj linku edycji, aby zmienić tę wartość.',
// %s can contain auto-increment value
'Item%s has been inserted.' => 'Rekord%s został dodany.',
@@ -281,7 +290,7 @@ $translations = array(
'Selected' => 'Zaznaczone',
'Clone' => 'Duplikuj',
'Delete' => 'Usuń',
'You have no privileges to update this table.' => 'Brak uprawnień do edycji tej tabeli',
'You have no privileges to update this table.' => 'Brak uprawnień do edycji tej tabeli.',
'E-mail' => 'E-mail',
'From' => 'Nadawca',
@@ -338,4 +347,12 @@ $translations = array(
'Type has been dropped.' => 'Typ został usunięty.',
'Type has been created.' => 'Typ został utworzony.',
'Alter type' => 'Zmień typ',
// Table check constraints
'Checks' => 'Kontrole',
'Create check' => 'Utwórz kontrolę',
'Alter check' => 'Zmień kontrolę',
'Check has been created.' => 'Kontrola została utworzona.',
'Check has been altered.' => 'Kontrola została zmieniona.',
'Check has been dropped.' => 'Kontrola została usunięta.',
);

View File

@@ -261,7 +261,7 @@ $translations = array(
'Please use one of the extensions %s.' => 'Folosiți una din următoarele extensii %s.',
'now' => 'acum',
'ltr' => 'ltr',
'Tables have been copied.' => 'Tabelele au fost copiate',
'Tables have been copied.' => 'Tabelele au fost copiate.',
'Copy' => 'Copiază',
'Permanent link' => 'Adresă permanentă',
'Edit all' => 'Editează tot',

View File

@@ -285,7 +285,7 @@ $translations = array(
'Default value' => 'Predvolená hodnota',
'Full table scan' => 'Prechod celej tabuľky',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Príliš veľa pokusov o prihlásenie, skúste to znova za %d minutu.', 'Príliš veľa pokusov o prihlásenie, skúste to znova za %d minuty.', 'Príliš veľa pokusov o prihlásenie, skúste to znova za %d minút.'),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Vďaka za používanie Admineru, <a href="https://www.adminer.org/cs/donation/">prispejte</a> na vývoj.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Vďaka za používanie Admineru, <a href="https://www.adminer.org/sk/donation/">prispejte</a> na vývoj.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Platnosť hlavného hesla vypršala. <a href="https://www.adminer.org/cs/extension/"%s>Implementujte</a> metodu %s, aby platilo natrvalo.',
'The action will be performed after successful login with the same credentials.' => 'Akcia sa vykoná po úspešnom prihlásení s rovnakými prihlasovacími údajmi.',
'Connecting to privileged ports is not allowed.' => 'Pripojenie k privilegovaným portom nie je povolené.',
@@ -302,4 +302,10 @@ $translations = array(
'Disable %s or enable %s or %s extensions.' => 'Zakážte %s alebo povoľte rozšírenie %s alebo %s.',
'yes' => 'áno',
'no' => 'nie',
'Checks' => 'Kontroly',
'Create check' => 'Vytvoriť kontrolu',
'Alter check' => 'Zmeniť kontrolu',
'Check has been created.' => 'Kontrola bola vytvorená.',
'Check has been altered.' => 'Kontrola bola zmenená.',
'Check has been dropped.' => 'Kontrola bola odstránená.',
);

View File

@@ -16,7 +16,7 @@ $translations = array(
'Language' => 'Језик',
'Invalid CSRF token. Send the form again.' => 'Неважећи CSRF код. Проследите поново форму.',
'No extension' => 'Без додатака',
'None of the supported PHP extensions (%s) are available.' => 'Ниједан од подржаних PHP додатака није доступан.',
'None of the supported PHP extensions (%s) are available.' => 'Ниједан од подржаних PHP додатака (%s) није доступан.',
'Session support must be enabled.' => 'Морате омогућити подршку за сесије.',
'Session expired, please login again.' => 'Ваша сесија је истекла, пријавите се поново.',
'%s version: %s through PHP extension %s' => '%s верзија: %s помоћу PHP додатка је %s',

View File

@@ -229,7 +229,7 @@ $translations = array(
'Create sequence' => 'வ‌ரிசைமுறையை உருவாக்கு',
'User types' => 'ப‌ய‌னாள‌ர் வ‌கைக‌ள்',
'Create type' => 'வ‌கையை உருவாக்கு',
'Item%s has been inserted.' => 'உருப்ப‌டி (Item) சேர்க்க‌ப்ப‌ட்ட‌து.',
'Item%s has been inserted.' => 'உருப்ப‌டி (Item%s) சேர்க்க‌ப்ப‌ட்ட‌து.',
'Schema has been dropped.' => 'அமைப்புமுறை நீக்க‌ப்ப‌ட்ட‌து.',
'Schema has been created.' => 'அமைப்புமுறை உருவாக்க‌ப்ப‌ட்ட‌து.',
'Schema has been altered.' => 'அமைப்புமுறை மாற்ற‌ப்ப‌ட்ட‌து.',

View File

@@ -58,7 +58,7 @@ $translations = array(
'ATTACH queries are not supported.' => 'ATTACH sorguları desteklenmiyor.',
'Execute' => 'Çalıştır',
'Stop on error' => 'Hata oluşursa dur',
'Show only errors' => 'Sadece hataları göster.',
'Show only errors' => 'Sadece hataları göster',
// sprintf() format for time of the command
'%.3f s' => '%.3f s',
'History' => 'Geçmiş',
@@ -225,7 +225,7 @@ $translations = array(
'Trigger has been dropped.' => 'Tetik silindi.',
'Trigger has been altered.' => 'Tetik değiştirildi.',
'Trigger has been created.' => 'Tetik oluşturuldu.',
'Alter trigger' => 'Tetiği değiştir.',
'Alter trigger' => 'Tetiği değiştir',
'Create trigger' => 'Tetik oluştur',
'Time' => 'Zaman',
'Event' => 'Olay',

View File

@@ -61,7 +61,7 @@ $translations = array(
'File upload' => 'Tải tệp lên',
'From server' => 'Dùng tệp trên máy chủ',
'Webserver file %s' => 'Tệp trên máy chủ',
'Webserver file %s' => 'Tệp trên máy chủ %s',
'Run file' => 'Chạy tệp',
'File does not exist.' => 'Tệp không tồn tại.',
'File uploads are disabled.' => 'Chức năng tải tệp lên đã bị cấm.',

View File

@@ -18,11 +18,12 @@ $translations = array(
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Xx, <a href="https://www.adminer.org/en/password/"%s>xx</a>.',
'Database does not support password.' => 'Xx.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Xx %d.', 'Xx %d.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => '<a href="https://www.adminer.org/en/extension/"%s>Xx</a> %s xx.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Xx. <a href="https://www.adminer.org/en/extension/"%s>Xx</a> %s xx.',
'Language' => 'Xx',
'Invalid CSRF token. Send the form again.' => 'Xx.',
'If you did not send this request from Adminer then close this page.' => 'Xx.',
'No extension' => 'Xx',
// %s contains the list of the extensions, e.g. 'mysqli, PDO_MySQL'
'None of the supported PHP extensions (%s) are available.' => 'Xx (%s).',
'Connecting to privileged ports is not allowed.' => 'Xx.',
'Disable %s or enable %s or %s extensions.' => 'Xx %s xx %s xx %s xx.',
@@ -33,7 +34,7 @@ $translations = array(
'Refresh' => 'Xx',
// text direction - 'ltr' or 'rtl'
'ltr' => 'xx',
'ltr' => 'ltr',
'Privileges' => 'Xx',
'Create user' => 'Xx',
@@ -254,6 +255,7 @@ $translations = array(
'Full table scan' => 'Xx',
'Unable to select the table' => 'Xx',
'No rows.' => 'Xx.',
// used in SQL query limit and it is followed by another number, e.g. '10 / 50 rows' meaning 10 of 50 rows
'%d / ' => '%d / ',
'%d row(s)' => array('%d xx', '%d xx'),
'Page' => 'Xx',
@@ -272,7 +274,7 @@ $translations = array(
'Ctrl+click on a value to modify it.' => 'Xx.',
'Use edit link to modify this value.' => 'Xx.',
// %s can contain auto-increment value
// %s can contain auto-increment value, e.g. ' 123'
'Item%s has been inserted.' => 'Xx%s.',
'Item has been deleted.' => 'Xx.',
'Item has been updated.' => 'Xx.',

View File

@@ -12,10 +12,10 @@ $translations = array(
'Logout' => '登出',
'Logged as: %s' => '登錄為: %s',
'Logout successful.' => '成功登出。',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => '感謝使用Adminer請考慮為我們<a href="https://www.adminer.org/en/donation/">捐款(英文網頁)</a>.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => '感謝使用Adminer請考慮為我們<a href="https://www.adminer.org/en/donation/">捐款(英文網頁)</a>',
'Invalid credentials.' => '無效的憑證。',
'There is a space in the input password which might be the cause.' => '您輸入的密碼中有一個空格,這可能是導致問題的原因。',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer預設不支援訪問沒有密碼的資料庫<a href="https://www.adminer.org/en/password/"%s>詳情見這裡</a>.',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer預設不支援訪問沒有密碼的資料庫<a href="https://www.adminer.org/en/password/"%s>詳情見這裡</a>',
'Database does not support password.' => '資料庫不支援密碼。',
'Too many unsuccessful logins, try again in %d minute(s).' => '登錄失敗次數過多,請 %d 分鐘後重試。',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => '主密碼已過期。<a href="https://www.adminer.org/en/extension/"%s>請擴展</a> %s 方法讓它永久化。',
@@ -47,7 +47,7 @@ $translations = array(
'Revoke' => '廢除',
'Process list' => '處理程序列表',
'%d process(es) have been killed.' => '%d 個 Process(es) 被終止',
'%d process(es) have been killed.' => '%d 個 Process(es) 被終止',
'Kill' => '終止',
'Variables' => '變數',
@@ -74,10 +74,10 @@ $translations = array(
'From server' => '從伺服器',
'Webserver file %s' => '網頁伺服器檔案 %s',
'Run file' => '執行檔案',
'File does not exist.' => '檔案不存在',
'File does not exist.' => '檔案不存在',
'File uploads are disabled.' => '檔案上傳已經被停用。',
'Unable to upload a file.' => '無法上傳檔案。',
'Maximum allowed file size is %sB.' => '允許的檔案上限大小為 %sB',
'Maximum allowed file size is %sB.' => '允許的檔案上限大小為 %sB',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'POST 資料太大。減少資料或者增加 %s 的設定值。',
'You can upload a big SQL file via FTP and import it from server.' => '您可以通過FTP上傳大型SQL檔並從伺服器導入。',
'You are offline.' => '您離線了。',
@@ -128,11 +128,11 @@ $translations = array(
'Move' => '轉移',
'Tables have been moved.' => '已轉移資料表。',
'Copy' => '複製',
'Tables have been copied.' => '資料表已經複製',
'Tables have been copied.' => '資料表已經複製',
'overwrite' => '覆蓋',
'Routines' => '程序',
'Routine has been called, %d row(s) affected.' => '程序已被執行,%d 行被影響',
'Routine has been called, %d row(s) affected.' => '程序已被執行,%d 行被影響',
'Call' => '呼叫',
'Parameter name' => '參數名稱',
'Create procedure' => '建立預存程序',
@@ -274,7 +274,7 @@ $translations = array(
// %s can contain auto-increment value
'Item%s has been inserted.' => '已新增項目 %s。',
'Item has been deleted.' => '該項目已被刪除',
'Item has been deleted.' => '該項目已被刪除',
'Item has been updated.' => '已更新項目。',
'%d item(s) have been affected.' => '%d 個項目受到影響。',
'New item' => '新增項目',

View File

@@ -12,10 +12,10 @@ $translations = array(
'Logout' => '登出',
'Logged as: %s' => '登录用户:%s',
'Logout successful.' => '成功登出。',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => '感谢使用Adminer请考虑为我们<a href="https://www.adminer.org/en/donation/">捐款(英文页面)</a>.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => '感谢使用Adminer请考虑为我们<a href="https://www.adminer.org/en/donation/">捐款(英文页面)</a>',
'Invalid credentials.' => '无效凭据。',
'There is a space in the input password which might be the cause.' => '您输入的密码中有一个空格,这可能是导致问题的原因。',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer默认不支持访问没有密码的数据库<a href="https://www.adminer.org/en/password/"%s>详情见这里</a>.',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer默认不支持访问没有密码的数据库<a href="https://www.adminer.org/en/password/"%s>详情见这里</a>',
'Database does not support password.' => '数据库不支持密码。',
'Too many unsuccessful logins, try again in %d minute(s).' => '登录失败次数过多,请 %d 分钟后重试。',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => '主密码已过期。<a href="https://www.adminer.org/en/extension/"%s>请扩展</a> %s 方法让它永久化。',
@@ -47,7 +47,7 @@ $translations = array(
'Revoke' => '废除',
'Process list' => '进程列表',
'%d process(es) have been killed.' => '%d 个进程被终止',
'%d process(es) have been killed.' => '%d 个进程被终止',
'Kill' => '终止',
'Variables' => '变量',
@@ -208,7 +208,7 @@ $translations = array(
'Alter indexes' => '修改索引',
'Add next' => '下一行插入',
'Index Type' => '索引类型',
'Column (length)' => '列(长度)',
// 'Column (length)' => '列(长度)',
'Foreign keys' => '外键',
'Foreign key' => '外键',

View File

@@ -34,6 +34,7 @@ if (!$_POST && $PROCEDURE != "") {
$collations = get_vals("SHOW CHARACTER SET");
sort($collations);
$routine_languages = routine_languages();
echo ($collations ? "<datalist id='collations'>" . optionlist($collations) . "</datalist>" : "");
?>
<form action="" method="post" id="form">

View File

@@ -74,7 +74,9 @@ foreach ($schema as $name => $table) {
$left1 = $left - $table_pos[$name][1];
$i = 0;
foreach ($ref[0] as $source) {
echo "\n<div class='references' title='" . h($target_name) . "' id='refs$left-" . ($i++) . "' style='left: $left1" . "em; top: " . $table["fields"][$source]["pos"] . "em; padding-top: .5em;'><div style='border-top: 1px solid Gray; width: " . (-$left1) . "em;'></div></div>";
echo "\n<div class='references' title='" . h($target_name) . "' id='refs$left-" . ($i++) . "' style='left: $left1" . "em; top: " . $table["fields"][$source]["pos"] . "em; padding-top: .5em;'>"
. "<div style='border-top: 1px solid gray; width: " . (-$left1) . "em;'></div></div>"
;
}
}
}
@@ -84,8 +86,9 @@ foreach ($schema as $name => $table) {
$left1 = $left - $table_pos[$name][1];
$i = 0;
foreach ($columns as $target) {
echo "\n<div class='references' title='" . h($target_name) . "' id='refd$left-" . ($i++) . "' style='left: $left1" . "em; top: " . $table["fields"][$target]["pos"] . "em; height: 1.25em; background: url(../adminer/static/arrow.gif) no-repeat right center;'>"
. "<div style='height: .5em; border-bottom: 1px solid Gray; width: " . (-$left1) . "em;'></div>"
echo "\n<div class='references' title='" . h($target_name) . "' id='refd$left-" . ($i++) . "'"
. " style='left: $left1" . "em; top: " . $table["fields"][$target]["pos"] . "em; height: 1.25em; background: url(../adminer/static/arrow.gif) no-repeat right center;'>"
. "<div style='height: .5em; border-bottom: 1px solid gray; width: " . (-$left1) . "em;'></div>"
. "</div>"
;
}
@@ -106,7 +109,7 @@ foreach ($schema as $name => $table) {
$min_pos = min($min_pos, $pos1, $pos2);
$max_pos = max($max_pos, $pos1, $pos2);
}
echo "<div class='references' id='refl$left' style='left: $left" . "em; top: $min_pos" . "em; padding: .5em 0;'><div style='border-right: 1px solid Gray; margin-top: 1px; height: " . ($max_pos - $min_pos) . "em;'></div></div>\n";
echo "<div class='references' id='refl$left' style='left: $left" . "em; top: $min_pos" . "em; padding: .5em 0;'><div style='border-right: 1px solid gray; margin-top: 1px; height: " . ($max_pos - $min_pos) . "em;'></div></div>\n";
}
}
}

View File

@@ -25,7 +25,7 @@ if ($_GET["script"] == "db") {
$sums[$key] += ($table_status["Engine"] != "InnoDB" || $key != "Data_free" ? $table_status[$key] : 0);
}
} elseif (array_key_exists($key, $table_status)) {
json_row("$key-$name");
json_row("$key-$name", "?");
}
}
}

View File

@@ -11,15 +11,24 @@ parse_str($_COOKIE["adminer_import"], $adminer_import);
$rights = array(); // privilege => 0
$columns = array(); // selectable columns
$search_columns = array(); // searchable columns
$order_columns = array(); // searchable columns
$text_length = null;
foreach ($fields as $key => $field) {
$name = $adminer->fieldName($field);
$name_plain = html_entity_decode(strip_tags($name), ENT_QUOTES);
if (isset($field["privileges"]["select"]) && $name != "") {
$columns[$key] = html_entity_decode(strip_tags($name), ENT_QUOTES);
$columns[$key] = $name_plain;
if (is_shortable($field)) {
$text_length = $adminer->selectLengthProcess();
}
}
if (isset($field["privileges"]["where"]) && $name != "") {
$search_columns[$key] = $name_plain;
}
if (isset($field["privileges"]["order"]) && $name != "") {
$order_columns[$key] = $name_plain;
}
$rights += $field["privileges"];
}
@@ -81,9 +90,8 @@ if ($_POST && !$error) {
. convert_fields($columns, $fields, $select)
. "\nFROM " . table($TABLE);
$group_by = ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : "");
if (!is_array($_POST["check"]) || $primary) {
$query = "SELECT $from$where_check$group_by";
} else {
$query = "SELECT $from$where_check$group_by";
if (is_array($_POST["check"]) && !$primary) {
$union = array();
foreach ($_POST["check"] as $val) {
// where is not unique so OR can't be used
@@ -92,6 +100,7 @@ if ($_POST && !$error) {
$query = implode(" UNION ALL ", $union);
}
$adminer->dumpData($TABLE, "table", $query);
$adminer->dumpFooter();
exit;
}
@@ -253,8 +262,8 @@ if (!$columns && support("table")) {
echo '<input type="hidden" name="select" value="' . h($TABLE) . '">';
echo "</div>\n";
$adminer->selectColumnsPrint($select, $columns);
$adminer->selectSearchPrint($where, $columns, $indexes);
$adminer->selectOrderPrint($order, $columns, $indexes);
$adminer->selectSearchPrint($where, $search_columns, $indexes);
$adminer->selectOrderPrint($order, $order_columns, $indexes);
$adminer->selectLimitPrint($limit);
$adminer->selectLengthPrint($text_length);
$adminer->selectActionPrint($indexes);
@@ -262,7 +271,7 @@ if (!$columns && support("table")) {
$page = $_GET["page"];
if ($page == "last") {
$found_rows = $connection->result(count_rows($TABLE, $where, $is_group, $group));
$found_rows = get_val(count_rows($TABLE, $where, $is_group, $group));
$page = floor(max(0, $found_rows - 1) / $limit);
}
@@ -309,7 +318,7 @@ if (!$columns && support("table")) {
// use count($rows) without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest)
if ($_GET["page"] != "last" && $limit != "" && $group && $is_group && JUSH == "sql") {
$found_rows = $connection->result(" SELECT FOUND_ROWS()"); // space to allow mysql.trace_mode
$found_rows = get_val(" SELECT FOUND_ROWS()"); // space to allow mysql.trace_mode
}
if (!$rows) {
@@ -339,12 +348,15 @@ if (!$columns && support("table")) {
$column = idf_escape($key);
$href = remove_from_uri('(order|desc)[^=]*|page') . '&order%5B0%5D=' . urlencode($key);
$desc = "&desc%5B0%5D=1";
$sortable = isset($field["privileges"]["order"]);
echo "<th id='th[" . h(bracket_escape($key)) . "]'>" . script("mixin(qsl('th'), {onmouseover: partial(columnMouse), onmouseout: partial(columnMouse, ' hidden')});", "");
echo '<a href="' . h($href . ($order[0] == $column || $order[0] == $key || (!$order && $is_group && $group[0] == $column) ? $desc : '')) . '">'; // $order[0] == $key - COUNT(*)
echo apply_sql_function($val["fun"], $name) . "</a>"; //! columns looking like functions
$fun = apply_sql_function($val["fun"], $name); //! columns looking like functions
echo ($sortable ? '<a href="' . h($href . ($order[0] == $column || $order[0] == $key || (!$order && $is_group && $group[0] == $column) ? $desc : '')) . '">' . "$fun</a>" : $fun); // $order[0] == $key - COUNT(*)
echo "<span class='column hidden'>";
echo "<a href='" . h($href . $desc) . "' title='" . lang('descending') . "' class='text'> ↓</a>";
if (!$val["fun"]) {
if ($sortable) {
echo "<a href='" . h($href . $desc) . "' title='" . lang('descending') . "' class='text'> ↓</a>";
}
if (!$val["fun"] && isset($field["privileges"]["where"])) {
echo '<a href="#fieldset-search" title="' . lang('Search') . '" class="text jsonly"> =</a>';
echo script("qsl('a').onclick = partial(selectSearch, '" . js_escape($key) . "');");
}
@@ -440,7 +452,7 @@ if (!$columns && support("table")) {
$id = h("val[$unique_idf][" . bracket_escape($key) . "]");
$value = $_POST["val"][$unique_idf][bracket_escape($key)];
$editable = !is_array($row[$key]) && is_utf8($val) && $rows[$n][$key] == $row[$key] && !$functions[$key] && !$field["generated"];
$text = preg_match('~text|lob~', $field["type"]);
$text = preg_match('~text|json|lob~', $field["type"]);
echo "<td id='$id'";
if (($_GET["modify"] && $editable) || $value !== null) {
$h_value = h($value !== null ? $value : $row[$key]);
@@ -576,7 +588,7 @@ if (!$columns && support("table")) {
echo script("qsl('a').onclick = partial(toggle, 'import');", "");
echo "<span id='import'" . ($_POST["import"] ? "" : " class='hidden'") . ">: ";
echo "<input type='file' name='csv_file'> ";
echo html_select("separator", array("csv" => "CSV,", "csv;" => "CSV;", "tsv" => "TSV"), $adminer_import["format"], 1); // 1 - select
echo html_select("separator", array("csv" => "CSV,", "csv;" => "CSV;", "tsv" => "TSV"), $adminer_import["format"]);
echo " <input type='submit' name='import' value='" . lang('Import') . "'>";
echo "</span>";
echo "</div>";

View File

@@ -5,6 +5,7 @@ if (!$error && $_POST["export"]) {
dump_headers("sql");
$adminer->dumpTable("", "");
$adminer->dumpData("", "table", $_POST["query"]);
$adminer->dumpFooter();
exit;
}
@@ -30,7 +31,7 @@ if (!$error && $_POST) {
), "rb");
$query = ($fp ? fread($fp, 1e6) : false);
} else {
$query = get_file("sql_file", true);
$query = get_file("sql_file", true, ";");
}
if (is_string($query)) { // get_file() returns error as number, fread() as false

47
adminer/static/dark.css Normal file
View File

@@ -0,0 +1,47 @@
/** @author Robert Mesaros, https://www.rmsoft.sk */
body { color: #829bb0; background: #002240; }
a { color: #517fa8; }
a:visited { color: #517fa8; }
a:link:hover, a:visited:hover { color: #9bc0e1; }
h1 { border-color: #5e94c1; color: #ffddbf; background: #154269; }
h2 { border-color: #a3bdd3; color: #000; background: #3c678d; }
td, th { border-color: #0e416d; }
th { background: #11385a; }
thead td, thead th { color: #a8b05f; background: #011d35; }
thead th a { color: #a8b05f; }
fieldset { border-color: #16548a; }
code { background: #11385a; }
code[class^="jush-"] { color: #002240; background: #81a0bc; padding: .2em .5em; }
tbody tr:hover td, tbody tr:hover th { background: #133553; }
pre.jush { background: #a7c3dc; }
input.default { box-shadow: 1px 1px 1px #888; }
input.required, input.maxlength { box-shadow: 1px 1px 1px red; }
.version { color: #888; }
.js .column { background: #011d35; }
.error { color: red; background: #efdada; border: 1px solid #e76f6f; }
.error b { background: #002240; }
.message { color: #0b860b; background: #efe; border: 1px solid #7fbd7f; }
.message table { color: #829bb0; background: #002240; }
.char { color: #a949a9; }
.date { color: #59c159; }
.enum { color: #d55c5c; }
.binary { color: #9bc0e1; }
.odds tbody tr:nth-child(2n) { background: #042541; }
.js .checkable .checked td, .js .checkable .checked th { background: #10395c; color: #67a4a5; }
.js .checkable .checked:hover td, .js .checkable .checked:hover th { background: #133553; }
.js .checkable .checked a { color: #67a4a5; }
.icon { background-color: #062642; }
.icon:hover { background-color: #d1394e; }
.footer { border-top-color: rgba(0, 34, 64, .7); border-image-source: linear-gradient(rgba(0, 34, 64, 0.2), #002240); }
.footer > div { background: #002240; }
#menu p, #logins, #tables { border-color: #326b9c; }
#logins a, #tables a, #tables span { background: #002240; }
#breadcrumb { background: #154269; }
#h1 { color: #ffddbf; }
#version { color: #d2b397; }
#schema .table { border-color: #093459; }
#help { border-color: #666; background: #c7e4fe; }
#schema div.table a { color: #3c7bb3; }
#menu .active { color: #398c8d; }
#edit-fields tbody tr:hover td, #edit-fields tbody tr:hover th { background: #3b6f9d; }

View File

@@ -1,4 +1,5 @@
/** @author Ondrej Valka, http://valka.info */
body { color: #000; background: #fff; font: 90%/1.25 Verdana, Arial, Helvetica, sans-serif; margin: 0; min-width: fit-content; }
a { color: blue; text-decoration: none; }
a:visited { color: navy; }
@@ -25,12 +26,12 @@ pre { margin: 1em 0 0; }
td pre { margin: 0; }
pre, textarea { font: 100%/1.25 monospace; }
pre.jush { background: #fff; }
pre code { display: block; }
input, textarea { box-sizing: border-box; }
input, select { vertical-align: middle; }
input[type="radio"] { vertical-align: text-bottom; }
input.default { box-shadow: 1px 1px 1px #777; }
input.required { box-shadow: 1px 1px 1px red; }
input.maxlength { box-shadow: 1px 1px 1px red; }
input.required, input.maxlength { box-shadow: 1px 1px 1px red; }
input.wayoff { left: -1000px; position: absolute; }
.block { display: block; }
.version { color: #777; font-size: 62%; }
@@ -47,18 +48,16 @@ input.wayoff { left: -1000px; position: absolute; }
.date { color: #7F007F; }
.enum { color: #007F7F; }
.binary { color: red; }
.odds tbody tr:nth-child(2n) td { background: #F5F5F5; }
.odds tbody tr:nth-child(2n) { background: #F5F5F5; }
.js .checkable .checked td, .js .checkable .checked th { background: #ddf; }
.time { color: silver; font-size: 70%; }
.function { text-align: right; }
.number { text-align: right; }
.datetime { text-align: right; }
.type { width: 15ex; width: auto\9; }
.options select { width: 20ex; width: auto\9; }
.function, .number, .datetime { text-align: right; }
.type { width: 15ex; }
.options select, .options input { width: 20ex; }
.view { font-style: italic; }
.active { font-weight: bold; }
.sqlarea { width: 98%; }
.explain { white-space: pre; }
.explain table { white-space: pre; }
.icon { width: 18px; height: 18px; background-color: navy; }
.icon:hover { background-color: red; }
.size { width: 7ex; }

View File

@@ -65,7 +65,7 @@ function mixin(target, source) {
/** Add or remove CSS class
* @param HTMLElement
* @param string
* @param [bool]
* @param [boolean]
*/
function alterClass(el, className, enable) {
if (el) {
@@ -79,7 +79,7 @@ function alterClass(el, className, enable) {
*/
function toggle(id) {
var el = qs('#' + id);
el.className = (el.className == 'hidden' ? '' : 'hidden');
alterClass(el, 'hidden', !/(^|\s)hidden(\s|$)/.test(el.className));
return false;
}
@@ -568,7 +568,7 @@ function functionChange() {
* @this HTMLTableCellElement
*/
function skipOriginal(first) {
var fnSelect = this.previousSibling.firstChild;
var fnSelect = qs('select', this.previousSibling);
if (fnSelect.selectedIndex < first) {
fnSelect.selectedIndex = first;
}

View File

@@ -45,7 +45,11 @@ if (!is_view($table_status)) {
foreach ($foreign_keys as $name => $foreign_key) {
echo "<tr title='" . h($name) . "'>";
echo "<th><i>" . implode("</i>, <i>", array_map('Adminer\h', $foreign_key["source"])) . "</i>";
echo "<td><a href='" . h($foreign_key["db"] != "" ? preg_replace('~db=[^&]*~', "db=" . urlencode($foreign_key["db"]), ME) : ($foreign_key["ns"] != "" ? preg_replace('~ns=[^&]*~', "ns=" . urlencode($foreign_key["ns"]), ME) : ME)) . "table=" . urlencode($foreign_key["table"]) . "'>"
$link = ($foreign_key["db"] != ""
? preg_replace('~db=[^&]*~', "db=" . urlencode($foreign_key["db"]), ME)
: ($foreign_key["ns"] != "" ? preg_replace('~ns=[^&]*~', "ns=" . urlencode($foreign_key["ns"]), ME) : ME)
);
echo "<td><a href='" . h($link . "table=" . urlencode($foreign_key["table"])) . "'>"
. ($foreign_key["db"] != "" && $foreign_key["db"] != DB ? "<b>" . h($foreign_key["db"]) . "</b>." : "")
. ($foreign_key["ns"] != "" && $foreign_key["ns"] != $_GET["ns"] ? "<b>" . h($foreign_key["ns"]) . "</b>." : "")
. h($foreign_key["table"])

View File

@@ -56,7 +56,7 @@ if ($_POST && !$error) {
$pass = $_POST["pass"];
if ($pass != '' && !$_POST["hashed"] && !min_version(8)) {
// compute hash in a separate query so that plain text password is not saved to history
$pass = $connection->result("SELECT PASSWORD(" . q($pass) . ")");
$pass = get_val("SELECT PASSWORD(" . q($pass) . ")");
$error = !$pass;
}
@@ -120,11 +120,11 @@ if ($_POST && !$error) {
page_header((isset($_GET["host"]) ? lang('Username') . ": " . h("$USER@$_GET[host]") : lang('Create user')), $error, array("privileges" => array('', lang('Privileges'))));
if ($_POST) {
$row = $_POST;
$row = $_POST;
if ($row) {
$grants = $new_grants;
} else {
$row = $_GET + array("host" => $connection->result("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', -1)")); // create user on the same domain by default
$row = $_GET + array("host" => get_val("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', -1)")); // create user on the same domain by default
$row["pass"] = $old_pass;
if ($old_pass != "") {
$row["hashed"] = true;
@@ -148,7 +148,10 @@ echo "<table class='odds'>\n";
echo "<thead><tr><th colspan='2'>" . lang('Privileges') . doc_link(array('sql' => "grant.html#priv_level"));
$i = 0;
foreach ($grants as $object => $grant) {
echo '<th>' . ($object != "*.*" ? "<input name='objects[$i]' value='" . h($object) . "' size='10' autocapitalize='off'>" : "<input type='hidden' name='objects[$i]' value='*.*' size='10'>*.*"); //! separate db, table, columns, PROCEDURE|FUNCTION, routine
echo '<th>' . ($object != "*.*"
? "<input name='objects[$i]' value='" . h($object) . "' size='10' autocapitalize='off'>"
: "<input type='hidden' name='objects[$i]' value='*.*' size='10'>*.*"
); //! separate db, table, columns, PROCEDURE|FUNCTION, routine
$i++;
}
echo "</thead>\n";

View File

@@ -1,8 +1,43 @@
Adminer 5.0.5 (released 2025-03-13):
MySQL: Display converting function for binary, bit or geometry fields
MySQL: Display default values of binary columns
MySQL: Allow setting default values of json column
MariaDB: Don't display NULL as default value (regression from 5.0.0)
PostgreSQL PDO: Escape bytea values (bug #218)
CockroachDB: Display version
CockroachDB: Recognize unique_rowid() as auto_increment
MS SQL: Fix editing rows with datetime column in primary key
MongoDB: Move to plugin
CSS: Add dark theme
Adminer 5.0.4 (released 2025-03-11):
Compile: Fix shortening in private methods (regression from 5.0.3)
Adminer 5.0.3 (released 2025-03-11):
Fix gzip export (bug #896, regression from 5.0.0)
Fix importing multiple SQL files not terminated by semicolon
Use <datalist> for altering collations
MySQL: Allow setting default values of text column
MySQL: Stop treating enum and set as numbers (bug #475)
MySQL, MariaDB: Fix default values with ' (bug #895)
MariaDB: Fix creating and altering generated columns (bug #897)
PostgreSQL: Fix "where" and "order" privileges (bug #902, regression from 5.0.2)
SQLite: Fix creating table in compiled version (bug #901, regression from 5.0.0)
Elastic: Do not pass null values on insert (PR #892)
Elastic: Fix displaying sparse rows (PR #893)
Plugins: Add method dumpFooter()
Adminer 5.0.2 (released 2025-03-10):
PostgreSQL: Fix setting NULL and original value on enum (bug #884)
CockroachDB: Add support via PostgreSQL driver
Elasticsearch: Add support for "where" and "order" field privilege
Adminer 5.0.1 (released 2025-03-07):
Fix bulk operations with tables
Fix bulk operations with tables (regression from 5.0.0)
Remove duplicate columns from select (bug #670)
MariaDB: Fix link to status variable doc (bug #658)
PostgreSQL: Support indexes on materialized views (PR #467)
Elasticsearch: Drop support for version < 7
Adminer 5.0.0 (released 2025-03-07):
Speed up with disabled output buffering
@@ -58,7 +93,7 @@ SQLite: Show all supported pragmas in Variables
MS SQL: Allow altering table in non-default schema (bug #405)
MS SQL: Fix default values (bug #732, bug #733)
MS SQL: Fix length of nvarchar columns
Editor: PDO: Select value of foreign key in edit (bug #847)
Editor PDO: Select value of foreign key in edit (bug #847)
Mobile devices: Use device width
Adminer 4.16.0 (released 2025-02-20):
@@ -77,6 +112,7 @@ Escape unknown field in select
HTTP drivers: Don't allow path in server name
HTTP drivers: Hide connection error message
SimpleDB: Disable XML entity loader
Latvian translation
Adminer 4.14.0:
Use autofocus HTML attribute
@@ -540,7 +576,7 @@ MySQL: Speed up updating rows without numeric or UTF-8 primary key
Non-MySQL: Descending indexes
PostgreSQL: Fix detecting oid column in PDO
PostgreSQL: Handle timestamp types (bug #324)
Add Korean translation
Korean translation
Adminer 3.7.0 (released 2013-05-19):
Allow more SQL files to be uploaded at the same time

View File

@@ -2,12 +2,9 @@
<?php
include __DIR__ . "/adminer/include/version.inc.php";
include __DIR__ . "/adminer/include/errors.inc.php";
include __DIR__ . "/php_shrink.inc.php";
include __DIR__ . "/externals/JsShrink/jsShrink.php";
function add_apo_slashes($s) {
return addcslashes($s, "\\'");
}
function add_quo_slashes($s) {
$return = $s;
$return = addcslashes($return, "\n\r\$\"\\");
@@ -41,7 +38,7 @@ function put_file($match) {
return $match[0]; // processed later
}
$return = file_get_contents(__DIR__ . "/$project/$match[2]");
$return = str_replace("namespace Adminer;\n", "", $return);
$return = preg_replace('~namespace Adminer;\s*~', '', $return);
if (basename($match[2]) == "file.inc.php") {
$return = str_replace("\n// caching headers added in compile.php", (preg_match('~-dev$~', $VERSION) ? '' : '
if ($_SERVER["HTTP_IF_MODIFIED_SINCE"]) {
@@ -212,126 +209,8 @@ if (!$translations) {
';
}
function short_identifier($number, $chars) {
$return = '';
while ($number >= 0) {
$return .= $chars[$number % strlen($chars)];
$number = floor($number / strlen($chars)) - 1;
}
return $return;
}
// based on http://latrine.dgx.cz/jak-zredukovat-php-skripty
function php_shrink($input) {
global $VERSION;
$special_variables = array_flip(array('$this', '$GLOBALS', '$_GET', '$_POST', '$_FILES', '$_COOKIE', '$_SESSION', '$_SERVER', '$http_response_header', '$php_errormsg'));
$short_variables = array();
$shortening = true;
$tokens = token_get_all($input);
// remove unnecessary { }
//! change also `while () { if () {;} }` to `while () if () ;` but be careful about `if () { if () { } } else { }
$shorten = 0;
$opening = -1;
foreach ($tokens as $i => $token) {
if (in_array($token[0], array(T_IF, T_ELSE, T_ELSEIF, T_WHILE, T_DO, T_FOR, T_FOREACH), true)) {
$shorten = ($token[0] == T_FOR ? 4 : 2);
$opening = -1;
} elseif (in_array($token[0], array(T_SWITCH, T_FUNCTION, T_CLASS, T_CLOSE_TAG), true)) {
$shorten = 0;
} elseif ($token === ';') {
$shorten--;
} elseif ($token === '{') {
if ($opening < 0) {
$opening = $i;
} elseif ($shorten > 1) {
$shorten = 0;
}
} elseif ($token === '}' && $opening >= 0 && $shorten == 1) {
unset($tokens[$opening]);
unset($tokens[$i]);
$shorten = 0;
$opening = -1;
}
}
$tokens = array_values($tokens);
foreach ($tokens as $i => $token) {
if ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
$short_variables[$token[1]]++;
}
}
arsort($short_variables);
$chars = implode(range('a', 'z')) . '_' . implode(range('A', 'Z'));
// preserve variable names between versions if possible
$short_variables2 = array_splice($short_variables, strlen($chars));
ksort($short_variables);
ksort($short_variables2);
$short_variables += $short_variables2;
foreach (array_keys($short_variables) as $number => $key) {
$short_variables[$key] = short_identifier($number, $chars); // could use also numbers and \x7f-\xff
}
$set = array_flip(preg_split('//', '!"#$%&\'()*+,-./:;<=>?@[]^`{|}'));
$space = '';
$output = '';
$in_echo = false;
$doc_comment = false; // include only first /**
for (reset($tokens); list($i, $token) = each($tokens);) {
if (!is_array($token)) {
$token = array(0, $token);
}
if (
$tokens[$i+2][0] === T_CLOSE_TAG && $tokens[$i+3][0] === T_INLINE_HTML && $tokens[$i+4][0] === T_OPEN_TAG
&& strlen(add_apo_slashes($tokens[$i+3][1])) < strlen($tokens[$i+3][1]) + 3
) {
$tokens[$i+2] = array(T_ECHO, 'echo');
$tokens[$i+3] = array(T_CONSTANT_ENCAPSED_STRING, "'" . add_apo_slashes($tokens[$i+3][1]) . "'");
$tokens[$i+4] = array(0, ';');
}
if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE || ($token[0] == T_DOC_COMMENT && $doc_comment)) {
$space = "\n";
} else {
if ($token[0] == T_DOC_COMMENT) {
$doc_comment = true;
$token[1] = substr_replace($token[1], "* @version $VERSION\n", -2, 0);
}
if ($token[0] == T_VAR) {
$shortening = false;
} elseif (!$shortening) {
if ($token[1] == ';') {
$shortening = true;
}
} elseif ($token[0] == T_ECHO) {
$in_echo = true;
} elseif ($token[1] == ';' && $in_echo) {
if ($tokens[$i+1][0] === T_WHITESPACE && $tokens[$i+2][0] === T_ECHO) {
next($tokens);
$i++;
}
if ($tokens[$i+1][0] === T_ECHO) {
// join two consecutive echos
next($tokens);
$token[1] = ','; // '.' would conflict with "a".1+2 and would use more memory //! remove ',' and "," but not $var","
} else {
$in_echo = false;
}
} elseif ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
$token[1] = '$' . $short_variables[$token[1]];
}
if (isset($set[substr($output, -1)]) || isset($set[$token[1][0]])) {
$space = '';
}
$output .= $space . $token[1];
$space = '';
}
}
return $output;
}
function minify_css($file) {
return lzw_compress(preg_replace('~\s*([:;{},])\s*~', '\1', preg_replace('~/\*.*\*/~sU', '', $file)));
return lzw_compress(preg_replace('~\s*([:;{},])\s*~', '\1', preg_replace('~/\*.*?\*/\s*~s', '', $file)));
}
function minify_js($file) {
@@ -356,14 +235,6 @@ function compile_file($match) {
return '"' . add_quo_slashes($file) . '"';
}
if (!function_exists("each")) {
function each(&$arr) {
$key = key($arr);
next($arr);
return $key === null ? false : array($key, $arr[$key]);
}
}
function min_version() {
return true;
}
@@ -411,6 +282,7 @@ include __DIR__ . "/adminer/include/driver.inc.php";
$features = array("check", "call" => "routine", "dump", "event", "privileges", "procedure" => "routine", "processlist", "routine", "scheme", "sequence", "status", "trigger", "type", "user" => "privileges", "variables", "view");
$lang_ids = array(); // global variable simplifies usage in a callback function
$file = file_get_contents(__DIR__ . "/$project/index.php");
$file = preg_replace('~\*/~', "* @version $VERSION\n*/", $file, 1);
if ($driver) {
$_GET[$driver] = true; // to load the driver
include_once __DIR__ . $driver_path;
@@ -443,7 +315,7 @@ if ($driver) {
}
if (count($drivers) == 1) {
$file = str_replace('html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);")', "\"<input type='hidden' name='auth[driver]' value='" . ($driver == "mysql" ? "server" : $driver) . "'>" . reset($drivers) . "\"", $file, $count);
if (!$count) {
if (!$count && $project != "editor") {
echo "auth[driver] form field not found\n";
}
$file = str_replace(" . script(\"qs('#username').form['auth[driver]'].onchange();\")", "", $file);
@@ -469,16 +341,15 @@ if ($_SESSION["lang"]) {
$file = str_replace("switch_lang();", "", $file);
$file = str_replace('<?php echo $LANG; ?>', $_SESSION["lang"], $file);
}
$file = str_replace('<?php echo script_src("static/editing.js"); ?>' . "\n", "", $file);
$file = preg_replace('~\s+echo script_src\("\.\./externals/jush/modules/jush-(textarea|txt|js|" \. JUSH \. ")\.js"\);~', '', $file);
$file = str_replace('<link rel="stylesheet" type="text/css" href="../externals/jush/jush.css">' . "\n", "", $file);
$file = str_replace('echo script_src("static/editing.js");' . "\n", "", $file); // merged into functions.js
$file = preg_replace('~\s+echo script_src\("\.\./externals/jush/modules/jush-(textarea|txt|js|" \. JUSH \. ")\.js"\);~', '', $file); // merged into jush.js
$file = str_replace('<link rel="stylesheet" href="../externals/jush/jush.css">' . "\n", "", $file); // merged into default.css
$file = preg_replace_callback("~compile_file\\('([^']+)'(?:, '([^']*)')?\\)~", 'compile_file', $file); // integrate static files
$replace = 'preg_replace("~\\\\\\\\?.*~", "", ME) . "?file=\1&version=' . $VERSION . '"';
$file = preg_replace('~\.\./adminer/static/(default\.css|favicon\.ico)~', '<?php echo h(' . $replace . '); ?>', $file);
$file = preg_replace('~"\.\./adminer/static/(functions\.js)"~', $replace, $file);
$file = preg_replace('~\.\./adminer/static/([^\'"]*)~', '" . h(' . $replace . ') . "', $file);
$file = preg_replace('~"\.\./externals/jush/modules/(jush\.js)"~', $replace, $file);
$file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file);
$file = php_shrink($file);
$filename = $project . (preg_match('~-dev$~', $VERSION) ? "" : "-$VERSION") . ($driver ? "-$driver" : "") . ($_SESSION["lang"] ? "-$_SESSION[lang]" : "") . ".php";

View File

@@ -6,8 +6,8 @@
"database"
],
"support": {
"issues": "https://sourceforge.net/p/adminer/bugs-and-features/",
"forum": "https://sourceforge.net/p/adminer/discussion/",
"issues": "https://github.com/vrana/adminer/issues",
"forum": "https://github.com/vrana/adminer/discussions",
"source": "https://github.com/vrana/adminer/"
},
"authors": [
@@ -33,6 +33,7 @@
"php": ">=5.3"
},
"scripts": {
"compile": "php compile.php"
"clean": "rm -f adminer*.php editor*.php",
"compile": "@php compile.php"
}
}

View File

@@ -1,13 +1,14 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="cs">
<!DOCTYPE html>
<html lang="cs">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Coverage</title>
</head>
<body>
<?php
include "./adminer/include/errors.inc.php";
function xhtml_open_tags($s) {
// returns array of opened tags in $s
$return = array();
@@ -24,17 +25,18 @@ function xhtml_open_tags($s) {
$coverage_filename = sys_get_temp_dir() . "/adminer_coverage.ser";
if (!extension_loaded("xdebug")) {
echo "<p class='error'>Xdebug has to be enabled.</p>\n";
echo "<p class='error'>Xdebug has to be enabled.\n";
} elseif ($_GET["coverage"] === "0") {
file_put_contents($coverage_filename, serialize(array()));
echo "<p class='message'>Coverage started.</p>\n";
} elseif (preg_match('~^(adminer|editor)/(include/)?[-_.a-z0-9]+$~i', $_GET["coverage"])) {
echo "<p class='message'>Coverage started.\n";
} elseif (preg_match('~^(adminer|editor)/(include/|drivers/)?[-_.a-z0-9]+$~i', $_GET["coverage"])) {
// highlight single file
$filename = $_GET["coverage"];
$coverage = (file_exists($coverage_filename) ? unserialize(file_get_contents($coverage_filename)) : array());
$file = explode("<br />", highlight_file($filename, true));
$file = explode("\n", substr(highlight_file($filename, true), 5, -6)); // unwrap <pre></pre>
$prev_color = null;
$s = "";
echo "<pre>";
for ($l=0; $l <= count($file); $l++) {
$line = $file[$l];
$color = "#C0FFC0"; // tested
@@ -58,31 +60,28 @@ if (!extension_loaded("xdebug")) {
foreach (array_reverse($open_tags) as $tag) {
echo "</" . preg_replace('~ .*~', '', $tag) . ">";
}
echo "</div>\n";
echo "</div>";
$s = ($open_tags ? "<" . implode("><", $open_tags) . ">" : "");
$prev_color = $color;
}
$s .= "$line<br />\n";
$s .= "$line\n";
}
echo "</pre>";
} else {
if (file_exists($coverage_filename)) {
// display list of files
$coverage = unserialize(file_get_contents($coverage_filename));
echo "<table border='1' cellspacing='0'>\n";
foreach (array_merge(glob("adminer/*.php"), glob("adminer/include/*.php"), glob("editor/*.php"), glob("editor/include/*.php")) as $filename) {
foreach (array_merge(glob("adminer/*.php"), glob("adminer/drivers/*.php"), glob("adminer/include/*.php"), glob("editor/*.php"), glob("editor/include/*.php")) as $filename) {
$cov = $coverage[realpath($filename)];
$ratio = 0;
if (is_array($cov)) {
$values = array_count_values($cov);
$ratio = round(100 - 100 * $values[-1] / (count($cov) - $values[-2]));
}
echo "<tr><td align='right' style='background-color: " . ($ratio < 50 ? "Red" : ($ratio < 75 ? "#FFEA20" : "#A7FC9D")) . ";'>$ratio%</td><td><a href='coverage.php?coverage=$filename'>$filename</a></td></tr>\n";
echo "<tr><td align='right' style='background-color: " . ($ratio < 50 ? "Red" : ($ratio < 75 ? "#FFEA20" : "#A7FC9D")) . ";'>$ratio%<td><a href='coverage.php?coverage=$filename'>$filename</a>\n";
}
echo "</table>\n";
}
echo "<p><a href='coverage.php?coverage=0'>Start new coverage</a></p>\n";
echo "<p><a href='coverage.php?coverage=0'>Start new coverage</a>\n";
}
?>
</body>
</html>

View File

@@ -198,7 +198,7 @@ table label.block{padding:0}
tr{border-bottom:1px dotted rgba(255,255,255,0.1)}
th,td{padding:4px 10px}
th[style="text-align: right;"] input[type="checkbox"],td[align="right"] input[type="checkbox"],th[style="text-align: right;"] input[type="radio"],td[align="right"] input[type="radio"]{margin-right:0;margin-left:5px}
thead td,thead th,.odds tbody tr:nth-child(2n) td,tbody tr:hover td,tbody tr:hover th,.js .checkable .checked td,.js .checkable .checked th{background:transparent}
thead td,thead th,.odds tbody tr:nth-child(2n),tbody tr:hover td,tbody tr:hover th,.js .checkable .checked td,.js .checkable .checked th{background:transparent}
thead tr{background:#282b2f;border-bottom:1px solid rgba(255,255,255,0.1)}
thead td,thead th{padding:7px 10px;background:transparent;text-align:left}
tbody th,tbody td{vertical-align:top}

View File

@@ -112,7 +112,7 @@ border-bottom: 1px #BBB solid;
thead tr:hover td, thead tr:hover th {
background-color: #DDD !important;
}
tr:nth-child(2n) td, tr:nth-child(2n) th, .odd td, .odd th, tr.odd {
tr:nth-child(2n) td, tr:nth-child(2n) th {
background-color: #F1F1F1;
}
tr:hover td, tr:hover th {

View File

@@ -175,8 +175,7 @@
background: var(--color-darkPurple);
}
.odds tbody tr:nth-child(2n) th,
.odds tbody tr:nth-child(2n) td {
.odds tbody tr:nth-child(2n) {
background: var(--color-darkDraculaVSCode);
}

View File

@@ -133,7 +133,7 @@ th {
background:white;
}
.odds tbody tr:nth-child(2n) td {
.odds tbody tr:nth-child(2n) {
background:#fcfaf5;
}

View File

@@ -72,7 +72,7 @@ tr:first-child th {padding-right: 30px;}
td:first-child, th:first-child {border-left-width: 0;}
thead td, thead th {background-color: #DFDFDF; border: none; border-bottom: 1px #BBB solid;}
thead tr:hover td, thead tr:hover th {background-color: #DDD !important;}
tr:nth-child(2n) td, tr:nth-child(2n) th, .odds tbody tr:nth-child(2n) td, .odds tbody tr:nth-child(2n) th, .odds tbody tr:nth-child(2n) {background-color: #F1F1F1;}
tr:nth-child(2n) td, tr:nth-child(2n) th, .odds tbody tr:nth-child(2n), .odds tbody tr:nth-child(2n):not(.checked, :hover) {background-color: #F1F1F1;}
tr:hover td, tr:hover th {background-color: #BCD;}
fieldset {display: inline; vertical-align: top; padding: 2px 12px; margin: 25px 12px 12px 0; border: none; background-color: #F1F1F1; border: 1px solid #E3E3E3; position: relative;}
fieldset, x:-moz-any-link {padding-top: 4px;}

View File

@@ -378,7 +378,7 @@ thead td abbr, thead td sup, thead th acronym, thead th sup {
color: #cdf
}
.odds tbody tr:nth-child(2n) td {
.odds tbody tr:nth-child(2n) {
background: #fcfaf5
}

View File

@@ -153,7 +153,7 @@ th, td {
vertical-align: top;
}
.odds tbody tr:nth-child(2n) th, .odds tbody tr:nth-child(2n) td {
.odds tbody tr:nth-child(2n) {
background: #FCFAF5;
}

View File

@@ -132,7 +132,7 @@ th {
background:white;
}
.odds tbody tr:nth-child(2n) td {
.odds tbody tr:nth-child(2n) {
background:#fcfaf5;
}

View File

@@ -187,7 +187,7 @@ td.nowrap {
.binary {
color: red;
}
.odds tbody tr:nth-child(2n) td {
.odds tbody tr:nth-child(2n) {
background: transparent;
}
.js .checkable .checked td,

View File

@@ -169,7 +169,7 @@ th {
background:white;
}
.odds tbody tr:nth-child(2n) td {
.odds tbody tr:nth-child(2n) {
background:#fcfaf5;
}
@@ -181,7 +181,7 @@ th {
background: #f2f2f2;
}
#content tbody tr.checked td, .odds tbody tr:nth-child(2n).checked td {
#content tbody tr.checked td {
background:#fbe2e2;
color:red;
}

View File

@@ -65,7 +65,7 @@ thead td, thead th {
border-bottom: 1px #DDD solid; }
.nowrap tr:nth-child(2n) td, .nowrap tr:nth-child(2n) th {
background-color: #DEF; }
.odds tbody tr:nth-child(2n) td, .odds tbody tr:nth-child(2n) th {
.odds tbody tr:nth-child(2n) {
background-color: #DEF; } /* IEx */
tr.selected td, tr.selected th {
background-color: #ABC !important; }
@@ -234,7 +234,7 @@ legend a:hover {
select[name^="columns"] optgroup:last-child option:nth-child(3)::before {
content: "count "; }
select[name$="[collation]"] {
input[name$="[collation]"] {
max-width: 120px; }
.logout a:first-child, p a {

View File

@@ -136,8 +136,7 @@ table.checkable tbody tr:hover th {
background: #bfb008;
}
.odds tbody tr:nth-child(2n) th,
.odds tbody tr:nth-child(2n) td {
.odds tbody tr:nth-child(2n) {
background: #f5f5f5;
}

View File

@@ -58,7 +58,7 @@ table{-moz-border-bottom-colors:none;-moz-border-left-colors:none;-moz-border-ri
td,th{-moz-border-bottom-colors:none;-moz-border-left-colors:none;-moz-border-right-colors:none;-moz-border-top-colors:none;border-color:-moz-use-text-color #999 #999 -moz-use-text-color;border-image:none;border-style:none solid solid none;border-width:0 1px 1px 0;padding:.2em .3em}
thead td,thead th{background:#eee;background:-moz-linear-gradient(top,#eee 0,#ccc 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#eee),color-stop(100%,#ccc));background:-webkit-linear-gradient(top,#eee 0,#ccc 100%);background:-o-linear-gradient(top,#eee 0,#ccc 100%);background:-ms-linear-gradient(top,#eee 0,#ccc 100%);background:linear-gradient(to bottom,#eee 0,#ccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee',endColorstr='#cccccc',GradientType=0)}
td{background-color:#f4f8ff}
.odds tbody tr:nth-child(2n) td{background-color:#fff}
.odds tbody tr:nth-child(2n){background-color:#fff}
tbody tr:hover td,tbody tr:hover th{background-color:#FFE}
p.tabs{margin:0 20px 0 0}
.jush-sql{background:0}
@@ -70,6 +70,7 @@ a:hover{color:#28c}
#logout:hover,#logins a:hover,#tables a:hover,#breadcrumb a:hover,.logout a:hover,.tabs a:hover{color:#fff;text-decoration:none;background:#93c9ff;background:-moz-linear-gradient(top,#93c9ff 0,#79b8f7 44%,#57a2ed 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#93c9ff),color-stop(44%,#79b8f7),color-stop(100%,#57a2ed));background:-webkit-linear-gradient(top,#93c9ff 0,#79b8f7 44%,#57a2ed 100%);background:-o-linear-gradient(top,#93c9ff 0,#79b8f7 44%,#57a2ed 100%);background:-ms-linear-gradient(top,#93c9ff 0,#79b8f7 44%,#57a2ed 100%);background:linear-gradient(to bottom,#93c9ff 0,#79b8f7 44%,#57a2ed 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#93c9ff',endColorstr='#57a2ed',GradientType=0)}
#breadcrumb a,#breadcrumb a:link{border:1px solid #246;padding:2px 6px;margin:1px auto;line-height:1.6em}
#logins a,#tables a{background:none repeat scroll 0 0 #fff;padding:2px 6px;margin:1px 0;font-size:.8em}
#lang{top:-4.5em;}
a[title='Show structure'],#tables a[title='Show structure']{border:0;background:0;color:#369}
.jush a{border:0;background:0;margin:0;padding:0}
a.active,a.active:link,a.active:hover{text-decoration:underline}

View File

@@ -2,8 +2,8 @@
* @package Adminer.css - Theme CSS for Adminer --- [theme light] gray - orange B (with icons)
*
*//*!
* @version 4.17.1.2
* @date Thu, 27 Feb 2025 09:28:32 +0100
* @version 5.0.4.1
* @date Wed, 12 Mar 2025 21:35:32 +0100
* @author Robert Mesaros
* @copyright Copyright 2025 Robert Mesaros, rmSOFT, Slovakia
* @web https://www.rmsoft.sk
@@ -35,10 +35,6 @@
* Modified icons by Robert Mesaros
*
*/
#menu{padding:0 0 30px 0}
.ltr .logout{right:0;left:auto;margin-top:.5em}
.rtl .logout{left:0;right:auto;margin-top:.5em}
.rtl table.layout tbody{direction:ltr}
html{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}
*,*:before,*:after{box-sizing:inherit}
body{color:#000;background:#f0f0f0;font-family:Verdana,Arial,Helvetica,sans-serif;font-weight:normal;cursor:default;margin:0}
@@ -49,6 +45,9 @@ img{width:100%;max-width:100%}
#menu #h1{margin-left:10px}
#menu h1{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozNDA3NDEwQ0Y0MkQxMUVGODA4RUNENTRFQzJENUU4RCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozNDA3NDEwQkY0MkQxMUVGODA4RUNENTRFQzJENUU4RCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRTREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Ph59M4AAAAPFSURBVHja7JZrSFNRHMDvvVvq1mNlucBK0g/lh+Us6oPrU0ERRFgRUqYUVEb2qTJ0vko0ZbMHiBT0sizSXEUfJGzN1CjBQLPCR/RwSYKp23RO3e527/r/57mxxpblhCD8w59z7t2553f+zx36Ulk5FYxkZpyiijVahUgkqnc62cu5arUGXrMl2tIkhmGuu91uGp4HXre0qB490A3C3IXfMVSQojl/QQYAHUzlNtvYPBhl2Xn5672gqBFxSmXF0WPpCTCfg+/EwUDBwkixeM4TmqZjzSbTFU1J8W00RiaTtUxMTJSfzctFd4Yq49eGJ6ekNETHxGyG50jQkWDAcoA+BqjSbDaXA/QqvBtFBWg6QGuJtSaapr7jB7AWrV0C6pguWAZurIeNFCaTqUxbUnwd3lkRAjoO0JswStApEGs1jJs4jusw9vTcEcI7LTBA3wA02mI2X/WFgvIIxCQC6EmIdQ7P898qb1Xs7O7qGiVrWWaa4C5PZopEy6RSKQfTYS8oRUYO1i3Hh4e6mlSA2sjhLHgwMdkoA04lI1noV8BVn/Nzsu/iFHTP2cIiHSTR9tNZaqYgP28/iecv4nA4ajmXi7NYLKPkcFbiDYomdcxNVVoul6s9JytzC/mYWxEVtfDQkbQKiUSyw26368/k5iTBexvZSxA0bD4Zx0An0E4B3Nfz5cu+zs4OJ+tgQwOBlfHxcSujo7MHBwfTLpZq69Cdq2NjFyWnpFaGhYVtA3hdU2PD4ecGQ78AhxjnQi6o29va1lVX3TNibAUwniSyq7PT+qKxcQjmduEHX0lQqSIgUZaOj4+FwyM2ipEP3d1msHRvQdG5GoQnqDYWAviEYDmErw/G1t7e3hAYQwiY+tm5Pn36aCdusATS+QsWDOBa8ArWInqGga6FltnQzcPDlrKvRmMTKSMRroXQ3AXd3fzq5ZCvQZ7kOnb8ONQXbYd+6/pNmBd70pXnfHPBAy8pKsojUNYruzmSEwzp0e5fwNCBFIFc7CXMZHbzIn9JT9wrJA/nVVasv8084PvVVVvftLbavIPvK6kHDqoUa9Zc+03J8V6WTike8FzpXJ4UtzUQOEIux98oCAdHzYCIJzsQw5M6s0LC+D01NIPxmQQz1D+SWfAs+D8FO1mn6w9uHUJ90zPSQOAvcdWOxERD4q5dSwjA/0KxuNmg1294/+7tGLlFuIOy+NbNG0b4s3YSSwIqyzr4Z/qnlv7+/iE/N42/FjokJBQ3lmI7JteUQK5E0Ajp6fZgLUaw0LNDp7juuomL2WCtRfkhwACjULOQ0RiwkAAAAABJRU5ErkJggg==");background-repeat:no-repeat}
#menu h1:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQUNCOTdFQkY0MkQxMUVGOUM0OUMyQTRDNjAyNzhENiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQUNCOTdFQUY0MkQxMUVGOUM0OUMyQTRDNjAyNzhENiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRTREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pq1mg9cAAAQtSURBVHja7JZdTFxFFIDP3J9dCgqUQimQIlBSWNoCNfVBYmo0jX9Jg014aYrWFzWGRl9MTHzpiy8k2kbrm9qUWtMaY9S2RqV9ADQm9o/+pHsvhW5Lw8/iLu6PC9yfvTOeWWbbC9ktlPWRk5ydvWfmzjfnzJkzlxz+7HNYSpIeD1QEAtB2+kew8vKgwdXn9Wsw1uR7tQTg+zhjfRs0fTeazWCT71ARwLt8jANgn0nMNO+9d+82nw6VSZCj3PE1VhcDnJIBpDnG8tC0TmvYvC8N5YJ9yq6C/L4/6je9jo8eVJITOMjY9lJCdBUdn6D0Sq0+9B6alTpZ7okwNrjGrzWjPnkwHO4oJKR8h8fzJfaXcLiUA3TLWkJ+x+WvQeglhL6N5jhqZIqxbyo1vQP/z6GOW5QN8nfI/KtrOVhZLogwllIuE4xVo6eXEJo3TumFOn2oS0D/Rv23WtPfxPYxVCvU5DuL41pMAOOWbf+ENu4sWR4YgUlVBUdRQHIcKJPlEQyvGqT02mLofC6BhRrFBPuhEOAZG20HJoOvHItEJtEeQ7WXFWrFtmGq+gm4+NLL6DUF23Ei3O4hpLRKVXkY/nFBRSKDjUlVxR8+Coc7BTSEGuZZr8w7xN6nlBZhS7LBqWHc3n/kyAkxaV2osWG4RJKqrtRvOluu6S0PtvCBxCg9iZtsBSwrJBYXEdFgKTAhpFuW5aW8v4p6RoTV7Bwb23F848aLxYRUhn2NN0o13Sf6kukX6vWhT7E5zoMm+mwOTTGxgIzfCQT2+v03bcu0vNmoLa2tzTW1tR+GpsNvHeru/pVP0FlcXHG4YsMFflSweEwdjUaf/2AyeEtEhWFincMM2/XzzOxzHaOjf6HNSIP5Sio1vz8+0NcXdncslqfb2sokSSqfTSRKRMbGTkSjE6hb0GM/h+8rKvoOwTtFAiUtxkYNQqI3TYNHkztlusEwMjJsiDMXzQZ+vLCQZy1gVFQxiWQ+u9P29g/EMMxNdxsbfhm2rH4+FHWWg6s0/QC2B0W1WjBvCvxOV9fXGHUD9zn5kD1el0oy6tzPhdM1tQD9A/ydWI0+9KKA8uShYogtkkpKJ9UCsKKoW7N56pIU0HGonDaMtG4H6OkBkVBxETUmgOljNZfxiPKfb0+dfGHw8uXE4lW55bX9b7Rt3bbtC/eR4wXFJY7rHC9dG/hPQX4BD820WHVGcNn69fHUTSPL9ydXDWPFF0wKLMkSB89wcPfHn9BMA03TnF0MxgKwYnDO9/EqeBW8Cl4Ati07ufTXD0ufb/J/gBW8Ejfvbm8/375nT6kAZB6oKH+e7+196sb1azPuC33FHh87+tVd/AKxhSdZ1bJMeq73t0gwGOT3duJR6nLGr1aPx8snzuflWFxr2ULpiAt++mEfDI8CTtdsb7p2Z9tmEWIrV2+5/CfAAOVxxSK4gGWJAAAAAElFTkSuQmCC")}
.rtl table.layout tbody td{display:flex}
.rtl table.layout~table thead th:first-child,.rtl table.layout~table tbody td:first-child{text-align:right !important}
.rtl table.layout~table thead th:last-child,.rtl table.layout~table tbody td:last-child{text-align:left !important}
h1{padding:.6em .4em;background:#c60;border:1px solid #894501;text-align:left}
#h1{color:#fff}
.version{color:#ddd;margin-left:8px}
@@ -99,7 +98,7 @@ code{background:#f0d6d6;padding:.2em .5em}
table code{font-size:130%;background:#f5e8ce;padding:.1em .3em}
code.jush-sql{background:#f0e8d6}
.rtl p code.jush-sql{background-position:right;clear:right;float:right}
pre.sqlarea{background:#e0e0e0;padding:5px}
pre{background:#e0e0e0 !important;padding:5px}
textarea{font-size:120%}
.ltr p.count{font-size:90%;margin:.8em 20px 8px 0}
.rtl p.count{font-size:90%;margin:.8em 0 8px 20px}
@@ -119,12 +118,12 @@ table{border-spacing:0}
table,td,th{border:0;border-collapse:separate}
.ltr table{margin:1.9em 0 0 0}
.rtl table{margin:1.9em 0 0 0}
.rtl table tbody td,.rtl table tbody th{text-align:right}
.rtl table tbody td,.rtl table tbody th{text-align:right !important}
.ltr table thead td:first-child,.ltr table thead th:first-child{border-left:1px solid #999}
.rtl table thead td:first-child,.rtl table thead th:first-child{border-right:1px solid #999}
table thead td,table thead th{height:1.6em;border-top:1px solid #999;border-bottom:1px solid #999}
.ltr table thead td,.ltr table thead th{border-right:1px solid #999}
.rtl table thead td,.rtl table thead th{border-left:1px solid #999;text-align:right !important}
.rtl table thead td,.rtl table thead th{border-left:1px solid #999}
table tbody tr:first-child td,table tbody tr:first-child th{border-top:1px solid #999}
.ltr table tbody td:first-child,.ltr table tbody th:first-child{border-left:1px solid #999}
.rtl table tbody td:first-child,.rtl table tbody th:first-child{border-right:1px solid #999}
@@ -421,9 +420,12 @@ input[type=radio]{margin-bottom:5px}
.rtl input[type=checkbox],.rtl input[type=radio],.rtl input[type=range],.rtl progress{margin-left:5px}
.ltr input[type=submit]{margin-right:10px}
.rtl input[type=submit]{margin-left:10px}
.ltr table.layout label,.ltr label.jsonly{margin-left:8px}
.rtl table.layout label,.rtl label.jsonly{margin-right:8px}
input,button,select,.sqlarea{border-radius:3px}
.sqlarea{background:#e0e0e0;font-size:105%}
fieldset a{line-height:unset}
input[type=submit]{padding:2px 6px}
.ltr table.layout label,.ltr label.jsonly{margin-left:8px}
.rtl table.layout label,.rtl label.jsonly{margin-right:8px}
#menu{padding:0 0 30px 0}
.ltr .logout{right:0;left:auto;margin-top:.5em}
.rtl .logout{left:0;right:auto;margin-top:.5em}

View File

@@ -2,8 +2,8 @@
* @package Adminer.css - Theme CSS for Adminer --- [theme dark] blue B (with icons)
*
*//*!
* @version 4.17.1.2
* @date Thu, 27 Feb 2025 09:28:32 +0100
* @version 5.0.4.1
* @date Wed, 12 Mar 2025 21:35:32 +0100
* @author Robert Mesaros
* @copyright Copyright 2025 Robert Mesaros, rmSOFT, Slovakia
* @web https://www.rmsoft.sk
@@ -35,10 +35,6 @@
* Modified icons by Robert Mesaros
*
*/
#menu{padding:0 0 30px 0}
.ltr .logout{right:0;left:auto;margin-top:.5em}
.rtl .logout{left:0;right:auto;margin-top:.5em}
.rtl table.layout tbody{direction:ltr}
html{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}
*,*:before,*:after{box-sizing:inherit}
body{color:#829bb0;background:#002240;font-family:Verdana,Arial,Helvetica,sans-serif;font-weight:normal;cursor:default;margin:0}
@@ -50,6 +46,9 @@ img{width:100%;max-width:100%}
#menu h1{background-color:#1d4e78}
#menu h1{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozNDA3NDEwQ0Y0MkQxMUVGODA4RUNENTRFQzJENUU4RCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozNDA3NDEwQkY0MkQxMUVGODA4RUNENTRFQzJENUU4RCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRTREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Ph59M4AAAAPFSURBVHja7JZrSFNRHMDvvVvq1mNlucBK0g/lh+Us6oPrU0ERRFgRUqYUVEb2qTJ0vko0ZbMHiBT0sizSXEUfJGzN1CjBQLPCR/RwSYKp23RO3e527/r/57mxxpblhCD8w59z7t2553f+zx36Ulk5FYxkZpyiijVahUgkqnc62cu5arUGXrMl2tIkhmGuu91uGp4HXre0qB490A3C3IXfMVSQojl/QQYAHUzlNtvYPBhl2Xn5672gqBFxSmXF0WPpCTCfg+/EwUDBwkixeM4TmqZjzSbTFU1J8W00RiaTtUxMTJSfzctFd4Yq49eGJ6ekNETHxGyG50jQkWDAcoA+BqjSbDaXA/QqvBtFBWg6QGuJtSaapr7jB7AWrV0C6pguWAZurIeNFCaTqUxbUnwd3lkRAjoO0JswStApEGs1jJs4jusw9vTcEcI7LTBA3wA02mI2X/WFgvIIxCQC6EmIdQ7P898qb1Xs7O7qGiVrWWaa4C5PZopEy6RSKQfTYS8oRUYO1i3Hh4e6mlSA2sjhLHgwMdkoA04lI1noV8BVn/Nzsu/iFHTP2cIiHSTR9tNZaqYgP28/iecv4nA4ajmXi7NYLKPkcFbiDYomdcxNVVoul6s9JytzC/mYWxEVtfDQkbQKiUSyw26368/k5iTBexvZSxA0bD4Zx0An0E4B3Nfz5cu+zs4OJ+tgQwOBlfHxcSujo7MHBwfTLpZq69Cdq2NjFyWnpFaGhYVtA3hdU2PD4ecGQ78AhxjnQi6o29va1lVX3TNibAUwniSyq7PT+qKxcQjmduEHX0lQqSIgUZaOj4+FwyM2ipEP3d1msHRvQdG5GoQnqDYWAviEYDmErw/G1t7e3hAYQwiY+tm5Pn36aCdusATS+QsWDOBa8ArWInqGga6FltnQzcPDlrKvRmMTKSMRroXQ3AXd3fzq5ZCvQZ7kOnb8ONQXbYd+6/pNmBd70pXnfHPBAy8pKsojUNYruzmSEwzp0e5fwNCBFIFc7CXMZHbzIn9JT9wrJA/nVVasv8084PvVVVvftLbavIPvK6kHDqoUa9Zc+03J8V6WTike8FzpXJ4UtzUQOEIux98oCAdHzYCIJzsQw5M6s0LC+D01NIPxmQQz1D+SWfAs+D8FO1mn6w9uHUJ90zPSQOAvcdWOxERD4q5dSwjA/0KxuNmg1294/+7tGLlFuIOy+NbNG0b4s3YSSwIqyzr4Z/qnlv7+/iE/N42/FjokJBQ3lmI7JteUQK5E0Ajp6fZgLUaw0LNDp7juuomL2WCtRfkhwACjULOQ0RiwkAAAAABJRU5ErkJggg==");background-repeat:no-repeat;mix-blend-mode:difference}
#menu h1:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQUNCOTdFQkY0MkQxMUVGOUM0OUMyQTRDNjAyNzhENiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQUNCOTdFQUY0MkQxMUVGOUM0OUMyQTRDNjAyNzhENiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRTREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pq1mg9cAAAQtSURBVHja7JZdTFxFFIDP3J9dCgqUQimQIlBSWNoCNfVBYmo0jX9Jg014aYrWFzWGRl9MTHzpiy8k2kbrm9qUWtMaY9S2RqV9ADQm9o/+pHsvhW5Lw8/iLu6PC9yfvTOeWWbbC9ktlPWRk5ydvWfmzjfnzJkzlxz+7HNYSpIeD1QEAtB2+kew8vKgwdXn9Wsw1uR7tQTg+zhjfRs0fTeazWCT71ARwLt8jANgn0nMNO+9d+82nw6VSZCj3PE1VhcDnJIBpDnG8tC0TmvYvC8N5YJ9yq6C/L4/6je9jo8eVJITOMjY9lJCdBUdn6D0Sq0+9B6alTpZ7okwNrjGrzWjPnkwHO4oJKR8h8fzJfaXcLiUA3TLWkJ+x+WvQeglhL6N5jhqZIqxbyo1vQP/z6GOW5QN8nfI/KtrOVhZLogwllIuE4xVo6eXEJo3TumFOn2oS0D/Rv23WtPfxPYxVCvU5DuL41pMAOOWbf+ENu4sWR4YgUlVBUdRQHIcKJPlEQyvGqT02mLofC6BhRrFBPuhEOAZG20HJoOvHItEJtEeQ7WXFWrFtmGq+gm4+NLL6DUF23Ei3O4hpLRKVXkY/nFBRSKDjUlVxR8+Coc7BTSEGuZZr8w7xN6nlBZhS7LBqWHc3n/kyAkxaV2osWG4RJKqrtRvOluu6S0PtvCBxCg9iZtsBSwrJBYXEdFgKTAhpFuW5aW8v4p6RoTV7Bwb23F848aLxYRUhn2NN0o13Sf6kukX6vWhT7E5zoMm+mwOTTGxgIzfCQT2+v03bcu0vNmoLa2tzTW1tR+GpsNvHeru/pVP0FlcXHG4YsMFflSweEwdjUaf/2AyeEtEhWFincMM2/XzzOxzHaOjf6HNSIP5Sio1vz8+0NcXdncslqfb2sokSSqfTSRKRMbGTkSjE6hb0GM/h+8rKvoOwTtFAiUtxkYNQqI3TYNHkztlusEwMjJsiDMXzQZ+vLCQZy1gVFQxiWQ+u9P29g/EMMxNdxsbfhm2rH4+FHWWg6s0/QC2B0W1WjBvCvxOV9fXGHUD9zn5kD1el0oy6tzPhdM1tQD9A/ydWI0+9KKA8uShYogtkkpKJ9UCsKKoW7N56pIU0HGonDaMtG4H6OkBkVBxETUmgOljNZfxiPKfb0+dfGHw8uXE4lW55bX9b7Rt3bbtC/eR4wXFJY7rHC9dG/hPQX4BD820WHVGcNn69fHUTSPL9ydXDWPFF0wKLMkSB89wcPfHn9BMA03TnF0MxgKwYnDO9/EqeBW8Cl4Ati07ufTXD0ufb/J/gBW8Ejfvbm8/375nT6kAZB6oKH+e7+196sb1azPuC33FHh87+tVd/AKxhSdZ1bJMeq73t0gwGOT3duJR6nLGr1aPx8snzuflWFxr2ULpiAt++mEfDI8CTtdsb7p2Z9tmEWIrV2+5/CfAAOVxxSK4gGWJAAAAAElFTkSuQmCC");mask-image:linear-gradient(black, transparent);-webkit-mask-image:linear-gradient(black, transparent);mix-blend-mode:unset;background-color:unset}
.rtl table.layout tbody td{display:flex}
.rtl table.layout~table thead th:first-child,.rtl table.layout~table tbody td:first-child{text-align:right !important}
.rtl table.layout~table thead th:last-child,.rtl table.layout~table tbody td:last-child{text-align:left !important}
h1{padding:.6em .4em;background:#1d4e78;border:1px solid #f2ddaf;text-align:left}
#h1{color:#fff}
.version{color:#ddd;margin-left:8px}
@@ -100,7 +99,7 @@ code{background:#81a0bc;padding:.2em .5em}
table code{font-size:130%;background:#154167;padding:.1em .3em}
code.jush-sql{background:#c5d8e9}
.rtl p code.jush-sql{background-position:right;clear:right;float:right}
pre.sqlarea{background:#a7c3dc;padding:5px}
pre{background:#a7c3dc !important;padding:5px}
textarea{font-size:120%}
.ltr p.count{font-size:90%;margin:.8em 20px 8px 0}
.rtl p.count{font-size:90%;margin:.8em 0 8px 20px}
@@ -120,12 +119,12 @@ table{border-spacing:0}
table,td,th{border:0;border-collapse:separate}
.ltr table{margin:1.9em 0 0 0}
.rtl table{margin:1.9em 0 0 0}
.rtl table tbody td,.rtl table tbody th{text-align:right}
.rtl table tbody td,.rtl table tbody th{text-align:right !important}
.ltr table thead td:first-child,.ltr table thead th:first-child{border-left:1px solid #1e5687}
.rtl table thead td:first-child,.rtl table thead th:first-child{border-right:1px solid #1e5687}
table thead td,table thead th{height:1.6em;border-top:1px solid #1e5687;border-bottom:1px solid #1e5687}
.ltr table thead td,.ltr table thead th{border-right:1px solid #1e5687}
.rtl table thead td,.rtl table thead th{border-left:1px solid #1e5687;text-align:right !important}
.rtl table thead td,.rtl table thead th{border-left:1px solid #1e5687}
table tbody tr:first-child td,table tbody tr:first-child th{border-top:1px solid #1e5687}
.ltr table tbody td:first-child,.ltr table tbody th:first-child{border-left:1px solid #1e5687}
.rtl table tbody td:first-child,.rtl table tbody th:first-child{border-right:1px solid #1e5687}
@@ -422,9 +421,12 @@ input[type=radio]{margin-bottom:5px}
.rtl input[type=checkbox],.rtl input[type=radio],.rtl input[type=range],.rtl progress{margin-left:5px}
.ltr input[type=submit]{margin-right:10px}
.rtl input[type=submit]{margin-left:10px}
.ltr table.layout label,.ltr label.jsonly{margin-left:8px}
.rtl table.layout label,.rtl label.jsonly{margin-right:8px}
input,button,select,.sqlarea{border-radius:3px}
.sqlarea{background:#a7c3dc;font-size:105%}
fieldset a{line-height:unset}
input[type=submit]{padding:2px 6px}
.ltr table.layout label,.ltr label.jsonly{margin-left:8px}
.rtl table.layout label,.rtl label.jsonly{margin-right:8px}
#menu{padding:0 0 30px 0}
.ltr .logout{right:0;left:auto;margin-top:.5em}
.rtl .logout{left:0;right:auto;margin-top:.5em}

View File

@@ -2,8 +2,8 @@
* @package Adminer.css - Theme CSS for Adminer --- [theme light] blue B (with icons)
*
*//*!
* @version 4.17.1.2
* @date Thu, 27 Feb 2025 09:28:32 +0100
* @version 5.0.4.1
* @date Wed, 12 Mar 2025 21:35:32 +0100
* @author Robert Mesaros
* @copyright Copyright 2025 Robert Mesaros, rmSOFT, Slovakia
* @web https://www.rmsoft.sk
@@ -35,10 +35,6 @@
* Modified icons by Robert Mesaros
*
*/
#menu{padding:0 0 30px 0}
.ltr .logout{right:0;left:auto;margin-top:.5em}
.rtl .logout{left:0;right:auto;margin-top:.5em}
.rtl table.layout tbody{direction:ltr}
html{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}
*,*:before,*:after{box-sizing:inherit}
body{color:#000;background:#82a7c0;font-family:Verdana,Arial,Helvetica,sans-serif;font-weight:normal;cursor:default;margin:0}
@@ -49,6 +45,9 @@ img{width:100%;max-width:100%}
#menu #h1{margin-left:10px}
#menu h1{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozNDA3NDEwQ0Y0MkQxMUVGODA4RUNENTRFQzJENUU4RCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozNDA3NDEwQkY0MkQxMUVGODA4RUNENTRFQzJENUU4RCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRTREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Ph59M4AAAAPFSURBVHja7JZrSFNRHMDvvVvq1mNlucBK0g/lh+Us6oPrU0ERRFgRUqYUVEb2qTJ0vko0ZbMHiBT0sizSXEUfJGzN1CjBQLPCR/RwSYKp23RO3e527/r/57mxxpblhCD8w59z7t2553f+zx36Ulk5FYxkZpyiijVahUgkqnc62cu5arUGXrMl2tIkhmGuu91uGp4HXre0qB490A3C3IXfMVSQojl/QQYAHUzlNtvYPBhl2Xn5672gqBFxSmXF0WPpCTCfg+/EwUDBwkixeM4TmqZjzSbTFU1J8W00RiaTtUxMTJSfzctFd4Yq49eGJ6ekNETHxGyG50jQkWDAcoA+BqjSbDaXA/QqvBtFBWg6QGuJtSaapr7jB7AWrV0C6pguWAZurIeNFCaTqUxbUnwd3lkRAjoO0JswStApEGs1jJs4jusw9vTcEcI7LTBA3wA02mI2X/WFgvIIxCQC6EmIdQ7P898qb1Xs7O7qGiVrWWaa4C5PZopEy6RSKQfTYS8oRUYO1i3Hh4e6mlSA2sjhLHgwMdkoA04lI1noV8BVn/Nzsu/iFHTP2cIiHSTR9tNZaqYgP28/iecv4nA4ajmXi7NYLKPkcFbiDYomdcxNVVoul6s9JytzC/mYWxEVtfDQkbQKiUSyw26368/k5iTBexvZSxA0bD4Zx0An0E4B3Nfz5cu+zs4OJ+tgQwOBlfHxcSujo7MHBwfTLpZq69Cdq2NjFyWnpFaGhYVtA3hdU2PD4ecGQ78AhxjnQi6o29va1lVX3TNibAUwniSyq7PT+qKxcQjmduEHX0lQqSIgUZaOj4+FwyM2ipEP3d1msHRvQdG5GoQnqDYWAviEYDmErw/G1t7e3hAYQwiY+tm5Pn36aCdusATS+QsWDOBa8ArWInqGga6FltnQzcPDlrKvRmMTKSMRroXQ3AXd3fzq5ZCvQZ7kOnb8ONQXbYd+6/pNmBd70pXnfHPBAy8pKsojUNYruzmSEwzp0e5fwNCBFIFc7CXMZHbzIn9JT9wrJA/nVVasv8084PvVVVvftLbavIPvK6kHDqoUa9Zc+03J8V6WTike8FzpXJ4UtzUQOEIux98oCAdHzYCIJzsQw5M6s0LC+D01NIPxmQQz1D+SWfAs+D8FO1mn6w9uHUJ90zPSQOAvcdWOxERD4q5dSwjA/0KxuNmg1294/+7tGLlFuIOy+NbNG0b4s3YSSwIqyzr4Z/qnlv7+/iE/N42/FjokJBQ3lmI7JteUQK5E0Ajp6fZgLUaw0LNDp7juuomL2WCtRfkhwACjULOQ0RiwkAAAAABJRU5ErkJggg==");background-repeat:no-repeat}
#menu h1:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAYAAAC9pNwMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQUNCOTdFQkY0MkQxMUVGOUM0OUMyQTRDNjAyNzhENiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQUNCOTdFQUY0MkQxMUVGOUM0OUMyQTRDNjAyNzhENiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpFRTREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFODREQjFFMzE2RjRFRjExOTIyNkVEQzE2RkYzQkNDRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pq1mg9cAAAQtSURBVHja7JZdTFxFFIDP3J9dCgqUQimQIlBSWNoCNfVBYmo0jX9Jg014aYrWFzWGRl9MTHzpiy8k2kbrm9qUWtMaY9S2RqV9ADQm9o/+pHsvhW5Lw8/iLu6PC9yfvTOeWWbbC9ktlPWRk5ydvWfmzjfnzJkzlxz+7HNYSpIeD1QEAtB2+kew8vKgwdXn9Wsw1uR7tQTg+zhjfRs0fTeazWCT71ARwLt8jANgn0nMNO+9d+82nw6VSZCj3PE1VhcDnJIBpDnG8tC0TmvYvC8N5YJ9yq6C/L4/6je9jo8eVJITOMjY9lJCdBUdn6D0Sq0+9B6alTpZ7okwNrjGrzWjPnkwHO4oJKR8h8fzJfaXcLiUA3TLWkJ+x+WvQeglhL6N5jhqZIqxbyo1vQP/z6GOW5QN8nfI/KtrOVhZLogwllIuE4xVo6eXEJo3TumFOn2oS0D/Rv23WtPfxPYxVCvU5DuL41pMAOOWbf+ENu4sWR4YgUlVBUdRQHIcKJPlEQyvGqT02mLofC6BhRrFBPuhEOAZG20HJoOvHItEJtEeQ7WXFWrFtmGq+gm4+NLL6DUF23Ei3O4hpLRKVXkY/nFBRSKDjUlVxR8+Coc7BTSEGuZZr8w7xN6nlBZhS7LBqWHc3n/kyAkxaV2osWG4RJKqrtRvOluu6S0PtvCBxCg9iZtsBSwrJBYXEdFgKTAhpFuW5aW8v4p6RoTV7Bwb23F848aLxYRUhn2NN0o13Sf6kukX6vWhT7E5zoMm+mwOTTGxgIzfCQT2+v03bcu0vNmoLa2tzTW1tR+GpsNvHeru/pVP0FlcXHG4YsMFflSweEwdjUaf/2AyeEtEhWFincMM2/XzzOxzHaOjf6HNSIP5Sio1vz8+0NcXdncslqfb2sokSSqfTSRKRMbGTkSjE6hb0GM/h+8rKvoOwTtFAiUtxkYNQqI3TYNHkztlusEwMjJsiDMXzQZ+vLCQZy1gVFQxiWQ+u9P29g/EMMxNdxsbfhm2rH4+FHWWg6s0/QC2B0W1WjBvCvxOV9fXGHUD9zn5kD1el0oy6tzPhdM1tQD9A/ydWI0+9KKA8uShYogtkkpKJ9UCsKKoW7N56pIU0HGonDaMtG4H6OkBkVBxETUmgOljNZfxiPKfb0+dfGHw8uXE4lW55bX9b7Rt3bbtC/eR4wXFJY7rHC9dG/hPQX4BD820WHVGcNn69fHUTSPL9ydXDWPFF0wKLMkSB89wcPfHn9BMA03TnF0MxgKwYnDO9/EqeBW8Cl4Ati07ufTXD0ufb/J/gBW8Ejfvbm8/375nT6kAZB6oKH+e7+196sb1azPuC33FHh87+tVd/AKxhSdZ1bJMeq73t0gwGOT3duJR6nLGr1aPx8snzuflWFxr2ULpiAt++mEfDI8CTtdsb7p2Z9tmEWIrV2+5/CfAAOVxxSK4gGWJAAAAAElFTkSuQmCC")}
.rtl table.layout tbody td{display:flex}
.rtl table.layout~table thead th:first-child,.rtl table.layout~table tbody td:first-child{text-align:right !important}
.rtl table.layout~table thead th:last-child,.rtl table.layout~table tbody td:last-child{text-align:left !important}
h1{padding:.6em .4em;background:#1d5377;border:1px solid #f2ddaf;text-align:left}
#h1{color:#fff}
.version{color:#ddd;margin-left:8px}
@@ -99,7 +98,7 @@ code{background:#93b3c8;padding:.2em .5em}
table code{font-size:130%;background:#bfd9eb;padding:.1em .3em}
code.jush-sql{background:#d8e9f4}
.rtl p code.jush-sql{background-position:right;clear:right;float:right}
pre.sqlarea{background:#aac6d8;padding:5px}
pre{background:#aac6d8 !important;padding:5px}
textarea{font-size:120%}
.ltr p.count{font-size:90%;margin:.8em 20px 8px 0}
.rtl p.count{font-size:90%;margin:.8em 0 8px 20px}
@@ -119,12 +118,12 @@ table{border-spacing:0}
table,td,th{border:0;border-collapse:separate}
.ltr table{margin:1.9em 0 0 0}
.rtl table{margin:1.9em 0 0 0}
.rtl table tbody td,.rtl table tbody th{text-align:right}
.rtl table tbody td,.rtl table tbody th{text-align:right !important}
.ltr table thead td:first-child,.ltr table thead th:first-child{border-left:1px solid #0e344e}
.rtl table thead td:first-child,.rtl table thead th:first-child{border-right:1px solid #0e344e}
table thead td,table thead th{height:1.6em;border-top:1px solid #0e344e;border-bottom:1px solid #0e344e}
.ltr table thead td,.ltr table thead th{border-right:1px solid #0e344e}
.rtl table thead td,.rtl table thead th{border-left:1px solid #0e344e;text-align:right !important}
.rtl table thead td,.rtl table thead th{border-left:1px solid #0e344e}
table tbody tr:first-child td,table tbody tr:first-child th{border-top:1px solid #527d9a}
.ltr table tbody td:first-child,.ltr table tbody th:first-child{border-left:1px solid #527d9a}
.rtl table tbody td:first-child,.rtl table tbody th:first-child{border-right:1px solid #527d9a}
@@ -421,9 +420,12 @@ input[type=radio]{margin-bottom:5px}
.rtl input[type=checkbox],.rtl input[type=radio],.rtl input[type=range],.rtl progress{margin-left:5px}
.ltr input[type=submit]{margin-right:10px}
.rtl input[type=submit]{margin-left:10px}
.ltr table.layout label,.ltr label.jsonly{margin-left:8px}
.rtl table.layout label,.rtl label.jsonly{margin-right:8px}
input,button,select,.sqlarea{border-radius:3px}
.sqlarea{background:#aac6d8;font-size:105%}
fieldset a{line-height:unset}
input[type=submit]{padding:2px 6px}
.ltr table.layout label,.ltr label.jsonly{margin-left:8px}
.rtl table.layout label,.rtl label.jsonly{margin-right:8px}
#menu{padding:0 0 30px 0}
.ltr .logout{right:0;left:auto;margin-top:.5em}
.rtl .logout{left:0;right:auto;margin-top:.5em}

View File

@@ -20,7 +20,7 @@ if ($adminer->homepage()) {
foreach (table_status() as $table => $row) {
$name = $adminer->tableName($row);
if (isset($row["Engine"]) && $name != "") {
if ($name != "") {
echo '<tr><td>' . checkbox("tables[]", $table, in_array($table, (array) $_POST["tables"], true));
echo "<th><a href='" . h(ME) . 'select=' . urlencode($table) . "'>$name</a>";
$val = format_number($row["Rows"]);

View File

@@ -1,6 +1,5 @@
<?php
function adminer_object() {
class AdminerCds extends Adminer\Adminer {
function name() {

View File

@@ -2,8 +2,8 @@
namespace Adminer;
class Adminer {
var $operators = array("<=", ">=");
var $_values = array();
public $operators = array("<=", ">=");
private $values = array();
function name() {
return "<a href='https://www.adminer.org/editor/'" . target_blank() . " id='h1'>" . lang('Editor') . "</a>";
@@ -34,7 +34,7 @@ class Adminer {
if ($connection) {
$databases = $this->databases(false);
return (!$databases
? $connection->result("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', 1)") // username without the database list
? get_val("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', 1)") // username without the database list
: $databases[(information_schema($databases[0]) ? 1 : 0)] // first available database
);
}
@@ -90,7 +90,10 @@ class Adminer {
}
function tableName($tableStatus) {
return h($tableStatus["Comment"] != "" ? $tableStatus["Comment"] : $tableStatus["Name"]);
return h(isset($tableStatus["Engine"])
? ($tableStatus["Comment"] != "" ? $tableStatus["Comment"] : $tableStatus["Name"])
: "" // ignore views
);
}
function fieldName($field, $order = 0) {
@@ -175,7 +178,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row //! requires MySQL 5
$ids[$row[$key]] = q($row[$key]);
}
// uses constant number of queries to get the descriptions, join would be complex, multiple queries would be slow
$descriptions = $this->_values[$table];
$descriptions = $this->values[$table];
if (!$descriptions) {
$descriptions = get_key_vals("SELECT $id, $name FROM " . table($table) . " WHERE $id IN (" . implode(", ", $ids) . ")");
}
@@ -248,7 +251,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row //! requires MySQL 5
);
echo "</div>\n";
unset($columns[$name]);
} elseif (is_array($options = $this->_foreignKeyOptions($_GET["select"], $name))) {
} elseif (is_array($options = $this->foreignKeyOptions($_GET["select"], $name))) {
if ($fields[$name]["null"]) {
$options[0] = '(' . lang('empty') . ')';
}
@@ -482,7 +485,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row //! requires MySQL 5
. enum_input("radio", $attrs, $field, ($value || isset($_GET["select"]) ? $value : 0), ($field["null"] ? "" : null))
;
}
$options = $this->_foreignKeyOptions($table, $field["field"], $value);
$options = $this->foreignKeyOptions($table, $field["field"], $value);
if ($options !== null) {
return (is_array($options)
? "<select$attrs>" . optionlist($options, $value, true) . "</select>"
@@ -574,6 +577,9 @@ qsl('div').onclick = whisperClick;", "")
return $ext;
}
function dumpFooter() {
}
function importServerPath() {
}
@@ -629,7 +635,7 @@ qsl('div').onclick = whisperClick;", "")
foreach ($tables as $row) {
echo '<li>';
$name = $this->tableName($row);
if (isset($row["Engine"]) && $name != "") { // ignore views and tables without name
if ($name != "") { // ignore tables without name
echo "<a href='" . h(ME) . 'select=' . urlencode($row["Name"]) . "'"
. bold($_GET["select"] == $row["Name"] || $_GET["edit"] == $row["Name"], "select")
. " title='" . lang('Select data') . "'>$name</a>\n"
@@ -651,16 +657,15 @@ qsl('div').onclick = whisperClick;", "")
}
}
function _foreignKeyOptions($table, $column, $value = null) {
global $connection;
private function foreignKeyOptions($table, $column, $value = null) {
if (list($target, $id, $name) = $this->_foreignColumn(column_foreign_keys($table), $column)) {
$return = &$this->_values[$target];
$return = &$this->values[$target];
if ($return === null) {
$table_status = table_status($target);
$return = ($table_status["Rows"] > 1000 ? "" : array("" => "") + get_key_vals("SELECT $id, $name FROM " . table($target) . " ORDER BY 2"));
}
if (!$return && $value !== null) {
return $connection->result("SELECT $name FROM " . table($target) . " WHERE $id = " . q($value));
return get_val("SELECT $name FROM " . table($target) . " WHERE $id = " . q($value));
}
return $return;
}

2
externals/jush vendored

View File

@@ -32,27 +32,40 @@ foreach (glob(__DIR__ . "/adminer/lang/" . ($_SESSION["lang"] ?: "*") . ".inc.ph
$messages = $messages_all;
$file = file_get_contents($filename);
$file = str_replace("\r", "", $file);
preg_match_all("~^(\\s*(?:// [^'].*\\s+)?)(?:// )?(('(?:[^\\\\']+|\\\\.)*') => .*[^,\n]),?~m", $file, $matches, PREG_SET_ORDER);
preg_match_all("~^(\\s*(?:// [^'].*\\s+)?)(?:// )?(('(?:[^\\\\']+|\\\\.)*') => (.*[^,\n])),?~m", $file, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
$s = "";
$lang = basename($filename, ".inc.php");
$fullstop = ($lang == "bn" ? '।' : (preg_match('~^(ja|zh)~', $lang) ? '。' : ($lang == 'he' ? '[^.]' : '\.')));
foreach ($matches as $match) {
if (isset($messages[$match[3]])) {
list(, list($indent), list($line, $offset), list($en), list($translation)) = $match;
if (isset($messages[$en])) {
// keep current messages
$s .= "$match[1]$match[2],\n";
unset($messages[$match[3]]);
$s .= "$indent$line,\n";
unset($messages[$en]);
$en_fullstop = (substr($en, -2, 1) == ".");
//! check in array
if ($en != "','" && ($en_fullstop xor preg_match("~$fullstop'\)?\$~", $line))) {
if ($lang != ($en_fullstop ? "ja" : "he")) { // fullstop is optional in 'ja', forbidden in 'he'
echo "$filename:" . (substr_count($file, "\n", 0, $offset) + 1) . ":Not matching fullstop: $line\n";
}
}
if (preg_match('~%~', $en) xor preg_match('~%~', $translation)) {
echo "$filename:" . (substr_count($file, "\n", 0, $offset) + 1) . ":Not matching placeholder.\n";
}
} else {
// comment deprecated messages
$s .= "$match[1]// $match[2],\n";
$s .= "$indent// $line,\n";
}
}
if ($messages) {
if (basename($filename) != "en.inc.php") {
if ($lang != "en") {
$s .= "\n";
}
foreach ($messages as $idf => $val) {
// add new messages
if ($val == "," && strpos($idf, "%d")) {
$s .= "\t$idf => array(),\n";
} elseif (basename($filename) != "en.inc.php") {
} elseif ($lang != "en") {
$s .= "\t$idf => null,\n";
}
}

144
php_shrink.inc.php Normal file
View File

@@ -0,0 +1,144 @@
<?php
/** Minify PHP code with these operations:
* remove extra {}
* minify variables
* strip comments, preserve only the first doc-comment
* join consecutive echo
* change ?>HTML<?php to echo 'HTML' if it saves space
* strip public visibility or change it to var
*
* @param string PHP code including <?php
* @return string
*/
function php_shrink($input) {
// based on http://latrine.dgx.cz/jak-zredukovat-php-skripty
$input = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $input);
$special_variables = array_flip(array('$this', '$GLOBALS', '$_GET', '$_POST', '$_FILES', '$_COOKIE', '$_SESSION', '$_SERVER', '$http_response_header', '$php_errormsg'));
$short_variables = array();
$shortening = true;
$tokens = token_get_all($input);
// remove unnecessary { }
//! change also `while () { if () {;} }` to `while () if () ;` but be careful about `if () { if () { } } else { }
$shorten = 0;
$opening = -1;
foreach ($tokens as $i => $token) {
if (in_array($token[0], array(T_IF, T_ELSE, T_ELSEIF, T_WHILE, T_DO, T_FOR, T_FOREACH), true)) {
$shorten = ($token[0] == T_FOR ? 4 : 2);
$opening = -1;
} elseif (in_array($token[0], array(T_SWITCH, T_FUNCTION, T_CLASS, T_CLOSE_TAG), true)) {
$shorten = 0;
} elseif ($token === ';') {
$shorten--;
} elseif ($token === '{') {
if ($opening < 0) {
$opening = $i;
} elseif ($shorten > 1) {
$shorten = 0;
}
} elseif ($token === '}' && $opening >= 0 && $shorten == 1) {
unset($tokens[$opening]);
unset($tokens[$i]);
$shorten = 0;
$opening = -1;
}
}
$tokens = array_values($tokens);
foreach ($tokens as $i => $token) {
if ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
$short_variables[$token[1]]++;
}
}
arsort($short_variables);
$chars = implode(range('a', 'z')) . '_' . implode(range('A', 'Z'));
//! preserve variable names between versions if possible
$short_variables2 = array_splice($short_variables, strlen($chars));
ksort($short_variables);
ksort($short_variables2);
$short_variables += $short_variables2;
foreach (array_keys($short_variables) as $number => $key) {
$short_variables[$key] = short_identifier($number, $chars); // could use also numbers and \x7f-\xff
}
$set = array_flip(preg_split('//', '!"#$%&\'()*+,-./:;<=>?@[]^`{|}'));
$space = '';
$output = '';
$in_echo = false;
$doc_comment = false; // include only first /**
for (reset($tokens); list($i, $token) = each($tokens);) {
if (!is_array($token)) {
$token = array(0, $token);
}
if (
$tokens[$i+2][0] === T_CLOSE_TAG && $tokens[$i+3][0] === T_INLINE_HTML && $tokens[$i+4][0] === T_OPEN_TAG
&& strlen(add_apo_slashes($tokens[$i+3][1])) < strlen($tokens[$i+3][1]) + 3
) {
$tokens[$i+2] = array(T_ECHO, 'echo');
$tokens[$i+3] = array(T_CONSTANT_ENCAPSED_STRING, "'" . add_apo_slashes($tokens[$i+3][1]) . "'");
$tokens[$i+4] = array(0, ';');
}
if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE || ($token[0] == T_DOC_COMMENT && $doc_comment)) {
$space = "\n";
} else {
if ($token[0] == T_DOC_COMMENT) {
$doc_comment = true;
}
if ($token[0] == T_VAR || $token[0] == T_PUBLIC || $token[0] == T_PROTECTED || $token[0] == T_PRIVATE) {
if ($token[0] == T_PUBLIC) {
$token[1] = ($tokens[$i+2][1][0] == '$' ? 'var' : '');
}
$shortening = false;
} elseif (!$shortening) {
if ($token[1] == ';' || $token[0] == T_FUNCTION) {
$shortening = true;
}
} elseif ($token[0] == T_ECHO) {
$in_echo = true;
} elseif ($token[1] == ';' && $in_echo) {
if ($tokens[$i+1][0] === T_WHITESPACE && $tokens[$i+2][0] === T_ECHO) {
next($tokens);
$i++;
}
if ($tokens[$i+1][0] === T_ECHO) {
// join two consecutive echos
next($tokens);
$token[1] = ','; // '.' would conflict with "a".1+2 and would use more memory //! remove ',' and "," but not $var","
} else {
$in_echo = false;
}
} elseif ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
$token[1] = '$' . $short_variables[$token[1]];
}
if (isset($set[substr($output, -1)]) || isset($set[$token[1][0]])) {
$space = '';
}
$output .= $space . $token[1];
$space = '';
}
}
return $output;
}
function short_identifier($number, $chars) {
$return = '';
while ($number >= 0) {
$return .= $chars[$number % strlen($chars)];
$number = floor($number / strlen($chars)) - 1;
}
return $return;
}
function add_apo_slashes($s) {
return addcslashes($s, "\\'");
}
if (!function_exists("each")) {
function each(&$arr) {
$key = key($arr);
next($arr);
return $key === null ? false : array($key, $arr[$key]);
}
}

View File

@@ -12,8 +12,6 @@
<rule ref="PSR12">
<exclude name="Generic.Whitespace.DisallowTabIndent"/><!-- Replaced by: Generic.Whitespace.DisallowSpaceIndent -->
<exclude name="PSR1.Files.SideEffects.FoundWithSymbols"/>
<exclude name="PSR12.Operators.OperatorSpacing.NoSpaceBefore"/>
<exclude name="PSR12.Operators.OperatorSpacing.NoSpaceAfter"/>
<exclude name="PSR1.Classes.ClassDeclaration.MultipleClasses"/>
<exclude name="PSR2.Classes.ClassDeclaration.OpenBraceNewLine"/><!-- Replaced by: Generic.Classes.OpeningBraceSameLine -->
<exclude name="PSR2.Classes.PropertyDeclaration.Underscore"/>
@@ -24,11 +22,12 @@
<!-- More readable. -->
<exclude name="PSR12.Files.FileHeader.SpacingAfterBlock"/>
<exclude name="PSR12.Classes.OpeningBraceSpace.Found"/>
<exclude name="PSR12.Operators.OperatorSpacing.NoSpaceBefore"/>
<exclude name="PSR12.Operators.OperatorSpacing.NoSpaceAfter"/>
<exclude name="Squiz.WhiteSpace.ControlStructureSpacing.SpacingBeforeClose"/>
<!-- Saves bytes. -->
<exclude name="PSR2.Classes.PropertyDeclaration.Multiple"/>
<exclude name="PSR2.Classes.PropertyDeclaration.VarUsed"/>
<exclude name="PSR2.Classes.PropertyDeclaration.ScopeMissing"/>
<exclude name="PSR12.Classes.ClassInstantiation.MissingParentheses"/>
<exclude name="Squiz.Scope.MethodScope.Missing"/>
@@ -46,7 +45,7 @@
<rule ref="Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="310"/>
<property name="lineLimit" value="250"/>
</properties>
<exclude-pattern>adminer/lang/</exclude-pattern>
</rule>
@@ -79,4 +78,51 @@
<rule ref="Generic.VersionControl.GitMergeConflict"/>
<rule ref="Generic.Whitespace.DisallowSpaceIndent"/>
<rule ref="Generic.WhiteSpace.LanguageConstructSpacing"/>
<rule ref="Squiz.Arrays.ArrayBracketSpacing"/>
<rule ref="Squiz.Classes.LowercaseClassKeywords"/>
<rule ref="Squiz.Classes.SelfMemberReference"/>
<rule ref="Squiz.CSS.ClassDefinitionNameSpacing"/>
<rule ref="Squiz.CSS.ColonSpacing"/>
<rule ref="Squiz.CSS.DuplicateClassDefinition"/>
<rule ref="Squiz.CSS.DuplicateStyleDefinition"/>
<rule ref="Squiz.CSS.EmptyClassDefinition"/>
<rule ref="Squiz.CSS.EmptyStyleDefinition"/>
<rule ref="Squiz.CSS.ForbiddenStyles"/>
<rule ref="Squiz.CSS.Indentation"/>
<rule ref="Squiz.CSS.MissingColon"/>
<rule ref="Squiz.CSS.Opacity"/>
<rule ref="Squiz.CSS.SemicolonSpacing"/>
<rule ref="Squiz.Functions.FunctionDuplicateArgument"/>
<rule ref="Squiz.Objects.ObjectMemberComma"/>
<rule ref="Squiz.Operators.IncrementDecrementUsage"/>
<rule ref="Squiz.Operators.ValidLogicalOperators"/>
<rule ref="Squiz.PHP.DiscouragedFunctions"/>
<rule ref="Squiz.PHP.Eval"/>
<rule ref="Squiz.PHP.Heredoc"/>
<rule ref="Squiz.PHP.InnerFunctions"/>
<rule ref="Squiz.PHP.LowercasePHPFunctions"/>
<rule ref="Squiz.PHP.NonExecutableCode"/>
<rule ref="Squiz.Scope.StaticThisUsage"/>
<rule ref="Squiz.WhiteSpace.FunctionOpeningBraceSpace"/>
<rule ref="Squiz.WhiteSpace.LanguageConstructSpacing"/>
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
<rule ref="Squiz.WhiteSpace.ObjectOperatorSpacing"/>
<!--
This is slow and has false positives but it's useful occasionally.
https://github.com/PHPCompatibility/PHPCompatibility
<rule ref="PHPCompatibility"/>
<config name="testVersion" value="5.3-"/>
<rule ref="PHPCompatibility.Extensions.RemovedExtensions">
<exclude name="PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved"/>
<exclude name="PHPCompatibility.Extensions.RemovedExtensions.ibaseRemoved"/>
</rule>
<rule ref="PHPCompatibility.Constants.RemovedConstants">
<exclude-pattern>adminer/plugins/drivers/firebird.php</exclude-pattern>
</rule>
<rule ref="PHPCompatibility.FunctionUse.RemovedFunctions">
<exclude-pattern>adminer/plugins/drivers/firebird.php</exclude-pattern>
</rule>
-->
</ruleset>

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/
class AdminerDesigns {
/** @access protected */
var $designs;
protected $designs;
/**
* @param array URL in key, name in value

View File

@@ -8,11 +8,12 @@ if (isset($_GET["clickhouse"])) {
if (ini_bool('allow_url_fopen')) {
class Db {
var $extension = "JSON", $server_info, $errno, $_result, $error, $_url;
var $_db = 'default';
public $extension = "JSON", $server_info, $errno, $error;
public $_db = 'default';
private $result, $url;
function rootQuery($db, $query) {
$file = @file_get_contents("$this->_url/?database=$db", false, stream_context_create(array('http' => array(
$file = @file_get_contents("$this->url/?database=$db", false, stream_context_create(array('http' => array(
'method' => 'POST',
'content' => $this->isQuerySelectLike($query) ? "$query FORMAT JSONCompact" : $query,
'header' => 'Content-type: application/x-www-form-urlencoded',
@@ -57,7 +58,7 @@ if (isset($_GET["clickhouse"])) {
function connect($server, $username, $password) {
preg_match('~^(https?://)?(.*)~', $server, $match);
$this->_url = ($match[1] ?: "http://") . urlencode($username) . ":" . urlencode($password) . "@$match[2]";
$this->url = ($match[1] ?: "http://") . urlencode($username) . ":" . urlencode($password) . "@$match[2]";
$return = $this->query('SELECT 1');
return (bool) $return;
}
@@ -72,11 +73,11 @@ if (isset($_GET["clickhouse"])) {
}
function multi_query($query) {
return $this->_result = $this->query($query);
return $this->result = $this->query($query);
}
function store_result() {
return $this->_result;
return $this->result;
}
function next_result() {
@@ -90,7 +91,8 @@ if (isset($_GET["clickhouse"])) {
}
class Result {
var $num_rows, $_rows, $columns, $meta, $_offset = 0;
public $num_rows, $columns, $meta;
private $rows, $offset = 0;
function __construct($result) {
foreach ($result['data'] as $item) {
@@ -98,28 +100,28 @@ if (isset($_GET["clickhouse"])) {
foreach ($item as $key => $val) {
$row[$key] = is_scalar($val) ? $val : json_encode($val, 256); // 256 - JSON_UNESCAPED_UNICODE
}
$this->_rows[] = $row;
$this->rows[] = $row;
}
$this->num_rows = $result['rows'];
$this->meta = $result['meta'];
$this->columns = array_column($this->meta, 'name');
reset($this->_rows);
reset($this->rows);
}
function fetch_assoc() {
$row = current($this->_rows);
next($this->_rows);
$row = current($this->rows);
next($this->rows);
return $row === false ? false : array_combine($this->columns, $row);
}
function fetch_row() {
$row = current($this->_rows);
next($this->_rows);
$row = current($this->rows);
next($this->rows);
return $row;
}
function fetch_field() {
$column = $this->_offset++;
$column = $this->offset++;
$return = new \stdClass;
if ($column < count($this->columns)) {
$return->name = $this->meta[$column]['name'];
@@ -135,13 +137,18 @@ if (isset($_GET["clickhouse"])) {
static $possibleDrivers = array("allow_url_fopen");
static $jush = "clickhouse";
var $operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL");
var $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
public $operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL");
public $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
function __construct($connection) {
parent::__construct($connection);
$this->types = array( //! arrays
lang('Numbers') => array("Int8" => 3, "Int16" => 5, "Int32" => 10, "Int64" => 19, "UInt8" => 3, "UInt16" => 5, "UInt32" => 10, "UInt64" => 20, "Float32" => 7, "Float64" => 16, 'Decimal' => 38, 'Decimal32' => 9, 'Decimal64' => 18, 'Decimal128' => 38),
lang('Numbers') => array(
"Int8" => 3, "Int16" => 5, "Int32" => 10, "Int64" => 19,
"UInt8" => 3, "UInt16" => 5, "UInt32" => 10, "UInt64" => 20,
"Float32" => 7, "Float64" => 16,
'Decimal' => 38, 'Decimal32' => 9, 'Decimal64' => 18, 'Decimal128' => 38,
),
lang('Date and time') => array("Date" => 13, "DateTime" => 20),
lang('Strings') => array("String" => 0),
lang('Binary') => array("FixedString" => 0),
@@ -340,7 +347,7 @@ if (isset($_GET["clickhouse"])) {
"default" => trim($row['default_expression']),
"null" => $nullable,
"auto_increment" => '0',
"privileges" => array("insert" => 1, "select" => 1, "update" => 0),
"privileges" => array("insert" => 1, "select" => 1, "update" => 0, "where" => 1, "order" => 1),
);
}

View File

@@ -9,7 +9,8 @@ if (isset($_GET["elastic"])) {
if (ini_bool('allow_url_fopen')) {
class Db {
var $extension = "JSON", $server_info, $errno, $error, $_url;
public $extension = "JSON", $server_info, $errno, $error;
private $url;
/**
* @param string $path
@@ -18,7 +19,7 @@ if (isset($_GET["elastic"])) {
* @return array|false
*/
function rootQuery($path, array $content = null, $method = 'GET') {
$file = @file_get_contents("$this->_url/" . ltrim($path, '/'), false, stream_context_create(array('http' => array(
$file = @file_get_contents("$this->url/" . ltrim($path, '/'), false, stream_context_create(array('http' => array(
'method' => $method,
'content' => $content !== null ? json_encode($content) : null,
'header' => $content !== null ? 'Content-Type: application/json' : array(),
@@ -78,7 +79,7 @@ if (isset($_GET["elastic"])) {
*/
function connect($server, $username, $password) {
preg_match('~^(https?://)?(.*)~', $server, $match);
$this->_url = ($match[1] ?: "http://") . urlencode($username) . ":" . urlencode($password) . "@$match[2]";
$this->url = ($match[1] ?: "http://") . urlencode($username) . ":" . urlencode($password) . "@$match[2]";
$return = $this->query('');
if ($return) {
$this->server_info = $return['version']['number'];
@@ -96,18 +97,19 @@ if (isset($_GET["elastic"])) {
}
class Result {
var $num_rows, $_rows;
public $num_rows;
private $rows;
function __construct($rows) {
$this->num_rows = count($rows);
$this->_rows = $rows;
$this->rows = $rows;
reset($this->_rows);
reset($this->rows);
}
function fetch_assoc() {
$return = current($this->_rows);
next($this->_rows);
$return = current($this->rows);
next($this->rows);
return $return;
}
@@ -124,8 +126,8 @@ if (isset($_GET["elastic"])) {
static $possibleDrivers = array("json + allow_url_fopen");
static $jush = "elastic";
var $editFunctions = array(array("json"));
var $operators = array("=", "must", "should", "must_not");
public $editFunctions = array(array("json"));
public $operators = array("=", "must", "should", "must_not");
function __construct($connection) {
parent::__construct($connection);
@@ -197,7 +199,7 @@ if (isset($_GET["elastic"])) {
$query = "$table/_search";
$start = microtime(true);
$search = $this->_conn->rootQuery($query, $data);
$search = $this->conn->rootQuery($query, $data);
if ($print) {
echo adminer()->selectQuery("$query: " . json_encode($data), $start, !$search);
@@ -205,6 +207,9 @@ if (isset($_GET["elastic"])) {
if (empty($search)) {
return false;
}
if ($select == array("*")) {
$tableFields = array_keys(fields($table));
}
$return = array();
foreach ($search["hits"]["hits"] as $hit) {
@@ -219,7 +224,9 @@ if (isset($_GET["elastic"])) {
$fields[$key] = $key == "_id" ? $hit["_id"] : $hit["_source"][$key];
}
} else {
$fields = $hit["_source"];
foreach ($tableFields as $key) {
$fields[$key] = $key == "_id" ? $hit["_id"] : $hit["_source"][$key];
}
}
foreach ($fields as $key => $val) {
$row[$key] = (is_array($val) ? json_encode($val) : $val);
@@ -238,19 +245,30 @@ if (isset($_GET["elastic"])) {
$id = trim($parts[1]);
$query = "$type/$id";
return $this->_conn->query($query, $record, 'POST');
return $this->conn->query($query, $record, 'POST');
}
return false;
}
function insert($type, $record) {
$id = ""; //! user should be able to inform _id
$query = "$type/$id";
$response = $this->_conn->query($query, $record, 'POST');
$this->_conn->last_id = $response['_id'];
$query = "$type/_doc/";
if (isset($record["_id"]) && $record["_id"] != "NULL") {
$query .= $record["_id"];
unset($record["_id"]);
}
foreach ($record as $key => $value) {
if ($value == "NULL") {
unset($record[$key]);
}
}
$response = $this->conn->query($query, $record, 'POST');
if ($response == false) {
return false;
}
$this->conn->last_id = $response['_id'];
return $response['created'];
return $response['result'];
}
function delete($table, $queryWhere, $limit = 0) {
@@ -268,17 +286,17 @@ if (isset($_GET["elastic"])) {
}
}
$this->_conn->affected_rows = 0;
$this->conn->affected_rows = 0;
foreach ($ids as $id) {
$query = "$table/_doc/$id";
$response = $this->_conn->query($query, null, 'DELETE');
$response = $this->conn->query($query, null, 'DELETE');
if (isset($response['result']) && $response['result'] == 'deleted') {
$this->_conn->affected_rows++;
$this->conn->affected_rows++;
}
}
return $this->_conn->affected_rows;
return $this->conn->affected_rows;
}
function convertOperator($operator) {
@@ -466,20 +484,17 @@ if (isset($_GET["elastic"])) {
"field" => "_id",
"full_type" => "text",
"type" => "text",
"null" => true,
"privileges" => array("insert" => 1, "select" => 1, "where" => 1, "order" => 1),
)
);
foreach ($mappings as $name => $field) {
$has_index = !isset($field["index"]) || $field["index"];
// TODO: privileges: where => $has_index
// TODO: privileges: sort => $field["type"] != "text"
$result[$name] = array(
"field" => $name,
"full_type" => $field["type"],
"type" => $field["type"],
"null" => true,
"privileges" => array(
"insert" => 1,
"select" => 1,

View File

@@ -12,14 +12,15 @@ if (isset($_GET["firebird"])) {
if (extension_loaded("interbase")) {
class Db {
var
public
$extension = "Firebird",
$server_info,
$affected_rows,
$errno,
$error,
$_link, $_result
$_link
;
private $result;
function connect($server, $username, $password) {
$this->_link = ibase_connect($server, $username, $password);
@@ -58,11 +59,11 @@ if (isset($_GET["firebird"])) {
}
function multi_query($query) {
return $this->_result = $this->query($query);
return $this->result = $this->query($query);
}
function store_result() {
return $this->_result;
return $this->result;
}
function next_result() {
@@ -80,23 +81,24 @@ if (isset($_GET["firebird"])) {
}
class Result {
var $num_rows, $_result, $_offset = 0;
public $num_rows;
private $result, $offset = 0;
function __construct($result) {
$this->_result = $result;
$this->result = $result;
// $this->num_rows = ibase_num_rows($result);
}
function fetch_assoc() {
return ibase_fetch_assoc($this->_result);
return ibase_fetch_assoc($this->result);
}
function fetch_row() {
return ibase_fetch_row($this->_result);
return ibase_fetch_row($this->result);
}
function fetch_field() {
$field = ibase_field_info($this->_result, $this->_offset++);
$field = ibase_field_info($this->result, $this->offset++);
return (object) array(
'name' => $field['name'],
'orgname' => $field['name'],
@@ -106,7 +108,7 @@ if (isset($_GET["firebird"])) {
}
function __destruct() {
ibase_free_result($this->_result);
ibase_free_result($this->result);
}
}
@@ -118,7 +120,7 @@ if (isset($_GET["firebird"])) {
static $possibleDrivers = array("interbase");
static $jush = "firebird";
var $operators = array("=");
public $operators = array("=");
}
@@ -254,7 +256,7 @@ ORDER BY r.RDB$FIELD_POSITION';
"null" => (trim($row["FIELD_NOT_NULL_CONSTRAINT"]) == "YES"),
"auto_increment" => '0',
"collation" => trim($row["FIELD_COLLATION"]),
"privileges" => array("insert" => 1, "select" => 1, "update" => 1),
"privileges" => array("insert" => 1, "select" => 1, "update" => 1, "where" => 1, "order" => 1),
"comment" => trim($row["FIELD_DESCRIPTION"]),
);
}

View File

@@ -1,24 +1,28 @@
<?php
namespace Adminer;
$drivers["mongo"] = "MongoDB (alpha)";
add_driver("mongo", "MongoDB (alpha)");
if (isset($_GET["mongo"])) {
define('Adminer\DRIVER', "mongo");
if (class_exists('MongoDB\Driver\Manager')) {
class Db {
var $extension = "MongoDB", $server_info = MONGODB_VERSION, $affected_rows, $error, $last_id;
public $extension = "MongoDB", $server_info = MONGODB_VERSION, $affected_rows, $error, $last_id;
/** @var MongoDB\Driver\Manager */
var $_link;
var $_db, $_db_name;
public $_link;
public $_db, $_db_name;
function connect($uri, $options) {
$this->_link = new \MongoDB\Driver\Manager($uri, $options);
$this->executeCommand($options["db"], array('ping' => 1));
$this->executeDbCommand($options["db"], array('ping' => 1));
}
function executeCommand($db, $command) {
function executeCommand($command) {
return $this->executeDbCommand($this->_db_name);
}
function executeDbCommand($db, $command) {
try {
return $this->_link->executeCommand($db, new \MongoDB\Driver\Command($command));
} catch (Exception $e) {
@@ -53,14 +57,15 @@ if (isset($_GET["mongo"])) {
}
class Result {
var $num_rows, $_rows = array(), $_offset = 0, $_charset = array();
public $num_rows;
private $rows = array(), $offset = 0, $charset = array();
function __construct($result) {
foreach ($result as $item) {
$row = array();
foreach ($item as $key => $val) {
if (is_a($val, 'MongoDB\BSON\Binary')) {
$this->_charset[$key] = 63;
$this->charset[$key] = 63;
}
$row[$key] =
(is_a($val, 'MongoDB\BSON\ObjectID') ? 'MongoDB\BSON\ObjectID("' . "$val\")" :
@@ -71,26 +76,26 @@ if (isset($_GET["mongo"])) {
$val // MongoMinKey, MongoMaxKey
)))));
}
$this->_rows[] = $row;
$this->rows[] = $row;
foreach ($row as $key => $val) {
if (!isset($this->_rows[0][$key])) {
$this->_rows[0][$key] = null;
if (!isset($this->rows[0][$key])) {
$this->rows[0][$key] = null;
}
}
}
$this->num_rows = count($this->_rows);
$this->num_rows = count($this->rows);
}
function fetch_assoc() {
$row = current($this->_rows);
$row = current($this->rows);
if (!$row) {
return $row;
}
$return = array();
foreach ($this->_rows[0] as $key => $val) {
foreach ($this->rows[0] as $key => $val) {
$return[$key] = $row[$key];
}
next($this->_rows);
next($this->rows);
return $return;
}
@@ -103,11 +108,11 @@ if (isset($_GET["mongo"])) {
}
function fetch_field() {
$keys = array_keys($this->_rows[0]);
$name = $keys[$this->_offset++];
$keys = array_keys($this->rows[0]);
$name = $keys[$this->offset++];
return (object) array(
'name' => $name,
'charsetnr' => $this->_charset[$name],
'charsetnr' => $this->charset[$name],
);
}
}
@@ -115,9 +120,8 @@ if (isset($_GET["mongo"])) {
function get_databases($flush) {
global $connection;
$return = array();
foreach ($connection->executeCommand($connection->_db_name, array('listDatabases' => 1)) as $dbs) {
foreach (connection()->executeCommand(array('listDatabases' => 1)) as $dbs) {
foreach ($dbs->databases as $db) {
$return[] = $db->name;
}
@@ -131,9 +135,8 @@ if (isset($_GET["mongo"])) {
}
function tables_list() {
global $connection;
$collections = array();
foreach ($connection->executeCommand($connection->_db_name, array('listCollections' => 1)) as $result) {
foreach (connection()->executeCommand(array('listCollections' => 1)) as $result) {
$collections[$result->name] = 'table';
}
return $collections;
@@ -144,9 +147,8 @@ if (isset($_GET["mongo"])) {
}
function indexes($table, $connection2 = null) {
global $connection;
$return = array();
foreach ($connection->executeCommand($connection->_db_name, array('listIndexes' => $table)) as $index) {
foreach (connection()->executeCommand(array('listIndexes' => $table)) as $index) {
$descs = array();
$columns = array();
foreach (get_object_vars($index->key) as $column => $type) {
@@ -164,7 +166,7 @@ if (isset($_GET["mongo"])) {
}
function fields($table) {
global $driver;
$driver = get_driver();
$fields = fields_from_edit();
if (!$fields) {
$result = $driver->select($table, array("*"), null, null, array(), 10);
@@ -181,6 +183,8 @@ if (isset($_GET["mongo"])) {
"insert" => 1,
"select" => 1,
"update" => 1,
"where" => 1,
"order" => 1,
),
);
}
@@ -191,9 +195,8 @@ if (isset($_GET["mongo"])) {
}
function found_rows($table_status, $where) {
global $connection;
$where = where_to_query($where);
$toArray = $connection->executeCommand($connection->_db_name, array('count' => $table_status['Name'], 'query' => $where))->toArray();
$toArray = connection()->executeCommand(array('count' => $table_status['Name'], 'query' => $where))->toArray();
return $toArray[0]->n;
}
@@ -218,7 +221,6 @@ if (isset($_GET["mongo"])) {
}
function where_to_query($whereAnd = array(), $whereOr = array()) {
global $adminer;
$data = array();
foreach (array('and' => $whereAnd, 'or' => $whereOr) as $type => $where) {
if (is_array($where)) {
@@ -228,7 +230,7 @@ if (isset($_GET["mongo"])) {
list(, $class, $val) = $match;
$val = new $class($val);
}
if (!in_array($op, $adminer->operators)) {
if (!in_array($op, adminer()->operators)) {
continue;
}
if (preg_match('~^\(f\)(.+)~', $op, $match)) {
@@ -282,9 +284,9 @@ if (isset($_GET["mongo"])) {
static $possibleDrivers = array("mongodb");
static $jush = "mongo";
var $editFunctions = array(array("json"));
public $editFunctions = array(array("json"));
var $operators = array(
public $operators = array(
"=",
"!=",
">",
@@ -328,15 +330,15 @@ if (isset($_GET["mongo"])) {
$limit = min(200, max(1, (int) $limit));
$skip = $page * $limit;
try {
return new Result($this->_conn->_link->executeQuery("$connection->_db_name.$table", new \MongoDB\Driver\Query($where, array('projection' => $select, 'limit' => $limit, 'skip' => $skip, 'sort' => $sort))));
return new Result($this->conn->_link->executeQuery($this->conn->_db_name . ".$table", new \MongoDB\Driver\Query($where, array('projection' => $select, 'limit' => $limit, 'skip' => $skip, 'sort' => $sort))));
} catch (Exception $e) {
$connection->error = $e->getMessage();
$this->conn->error = $e->getMessage();
return false;
}
}
function update($table, $set, $queryWhere, $limit = 0, $separator = "\n") {
$db = $this->_conn->_db_name;
$db = $this->conn->_db_name;
$where = sql_query_where_parser($queryWhere);
$bulk = new \MongoDB\Driver\BulkWrite(array());
if (isset($set['_id'])) {
@@ -354,25 +356,25 @@ if (isset($_GET["mongo"])) {
$update['$unset'] = $removeFields;
}
$bulk->update($where, $update, array('upsert' => false));
return $this->_conn->executeBulkWrite("$db.$table", $bulk, 'getModifiedCount');
return $this->conn->executeBulkWrite("$db.$table", $bulk, 'getModifiedCount');
}
function delete($table, $queryWhere, $limit = 0) {
$db = $this->_conn->_db_name;
$db = $this->conn->_db_name;
$where = sql_query_where_parser($queryWhere);
$bulk = new \MongoDB\Driver\BulkWrite(array());
$bulk->delete($where, array('limit' => $limit));
return $this->_conn->executeBulkWrite("$db.$table", $bulk, 'getDeletedCount');
return $this->conn->executeBulkWrite("$db.$table", $bulk, 'getDeletedCount');
}
function insert($table, $set) {
$db = $this->_conn->_db_name;
$db = $this->conn->_db_name;
$bulk = new \MongoDB\Driver\BulkWrite(array());
if ($set['_id'] == '') {
unset($set['_id']);
}
$bulk->insert($set);
return $this->_conn->executeBulkWrite("$db.$table", $bulk, 'getInsertedCount');
return $this->conn->executeBulkWrite("$db.$table", $bulk, 'getInsertedCount');
}
}
@@ -402,13 +404,11 @@ if (isset($_GET["mongo"])) {
}
function last_id() {
global $connection;
return $connection->last_id;
return connection()->last_id;
}
function error() {
global $connection;
return h($connection->error);
return h(connection()->error);
}
function collations() {
@@ -416,13 +416,11 @@ if (isset($_GET["mongo"])) {
}
function logged_user() {
global $adminer;
$credentials = $adminer->credentials();
$credentials = adminer()->credentials();
return $credentials[1];
}
function connect($credentials) {
global $adminer;
$connection = new Db;
list($server, $username, $password) = $credentials;
@@ -435,7 +433,7 @@ if (isset($_GET["mongo"])) {
$options["username"] = $username;
$options["password"] = $password;
}
$db = $adminer->database();
$db = adminer()->database();
if ($db != "") {
$options["db"] = $db;
}
@@ -450,7 +448,7 @@ if (isset($_GET["mongo"])) {
}
function alter_indexes($table, $alter) {
global $connection;
$connection = connection();
foreach ($alter as $val) {
list($type, $name, $set) = $val;
if ($set == "DROP") {
@@ -507,17 +505,15 @@ if (isset($_GET["mongo"])) {
}
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
global $connection;
if ($table == "") {
$connection->_db->createCollection($name);
connection()->_db->createCollection($name);
return true;
}
}
function drop_tables($tables) {
global $connection;
foreach ($tables as $table) {
$response = $connection->_db->selectCollection($table)->drop();
$response = connection()->_db->selectCollection($table)->drop();
if (!$response['ok']) {
return false;
}
@@ -526,9 +522,8 @@ if (isset($_GET["mongo"])) {
}
function truncate_tables($tables) {
global $connection;
foreach ($tables as $table) {
$response = $connection->_db->selectCollection($table)->remove();
$response = connection()->_db->selectCollection($table)->remove();
if (!$response['ok']) {
return false;
}

View File

@@ -8,7 +8,8 @@ if (isset($_GET["simpledb"])) {
if (class_exists('SimpleXMLElement') && ini_bool('allow_url_fopen')) {
class Db {
var $extension = "SimpleXML", $server_info = '2009-04-15', $error, $timeout, $next, $affected_rows, $_result;
public $extension = "SimpleXML", $server_info = '2009-04-15', $error, $timeout, $next, $affected_rows;
private $result;
function select_db($database) {
return ($database == "domain");
@@ -38,11 +39,11 @@ if (isset($_GET["simpledb"])) {
}
function multi_query($query) {
return $this->_result = $this->query($query);
return $this->result = $this->query($query);
}
function store_result() {
return $this->_result;
return $this->result;
}
function next_result() {
@@ -55,7 +56,8 @@ if (isset($_GET["simpledb"])) {
}
class Result {
var $num_rows, $_rows = array(), $_offset = 0;
public $num_rows;
private $rows = array(), $offset = 0;
function __construct($result) {
foreach ($result as $item) {
@@ -64,8 +66,8 @@ if (isset($_GET["simpledb"])) {
$row['itemName()'] = (string) $item->Name;
}
foreach ($item->Attribute as $attribute) {
$name = $this->_processValue($attribute->Name);
$value = $this->_processValue($attribute->Value);
$name = $this->processValue($attribute->Name);
$value = $this->processValue($attribute->Value);
if (isset($row[$name])) {
$row[$name] = (array) $row[$name];
$row[$name][] = $value;
@@ -73,30 +75,30 @@ if (isset($_GET["simpledb"])) {
$row[$name] = $value;
}
}
$this->_rows[] = $row;
$this->rows[] = $row;
foreach ($row as $key => $val) {
if (!isset($this->_rows[0][$key])) {
$this->_rows[0][$key] = null;
if (!isset($this->rows[0][$key])) {
$this->rows[0][$key] = null;
}
}
}
$this->num_rows = count($this->_rows);
$this->num_rows = count($this->rows);
}
function _processValue($element) {
private function processValue($element) {
return (is_object($element) && $element['encoding'] == 'base64' ? base64_decode($element) : (string) $element);
}
function fetch_assoc() {
$row = current($this->_rows);
$row = current($this->rows);
if (!$row) {
return $row;
}
$return = array();
foreach ($this->_rows[0] as $key => $val) {
foreach ($this->rows[0] as $key => $val) {
$return[$key] = $row[$key];
}
next($this->_rows);
next($this->rows);
return $return;
}
@@ -109,8 +111,8 @@ if (isset($_GET["simpledb"])) {
}
function fetch_field() {
$keys = array_keys($this->_rows[0]);
return (object) array('name' => $keys[$this->_offset++]);
$keys = array_keys($this->rows[0]);
return (object) array('name' => $keys[$this->offset++]);
}
}
}
@@ -121,12 +123,12 @@ if (isset($_GET["simpledb"])) {
static $possibleDrivers = array("SimpleXML + allow_url_fopen");
static $jush = "simpledb";
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "IS NOT NULL");
var $grouping = array("count");
public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "IS NOT NULL");
public $grouping = array("count");
public $primary = "itemName()";
function _chunkRequest($ids, $action, $params, $expand = array()) {
private function chunkRequest($ids, $action, $params, $expand = array()) {
$connection = connection();
foreach (array_chunk($ids, 25) as $chunk) {
$params2 = $params;
@@ -144,7 +146,7 @@ if (isset($_GET["simpledb"])) {
return true;
}
function _extractIds($table, $queryWhere, $limit) {
private function extractIds($table, $queryWhere, $limit) {
$return = array();
if (preg_match_all("~itemName\(\) = (('[^']*+')+)~", $queryWhere, $matches)) {
$return = array_map('Adminer\idf_unescape', $matches[1]);
@@ -165,8 +167,8 @@ if (isset($_GET["simpledb"])) {
}
function delete($table, $queryWhere, $limit = 0) {
return $this->_chunkRequest(
$this->_extractIds($table, $queryWhere, $limit),
return $this->chunkRequest(
$this->extractIds($table, $queryWhere, $limit),
'BatchDeleteAttributes',
array('DomainName' => $table)
);
@@ -176,7 +178,7 @@ if (isset($_GET["simpledb"])) {
$delete = array();
$insert = array();
$i = 0;
$ids = $this->_extractIds($table, $queryWhere, $limit);
$ids = $this->extractIds($table, $queryWhere, $limit);
$id = idf_unescape($set["`itemName()`"]);
unset($set["`itemName()`"]);
foreach ($set as $key => $val) {
@@ -196,8 +198,8 @@ if (isset($_GET["simpledb"])) {
}
}
$params = array('DomainName' => $table);
return (!$insert || $this->_chunkRequest(($id != "" ? array($id) : $ids), 'BatchPutAttributes', $params, $insert))
&& (!$delete || $this->_chunkRequest($ids, 'BatchDeleteAttributes', $params, $delete))
return (!$insert || $this->chunkRequest(($id != "" ? array($id) : $ids), 'BatchPutAttributes', $params, $insert))
&& (!$delete || $this->chunkRequest($ids, 'BatchDeleteAttributes', $params, $delete))
;
}
@@ -244,7 +246,7 @@ if (isset($_GET["simpledb"])) {
}
function slowQuery($query, $timeout) {
$this->_conn->timeout = $timeout;
$this->conn->timeout = $timeout;
return $query;
}
}
@@ -420,7 +422,7 @@ if (isset($_GET["simpledb"])) {
'max_redirects' => 0,
))));
if (!$file) {
$this->error = lang('Invalid credentials.');
$connection->error = lang('Invalid credentials.');
return false;
}
libxml_use_internal_errors(true);

View File

@@ -14,7 +14,7 @@ class AdminerDumpAlter {
}
}
function _database() {
private function database() {
// drop old tables
$query = "SELECT TABLE_NAME, ENGINE, TABLE_COLLATION, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()";
echo "DELIMITER ;;
@@ -59,9 +59,8 @@ SELECT @adminer_alter;
if ($first) {
$first = false;
echo "SET @adminer_alter = '';\n\n";
register_shutdown_function(array($this, '_database'));
} else {
$this->_database();
$this->database();
}
return true;
}
@@ -75,7 +74,10 @@ SELECT @adminer_alter;
} else {
echo substr_replace($create, " IF NOT EXISTS", 12, 0) . ";\n\n";
// create procedure which iterates over original columns and adds new and removes old
$query = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, COLLATION_NAME, COLUMN_TYPE, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . Adminer\q($table) . " ORDER BY ORDINAL_POSITION";
$query = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, COLLATION_NAME, COLUMN_TYPE, EXTRA, COLUMN_COMMENT
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . Adminer\q($table) . "
ORDER BY ORDINAL_POSITION";
echo "DELIMITER ;;
CREATE PROCEDURE adminer_alter (INOUT alter_command text) BEGIN
DECLARE _column_name, _collation_name, after varchar(64) DEFAULT '';
@@ -159,4 +161,10 @@ DROP PROCEDURE adminer_alter;
return true;
}
}
function dumpFooter() {
if ($_POST["format"] == "sql_alter") {
$this->database();
}
}
}

View File

@@ -8,8 +8,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/
class AdminerDumpBz2 {
/** @access protected */
var $filename, $fp;
protected $filename, $fp;
function dumpOutput() {
if (!function_exists('bzopen')) {

View File

@@ -9,7 +9,6 @@
class AdminerDumpDate {
function dumpFilename($identifier) {
$connection = Adminer\connection();
return Adminer\friendly_url(($identifier != "" ? $identifier : (Adminer\SERVER != "" ? Adminer\SERVER : "localhost")) . "-" . $connection->result("SELECT NOW()"));
return Adminer\friendly_url(($identifier != "" ? $identifier : (Adminer\SERVER != "" ? Adminer\SERVER : "localhost")) . "-" . Adminer\get_val("SELECT NOW()"));
}
}

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/
class AdminerDumpJson {
/** @access protected */
var $database = false;
protected $database = false;
function dumpFormat() {
return array('json' => 'JSON');
@@ -20,10 +19,6 @@ class AdminerDumpJson {
}
}
function _database() {
echo "}\n";
}
function dumpData($table, $style, $query) {
if ($_POST["format"] == "json") {
if ($this->database) {
@@ -31,7 +26,6 @@ class AdminerDumpJson {
} else {
$this->database = true;
echo "{\n";
register_shutdown_function(array($this, '_database'));
}
$connection = Adminer\connection();
$result = $connection->query($query, 1);
@@ -58,4 +52,10 @@ class AdminerDumpJson {
return "json";
}
}
function dumpFooter() {
if ($_POST["format"] == "json" && $this->database) {
echo "}\n";
}
}
}

View File

@@ -6,8 +6,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/
class AdminerDumpPhp {
var $output = array();
var $shutdown_callback = false;
protected $output = array();
function dumpFormat() {
return array('php' => 'PHP');
@@ -23,10 +22,6 @@ class AdminerDumpPhp {
function dumpTable($table, $style, $is_view = 0) {
if ($_POST['format'] == 'php') {
$this->output[$table] = array();
if (!$this->shutdown_callback) {
$this->shutdown_callback = true;
register_shutdown_function(array($this, '_export'));
}
return true;
}
}
@@ -44,8 +39,11 @@ class AdminerDumpPhp {
}
}
function _export() {
echo "<?php\n";
var_export($this->output);
function dumpFooter() {
if ($_POST['format'] == 'php') {
echo "<?php\n";
var_export($this->output);
echo ";\n";
}
}
}

View File

@@ -7,8 +7,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/
class AdminerDumpXml {
/** @access protected */
var $database = false;
protected $database = false;
function dumpFormat() {
return array('xml' => 'XML');
@@ -20,16 +19,11 @@ class AdminerDumpXml {
}
}
function _database() {
echo "</database>\n";
}
function dumpData($table, $style, $query) {
if ($_POST["format"] == "xml") {
if (!$this->database) {
$this->database = true;
echo "<database name='" . Adminer\h(Adminer\DB) . "'>\n";
register_shutdown_function(array($this, '_database'));
}
$connection = Adminer\connection();
$result = $connection->query($query, 1);
@@ -52,4 +46,10 @@ class AdminerDumpXml {
return "xml";
}
}
function dumpFooter() {
if ($_POST["format"] == "xml" && $this->database) {
echo "</database>\n";
}
}
}

View File

@@ -8,8 +8,7 @@
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/
class AdminerDumpZip {
/** @access protected */
var $filename, $data;
protected $filename, $data;
function dumpOutput() {
if (!class_exists('ZipArchive')) {

Some files were not shown because too many files have changed in this diff Show More