mirror of
https://github.com/vrana/adminer.git
synced 2025-08-30 01:30:12 +02:00
Compare commits
337 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
99a0949d2a | ||
|
1cf5a91d98 | ||
|
dcde78eef2 | ||
|
88821a5780 | ||
|
078a8b3d6b | ||
|
4df205d4ec | ||
|
a50395c275 | ||
|
8b93d51c68 | ||
|
50cdbbe415 | ||
|
f5d23a8cad | ||
|
3bc675b0fc | ||
|
b86a9cb5fb | ||
|
cd53c54b6a | ||
|
99163feefb | ||
|
84e4971b1e | ||
|
d22b1091f1 | ||
|
b349830758 | ||
|
b8eb0ad8f5 | ||
|
c47590bb0d | ||
|
486f164247 | ||
|
edce93ca80 | ||
|
858c914a50 | ||
|
9fd9a1fc8d | ||
|
60555c5736 | ||
|
8cec1bd611 | ||
|
9b84908b99 | ||
|
3dd1b41472 | ||
|
b89f628e40 | ||
|
708646156a | ||
|
9e52f0fa2e | ||
|
3cd50c9a02 | ||
|
f5ecb18896 | ||
|
0501846743 | ||
|
8db8b7a10d | ||
|
d6a417fa58 | ||
|
4477f95426 | ||
|
6a64c7771b | ||
|
c32e4f82fe | ||
|
19bb320e7a | ||
|
fb47ba6bbb | ||
|
03ff0bbc04 | ||
|
e8055329a6 | ||
|
9142e7e8a5 | ||
|
e975e546e1 | ||
|
1b59b10f62 | ||
|
f1a8bd9ef8 | ||
|
204176b33b | ||
|
cf436d7317 | ||
|
7eb92d9601 | ||
|
8da9239279 | ||
|
e0dde9034f | ||
|
9b162e8291 | ||
|
359fdf3d07 | ||
|
00b7056147 | ||
|
db829fd463 | ||
|
359d153130 | ||
|
ab44927442 | ||
|
01a6af8b70 | ||
|
3f2eec9b92 | ||
|
aaca1eee8e | ||
|
26db8596aa | ||
|
5aedb33fb6 | ||
|
7fca87dfd7 | ||
|
711f41d05b | ||
|
f7b20b5f6f | ||
|
719c1e7067 | ||
|
83a8b18c85 | ||
|
4d082d4fcd | ||
|
a705be7a94 | ||
|
a2586e7265 | ||
|
f38bbff5bf | ||
|
09720b31f1 | ||
|
0e28daac55 | ||
|
3eb478b65a | ||
|
192ce41bd3 | ||
|
bcd5164e2f | ||
|
cd686c7a1e | ||
|
e9feb1587a | ||
|
1f5a7fa717 | ||
|
3c310ddfaf | ||
|
6d4896e03c | ||
|
5ef77ec399 | ||
|
62c18efbd5 | ||
|
101229043e | ||
|
0e21106e48 | ||
|
f16a6d415a | ||
|
11699223df | ||
|
7c75d3f86c | ||
|
287667d631 | ||
|
ef4c340cc2 | ||
|
f2a5d5127a | ||
|
889ffe28c7 | ||
|
5f6aa1e267 | ||
|
def9e07831 | ||
|
c73bd1233e | ||
|
e6ead2d12c | ||
|
4802389ce6 | ||
|
7845b70d7d | ||
|
9f8344e53c | ||
|
2dd32cf534 | ||
|
0b063262ee | ||
|
458d07122f | ||
|
740a4b8b1c | ||
|
6be1e1c069 | ||
|
b861500910 | ||
|
eca176f362 | ||
|
8f489da2bd | ||
|
3138b1de88 | ||
|
e723158bbf | ||
|
feed6e4488 | ||
|
9b345fbafb | ||
|
ca30d04575 | ||
|
b4e41f5e4b | ||
|
8979baca28 | ||
|
8019b9ae4d | ||
|
7fec2992d9 | ||
|
df98f2453d | ||
|
eb1d8d5468 | ||
|
ea3da56b6d | ||
|
41dabfb4f2 | ||
|
ff0fe92c00 | ||
|
06c15aa263 | ||
|
8a64fb16cd | ||
|
bda53f0734 | ||
|
bc9de24d77 | ||
|
9cfea02e19 | ||
|
eeb78d7e48 | ||
|
751405e006 | ||
|
3fb6cac361 | ||
|
8613f97948 | ||
|
249807fc48 | ||
|
6e76454f59 | ||
|
655cca0872 | ||
|
16989a736c | ||
|
a3d1ab34bb | ||
|
b2f904c64f | ||
|
05d27a132d | ||
|
4861c88cc6 | ||
|
1424a42b1f | ||
|
1c5a192cb5 | ||
|
336fdaf09c | ||
|
57e6c2651c | ||
|
693dc5b8a7 | ||
|
753642630b | ||
|
8fed1523ec | ||
|
ebb31bdac8 | ||
|
5069e5a400 | ||
|
33b69ed82b | ||
|
4e4f280061 | ||
|
841f76fb00 | ||
|
73e7e00c77 | ||
|
29f954069d | ||
|
c1eccc9cdd | ||
|
430cdaeb3a | ||
|
e395fe583a | ||
|
19313a8dab | ||
|
17c0960e7f | ||
|
a9b020452e | ||
|
e1f0fded69 | ||
|
91f9980267 | ||
|
5f3fac4b48 | ||
|
b7679701ce | ||
|
b7258d2e95 | ||
|
c51d9919fe | ||
|
78c431ab20 | ||
|
916889bb8e | ||
|
e8b15c99f4 | ||
|
a460019535 | ||
|
ea5a7453fb | ||
|
587f6a5375 | ||
|
2bb74e7467 | ||
|
a684044bb3 | ||
|
36a3465a64 | ||
|
223aee70d5 | ||
|
c02a7d6abe | ||
|
22a3efe4ed | ||
|
dd47df9b9c | ||
|
0b0e8940e0 | ||
|
fa8339c8c2 | ||
|
f0ee812b29 | ||
|
f093cb6db2 | ||
|
68d4a5a650 | ||
|
6576fa6a73 | ||
|
28535bf384 | ||
|
43e3fe375d | ||
|
d8a9a3db8d | ||
|
777d5dca0e | ||
|
6d71cd678e | ||
|
30714d98f9 | ||
|
8353bd48de | ||
|
0762c761ac | ||
|
529197f403 | ||
|
d20cbf14e7 | ||
|
517f63835d | ||
|
4fee062b73 | ||
|
26769b2357 | ||
|
42bf7b9ca0 | ||
|
d8755c903d | ||
|
a391fcb6c4 | ||
|
c99ca863ce | ||
|
e0283543f3 | ||
|
a72e053520 | ||
|
de654712d5 | ||
|
9c1d5484a2 | ||
|
1fd8aa885b | ||
|
08882c6a8e | ||
|
fd199ec156 | ||
|
e3515fd63f | ||
|
be0a485b14 | ||
|
94c04712d6 | ||
|
caea0b7f68 | ||
|
134301b3ff | ||
|
d14f3dd2d8 | ||
|
67c313c86d | ||
|
5eaa73583a | ||
|
68b6af6fce | ||
|
e65fdba5d1 | ||
|
8f336cd0b3 | ||
|
5f3bfe8451 | ||
|
1a3d58e74e | ||
|
af9a851c5e | ||
|
3a40a855ea | ||
|
967647759e | ||
|
e4323ced55 | ||
|
85c6af6f87 | ||
|
9226804aa2 | ||
|
041e7064ca | ||
|
4c2a8b0050 | ||
|
9afbf1a465 | ||
|
352ef9c778 | ||
|
45107dc46e | ||
|
21f3426adb | ||
|
95dccfe9fb | ||
|
fe88f83c95 | ||
|
078957fe32 | ||
|
61f07867f9 | ||
|
0135dd5b81 | ||
|
773a2253d3 | ||
|
272042a30e | ||
|
48308f3357 | ||
|
c90033a962 | ||
|
8bd022f974 | ||
|
b1550b052d | ||
|
9862846a7c | ||
|
f14e3e38f6 | ||
|
95262c4215 | ||
|
dacfdc4608 | ||
|
7636c253fb | ||
|
44d26a9dd3 | ||
|
b229e7b583 | ||
|
8e91417be1 | ||
|
db7202fcf0 | ||
|
260487fbc2 | ||
|
3ae964c915 | ||
|
d56c8cbaae | ||
|
d347f88c54 | ||
|
b9b4db0c8e | ||
|
818b9ad903 | ||
|
4a6436773f | ||
|
81594e4a2d | ||
|
f0bdb0e6ca | ||
|
b9e4806d3c | ||
|
7e708dae57 | ||
|
a0fe44ec18 | ||
|
eb0f280776 | ||
|
3b1189cd3c | ||
|
434a8f7705 | ||
|
f9478c67d2 | ||
|
f2ce6c0a71 | ||
|
a50b3d6385 | ||
|
e39deca4f1 | ||
|
ce69970f54 | ||
|
51ac1312a1 | ||
|
4505544953 | ||
|
fa75213ff6 | ||
|
63acb37ea6 | ||
|
3ad6c16f59 | ||
|
22d08b4a50 | ||
|
dd3cc4e683 | ||
|
5504a617d0 | ||
|
2fdebfda29 | ||
|
dc2e945aef | ||
|
43d86287c4 | ||
|
a94a727af7 | ||
|
c2d29a6937 | ||
|
c082136558 | ||
|
7b1ea5fa2c | ||
|
156839142e | ||
|
2ee4e3b2e1 | ||
|
8b4c8b0156 | ||
|
9702878297 | ||
|
4a54648995 | ||
|
2e5027a1aa | ||
|
5a4c4dd892 | ||
|
7ef009336f | ||
|
1defc94d12 | ||
|
5d3376e620 | ||
|
d410cdc5be | ||
|
a44e625882 | ||
|
ae57d42105 | ||
|
199edfe11f | ||
|
b02c3e1f7f | ||
|
98cb9b9aca | ||
|
514d64048d | ||
|
1e963cf90f | ||
|
0c15a9f42d | ||
|
c454ea8430 | ||
|
607febea8e | ||
|
ebd5f19dd4 | ||
|
1b0984ff31 | ||
|
b017928256 | ||
|
526077535e | ||
|
8274b2e0e8 | ||
|
8f7d456887 | ||
|
91b735c576 | ||
|
916b9e62de | ||
|
f25c65837f | ||
|
b0182834bf | ||
|
6bf0b85919 | ||
|
37e63dd82f | ||
|
6fdde32f86 | ||
|
aeac0a3329 | ||
|
fde7d7dde2 | ||
|
e993462412 | ||
|
31f8f61d0e | ||
|
e589ee3fde | ||
|
35274f18bb | ||
|
f8b2640156 | ||
|
bb23546478 | ||
|
dddfc190a5 | ||
|
40760d153c | ||
|
4fe3d17255 | ||
|
6dcc5081e1 | ||
|
df6fe6b108 | ||
|
e6339046ff | ||
|
2c0cfbdd3f | ||
|
f13770c664 |
15
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
15
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
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.
|
||||
Also please include a screenshot._
|
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,4 +1,10 @@
|
||||
/adminer/adminer.css
|
||||
/adminer/adminer-dark.css
|
||||
/editor/adminer.css
|
||||
/editor/adminer-dark.css
|
||||
/adminer*.php
|
||||
/editor*.php
|
||||
/tests/pdo-*.html
|
||||
/vendor/
|
||||
adminer-plugins/
|
||||
adminer-plugins.php
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -4,3 +4,6 @@
|
||||
[submodule "JsShrink"]
|
||||
path = externals/JsShrink
|
||||
url = https://github.com/vrana/JsShrink
|
||||
[submodule "PhpShrink"]
|
||||
path = externals/PhpShrink
|
||||
url = https://github.com/vrana/PhpShrink
|
||||
|
1158
CHANGELOG.md
Normal file
1158
CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
3
CONTRIBUTING.md
Normal file
3
CONTRIBUTING.md
Normal file
@@ -0,0 +1,3 @@
|
||||
- Reproducible [bug reports](https://github.com/vrana/adminer/issues/new?template=bug_report.md) are warmly welcomed.
|
||||
- [Feature requests](https://github.com/vrana/adminer/issues/new?template=BLANK_ISSUE) are also fine, but I'm quite picky about what to accept into Adminer. Please don't be offended if I close the issue as "Not Planned," especially if it can be achieved with a plugin.
|
||||
- [Pull requests](https://github.com/vrana/adminer/pulls) for both bug fixes and simple features are welcome. Before working on anything more complicated, get familiar with the [Adminer philosophy](https://github.com/vrana/adminer/blob/master/developing.md).
|
50
README.md
Normal file
50
README.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Adminer
|
||||
**Adminer** is a full-featured database management tool written in PHP. It consists of a single file ready to deploy to the target server.
|
||||
**Adminer Editor** offers data manipulation for end-users.
|
||||
|
||||
[Official Website](https://www.adminer.org/)
|
||||
|
||||
## Features
|
||||
- **Supports:** MySQL, MariaDB, PostgreSQL, CockroachDB, SQLite, MS SQL, Oracle
|
||||
- **Plugins for:** Elasticsearch, SimpleDB, MongoDB, Firebird, ClickHouse, IMAP
|
||||
- **Requirements:** PHP 5.3+
|
||||
|
||||
## Screenshot
|
||||

|
||||
|
||||
## Installation
|
||||
If downloaded from Git then run: `git submodule update --init`
|
||||
|
||||
- `adminer/index.php` - Run development version of Adminer
|
||||
- `editor/index.php` - Run development version of Adminer Editor
|
||||
- `editor/example.php` - Example customization
|
||||
- `adminer/sqlite.php` - Development version of Adminer with SQLite allowed
|
||||
- `editor/sqlite.php` - Development version of Editor with SQLite allowed
|
||||
- `adminer/designs.php` - Development version of Adminer with `adminer.css` switcher
|
||||
- `compile.php` - Create a single file version
|
||||
- `lang.php` - Update translations
|
||||
- `tests/*.html` - Katalon Recorder test suites
|
||||
|
||||
## Plugins
|
||||
There are [several plugins](/plugins/) distributed with Adminer, as well as many user-contributed plugins linked on the [Adminer Plugins page](https://www.adminer.org/plugins/).
|
||||
To use a plugin, simply upload it to the `adminer-plugins/` directory next to `adminer.php`. You can also upload plugins for drivers (e.g., `elastic.php`) in this directory.
|
||||
|
||||
```
|
||||
- adminer.php
|
||||
- adminer-plugins/
|
||||
- dump-xml.php
|
||||
- login-password-less.php
|
||||
- elastic.php
|
||||
- ...
|
||||
- adminer-plugins.php
|
||||
```
|
||||
|
||||
Some plugins require configuration. To use them, create a file named `adminer-plugins.php`. You can also specify the loading order in this file.
|
||||
|
||||
```php
|
||||
<?php // adminer-plugins.php
|
||||
return array(
|
||||
new AdminerLoginPasswordLess('$2y$07$Czp9G/aLi3AnaUqpvkF05OHO1LMizrAgMLvnaOdvQovHaRv28XDhG'),
|
||||
// You can specify all plugins here or just the ones needing configuration.
|
||||
);
|
||||
```
|
@@ -2,10 +2,10 @@
|
||||
|
||||
## Supported Versions
|
||||
|
||||
I support only the last published version and the last development version (last commit).
|
||||
Only the latest published version and the latest development version (last commit) are supported.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
To report a vulnerability, add a new draft security advisory at https://github.com/vrana/adminer/security/advisories/new.
|
||||
To report a vulnerability, create a new draft security advisory at [GitHub Security Advisories](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.
|
||||
Security issues are handled with top priority. If you don't receive a response within a week, please follow up on the report. Once a vulnerability is acknowledged, a fix should be available and a new version released within a few days. The issue will be made public after the fix is released or if the report is declined.
|
||||
|
@@ -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
|
||||
@@ -88,7 +85,7 @@ if ($in) {
|
||||
?>
|
||||
<p>
|
||||
<input type="submit" value="<?php echo lang('Call'); ?>">
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
<?php echo input_token(); ?>
|
||||
</form>
|
||||
|
||||
<pre>
|
||||
|
@@ -47,5 +47,5 @@ echo doc_link(array(
|
||||
<?php if ($name != "") { ?>
|
||||
<input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $name)); ?>
|
||||
<?php } ?>
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
<?php echo input_token(); ?>
|
||||
</form>
|
||||
|
@@ -30,7 +30,7 @@ if ($row["auto_increment_col"]) {
|
||||
}
|
||||
|
||||
if ($_POST) {
|
||||
set_adminer_settings(array("comments" => $_POST["comments"], "defaults" => $_POST["defaults"]));
|
||||
save_settings(array("comments" => $_POST["comments"], "defaults" => $_POST["defaults"]));
|
||||
}
|
||||
|
||||
if ($_POST && !process_fields($row["fields"]) && !$error) {
|
||||
@@ -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) {
|
||||
@@ -168,7 +168,7 @@ if (!$_POST) {
|
||||
}
|
||||
|
||||
$collations = collations();
|
||||
$engines = engines();
|
||||
$engines = $driver->engines();
|
||||
// case of engine may differ
|
||||
foreach ($engines as $engine) {
|
||||
if (!strcasecmp($engine, $row["Engine"])) {
|
||||
@@ -180,27 +180,27 @@ foreach ($engines as $engine) {
|
||||
|
||||
<form action="" method="post" id="form">
|
||||
<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 ? html_select("Engine", array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . 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"]) : ""); ?>
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
<?php } ?>
|
||||
<?php
|
||||
if (support("columns") || $TABLE == "") {
|
||||
echo lang('Table name') . ": <input name='name'" . ($TABLE == "" && !$_POST ? " autofocus" : "") . " data-maxlength='64' value='" . h($row["name"]) . "' autocapitalize='off'>\n";
|
||||
echo ($engines ? html_select("Engine", array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . on_help("event.target.value", 1) . script("qsl('select').onchange = helpClose;") . "\n" : "");
|
||||
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') . ")'>");
|
||||
}
|
||||
echo "<input type='submit' value='" . lang('Save') . "'>\n";
|
||||
}
|
||||
|
||||
<?php if (support("columns")) { ?>
|
||||
<div class="scrollable">
|
||||
<table id="edit-fields" class="nowrap">
|
||||
<?php
|
||||
if (support("columns")) {
|
||||
echo "<div class='scrollable'>\n";
|
||||
echo "<table id='edit-fields' class='nowrap'>\n";
|
||||
edit_fields($row["fields"], $collations, "TABLE", $foreign_keys);
|
||||
?>
|
||||
</table>
|
||||
<?php echo script("editFields();"); ?>
|
||||
</div>
|
||||
<p>
|
||||
<?php echo lang('Auto Increment'); ?>: <input type="number" name="Auto_increment" class="size" value="<?php echo h($row["Auto_increment"]); ?>">
|
||||
<?php echo checkbox("defaults", 1, ($_POST ? $_POST["defaults"] : adminer_setting("defaults")), lang('Default values'), "columnShow(this.checked, 5)", "jsonly"); ?>
|
||||
<?php
|
||||
$comments = ($_POST ? $_POST["comments"] : adminer_setting("comments"));
|
||||
echo "</table>\n";
|
||||
echo script("editFields();");
|
||||
echo "</div>\n<p>\n";
|
||||
echo lang('Auto Increment') . ": <input type='number' name='Auto_increment' class='size' value='" . h($row["Auto_increment"]) . "'>\n";
|
||||
echo checkbox("defaults", 1, ($_POST ? $_POST["defaults"] : get_setting("defaults")), lang('Default values'), "columnShow(this.checked, 5)", "jsonly");
|
||||
$comments = ($_POST ? $_POST["comments"] : get_setting("comments"));
|
||||
echo (support("comment")
|
||||
? checkbox("comments", 1, $comments, lang('Comment'), "editingCommentsClick(this, true);", "jsonly")
|
||||
. ' ' . (preg_match('~\n~', $row["Comment"])
|
||||
@@ -221,25 +221,19 @@ foreach ($engines as $engine) {
|
||||
if (support("partitioning")) {
|
||||
$partition_table = preg_match('~RANGE|LIST~', $row["partition_by"]);
|
||||
print_fieldset("partition", lang('Partition by'), $row["partition_by"]);
|
||||
?>
|
||||
<p>
|
||||
<?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'"); ?>>
|
||||
<thead><tr><th><?php echo lang('Partition name'); ?><th><?php echo lang('Values'); ?></thead>
|
||||
<?php
|
||||
echo "<p>" . html_select("partition_by", array("" => "") + $partition_by, $row["partition_by"]) . on_help("event.target.value.replace(/./, 'PARTITION BY \$&')", 1) . script("qsl('select').onchange = partitionByChange;");
|
||||
echo "(<input name='partition' value='" . h($row["partition"]) . "'>)\n";
|
||||
echo lang('Partitions') . ": <input type='number' name='partitions' class='size" . ($partition_table || !$row["partition_by"] ? " hidden" : "") . "' value='" . h($row["partitions"]) . "'>\n";
|
||||
echo "<table id='partition-table'" . ($partition_table ? "" : " class='hidden'") . ">\n";
|
||||
echo "<thead><tr><th>" . lang('Partition name') . "<th>" . lang('Values') . "</thead>\n";
|
||||
foreach ($row["partition_names"] as $key => $val) {
|
||||
echo '<tr>';
|
||||
echo '<td><input name="partition_names[]" value="' . h($val) . '" autocapitalize="off">';
|
||||
echo ($key == count($row["partition_names"]) - 1 ? script("qsl('input').oninput = partitionNameChange;") : '');
|
||||
echo '<td><input name="partition_values[]" value="' . h($row["partition_values"][$key]) . '">';
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
</div></fieldset>
|
||||
<?php
|
||||
echo "</table>\n</div></fieldset>\n";
|
||||
}
|
||||
echo input_token();
|
||||
?>
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
</form>
|
||||
|
@@ -76,6 +76,6 @@ if (DB != "") {
|
||||
} elseif (!$_POST["add_x"] && $_GET["db"] == "") {
|
||||
echo "<input type='image' class='icon' name='add' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>\n";
|
||||
}
|
||||
echo input_token();
|
||||
?>
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
</form>
|
||||
|
@@ -157,7 +157,7 @@ if ($adminer->homepage()) {
|
||||
}
|
||||
echo "<input type='hidden' name='all' value=''>"; // used by trCheck()
|
||||
echo script("qsl('input').onclick = function () { selectCount('selected', formChecked(this, /^(tables|views)\[/));" . (support("table") ? " selectCount('selected2', formChecked(this, /^tables\[/) || $tables);" : "") . " }");
|
||||
echo "<input type='hidden' name='token' value='$token'>\n";
|
||||
echo input_token();
|
||||
echo "</div></fieldset>\n";
|
||||
echo "</div></div>\n";
|
||||
}
|
||||
@@ -165,8 +165,8 @@ if ($adminer->homepage()) {
|
||||
echo script("tableCheck();");
|
||||
}
|
||||
|
||||
echo '<p class="links"><a href="' . h(ME) . 'create=">' . lang('Create table') . "</a>\n";
|
||||
echo (support("view") ? '<a href="' . h(ME) . 'view=">' . lang('Create view') . "</a>\n" : "");
|
||||
echo "<p class='links'><a href='" . h(ME) . "create='>" . lang('Create table') . "</a>\n";
|
||||
echo (support("view") ? "<a href='" . h(ME) . "view='>" . lang('Create view') . "</a>\n" : "");
|
||||
|
||||
if (support("routine")) {
|
||||
echo "<h3 id='routines'>" . lang('Routines') . "</h3>\n";
|
||||
|
@@ -3,8 +3,13 @@ function adminer_object() {
|
||||
include_once "../plugins/plugin.php";
|
||||
include_once "../plugins/designs.php";
|
||||
$designs = array();
|
||||
foreach (glob("../designs/*", GLOB_ONLYDIR) as $filename) {
|
||||
$designs["$filename/adminer.css"] = basename($filename);
|
||||
foreach (glob("../designs/*", GLOB_ONLYDIR) as $dirname) {
|
||||
foreach (array("", "-dark") as $mode) {
|
||||
$filename = "$dirname/adminer$mode.css";
|
||||
if (file_exists($filename)) {
|
||||
$designs[$filename] = basename($dirname);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new AdminerPlugin(array(
|
||||
new AdminerDesigns($designs),
|
||||
|
@@ -11,11 +11,12 @@ $drivers["mssql"] = "MS SQL";
|
||||
|
||||
if (isset($_GET["mssql"])) {
|
||||
define('Adminer\DRIVER', "mssql");
|
||||
if (extension_loaded("sqlsrv")) {
|
||||
if (extension_loaded("sqlsrv") && $_GET["ext"] != "pdo") {
|
||||
class Db {
|
||||
var $extension = "sqlsrv", $_link, $_result, $server_info, $affected_rows, $errno, $error;
|
||||
public $extension = "sqlsrv", $flavor = '', $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,62 +126,85 @@ 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"];
|
||||
$return->type = ($field["Type"] == 1 ? 254 : 0);
|
||||
$return->type = ($field["Type"] == 1 ? 254 : 15);
|
||||
$return->charsetnr = 0;
|
||||
return $return;
|
||||
}
|
||||
|
||||
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";
|
||||
function last_id($result) {
|
||||
return get_val("SELECT SCOPE_IDENTITY()"); // @@IDENTITY can return trigger INSERT
|
||||
}
|
||||
|
||||
function connect($server, $username, $password) {
|
||||
$this->dsn("sqlsrv:Server=" . str_replace(":", ",", $server), $username, $password);
|
||||
return true;
|
||||
}
|
||||
function explain($connection, $query) {
|
||||
$connection->query("SET SHOWPLAN_ALL ON");
|
||||
$return = $connection->query($query);
|
||||
$connection->query("SET SHOWPLAN_ALL OFF"); // connection is used also for indexes
|
||||
return $return;
|
||||
}
|
||||
|
||||
} else {
|
||||
class MssqlDb extends PdoDb {
|
||||
function select_db($database) {
|
||||
// database selection is separated from the connection so dbname in DSN can't be used
|
||||
return $this->query(use_sql($database));
|
||||
}
|
||||
|
||||
function lastInsertId() {
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
}
|
||||
|
||||
} elseif (extension_loaded("pdo_dblib")) {
|
||||
class Db extends PdoDb {
|
||||
var $extension = "PDO_DBLIB";
|
||||
function last_id($result) {
|
||||
global $connection;
|
||||
return $connection->lastInsertId();
|
||||
}
|
||||
|
||||
function connect($server, $username, $password) {
|
||||
$this->dsn("dblib:charset=utf8;host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\d)~', ';port=\1', $server)), $username, $password);
|
||||
return true;
|
||||
function explain($connection, $query) {
|
||||
}
|
||||
|
||||
if (extension_loaded("pdo_sqlsrv")) {
|
||||
class Db extends MssqlDb {
|
||||
public $extension = "PDO_SQLSRV";
|
||||
|
||||
function connect($server, $username, $password) {
|
||||
$this->dsn("sqlsrv:Server=" . str_replace(":", ",", $server), $username, $password);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function select_db($database) {
|
||||
return $this->query(use_sql($database));
|
||||
} elseif (extension_loaded("pdo_dblib")) {
|
||||
class Db extends MssqlDb {
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,7 +214,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 +223,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);
|
||||
@@ -307,10 +332,6 @@ if (isset($_GET["mssql"])) {
|
||||
return get_val("SELECT collation_name FROM sys.databases WHERE name = " . q($db));
|
||||
}
|
||||
|
||||
function engines() {
|
||||
return array();
|
||||
}
|
||||
|
||||
function logged_user() {
|
||||
return get_val("SELECT SUSER_NAME()");
|
||||
}
|
||||
@@ -357,7 +378,7 @@ WHERE schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND type IN ('S', 'U', 'V')
|
||||
$return = array();
|
||||
$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
|
||||
get_rows("SELECT c.max_length, c.precision, c.scale, c.name, c.is_nullable, c.is_identity, c.collation_name, t.name type, d.definition [default], d.name default_constraint, i.is_primary_key
|
||||
FROM sys.all_columns c
|
||||
JOIN sys.types t ON c.user_type_id = t.user_type_id
|
||||
LEFT JOIN sys.default_constraints d ON c.default_object_id = d.object_id
|
||||
@@ -507,7 +528,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;
|
||||
}
|
||||
@@ -536,17 +566,6 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
|
||||
;
|
||||
}
|
||||
|
||||
function last_id() {
|
||||
return get_val("SELECT SCOPE_IDENTITY()"); // @@IDENTITY can return trigger INSERT
|
||||
}
|
||||
|
||||
function explain($connection, $query) {
|
||||
$connection->query("SET SHOWPLAN_ALL ON");
|
||||
$return = $connection->query($query);
|
||||
$connection->query("SET SHOWPLAN_ALL OFF"); // connection is used also for indexes
|
||||
return $return;
|
||||
}
|
||||
|
||||
function found_rows($table_status, $where) {
|
||||
}
|
||||
|
||||
|
@@ -1,19 +1,20 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
$drivers = array("server" => "MySQL") + $drivers;
|
||||
$drivers = array("server" => "MySQL / MariaDB") + $drivers;
|
||||
|
||||
if (!defined('Adminer\DRIVER')) {
|
||||
define('Adminer\DRIVER', "server"); // server - backwards compatibility
|
||||
// MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable
|
||||
if (extension_loaded("mysqli")) {
|
||||
if (extension_loaded("mysqli") && $_GET["ext"] != "pdo") {
|
||||
class Db extends \MySQLi {
|
||||
var $extension = "MySQLi";
|
||||
public $extension = "MySQLi", $flavor = '';
|
||||
|
||||
function __construct() {
|
||||
parent::init();
|
||||
}
|
||||
|
||||
/** @see https://php.net/mysqli.construct */
|
||||
function connect($server = "", $username = "", $password = "", $database = null, $port = null, $socket = null) {
|
||||
global $adminer;
|
||||
mysqli_report(MYSQLI_REPORT_OFF); // stays between requests, not required since PHP 5.3.4
|
||||
@@ -50,7 +51,7 @@ if (!defined('Adminer\DRIVER')) {
|
||||
return false;
|
||||
}
|
||||
$row = $result->fetch_array();
|
||||
return $row[$field];
|
||||
return ($row ? $row[$field] : false);
|
||||
}
|
||||
|
||||
function quote($string) {
|
||||
@@ -60,14 +61,16 @@ 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
|
||||
$flavor = '', ///< @var string different vendor with the same API, e.g. MariaDB, usually stays empty
|
||||
$server_info, ///< @var string server version
|
||||
$affected_rows, ///< @var int number of affected rows
|
||||
$info, ///< @var string see https://php.net/mysql_info
|
||||
$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,32 +83,32 @@ 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
|
||||
/** Set the client character set
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
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 +118,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 +126,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 +135,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 +155,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 +180,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,23 +200,30 @@ 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
|
||||
* @return object properties: name, type (0 number, 15 varchar, 254 char), charsetnr (63 binary); optionally: table, orgtable, orgname
|
||||
*/
|
||||
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);
|
||||
return $return;
|
||||
}
|
||||
@@ -226,13 +231,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 +289,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 +332,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 +370,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->flavor == '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 +380,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 +395,7 @@ if (!defined('Adminer\DRIVER')) {
|
||||
}
|
||||
|
||||
function tableHelp($name, $is_view = false) {
|
||||
$maria = preg_match('~MariaDB~', $this->_conn->server_info);
|
||||
$maria = ($this->conn->flavor == 'maria');
|
||||
if (information_schema(DB)) {
|
||||
return strtolower("information-schema-" . ($maria ? "$name-table/" : str_replace("_", "-", $name) . "-table.html"));
|
||||
}
|
||||
@@ -395,11 +407,21 @@ 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;
|
||||
}
|
||||
|
||||
function engines() {
|
||||
$return = array();
|
||||
foreach (get_rows("SHOW ENGINES") as $row) {
|
||||
if (preg_match("~YES|DEFAULT~", $row["Support"])) {
|
||||
$return[] = $row["Engine"];
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -425,10 +447,13 @@ if (!defined('Adminer\DRIVER')) {
|
||||
* @return mixed Db or string for error
|
||||
*/
|
||||
function connect($credentials) {
|
||||
global $drivers;
|
||||
$connection = new Db;
|
||||
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
|
||||
$connection->set_charset(charset($connection)); // available in MySQLi since PHP 5.0.5
|
||||
$connection->set_charset(charset($connection));
|
||||
$connection->query("SET sql_quote_show_create = 1, autocommit = 1");
|
||||
$connection->flavor = (preg_match('~MariaDB~', $connection->server_info) ? 'maria' : '');
|
||||
$drivers[DRIVER] = ($connection->flavor == 'maria' ? "MariaDB" : "MySQL");
|
||||
return $connection;
|
||||
}
|
||||
$return = $connection->error;
|
||||
@@ -495,19 +520,6 @@ if (!defined('Adminer\DRIVER')) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Get supported engines
|
||||
* @return array
|
||||
*/
|
||||
function engines() {
|
||||
$return = array();
|
||||
foreach (get_rows("SHOW ENGINES") as $row) {
|
||||
if (preg_match("~YES|DEFAULT~", $row["Support"])) {
|
||||
$return[] = $row["Engine"];
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Get logged user
|
||||
* @return string
|
||||
*/
|
||||
@@ -584,30 +596,45 @@ 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->flavor == '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"),
|
||||
@@ -649,7 +676,12 @@ if (!defined('Adminer\DRIVER')) {
|
||||
$return = array();
|
||||
$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);
|
||||
@@ -786,12 +818,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->flavor == '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,7 +1001,9 @@ if (!defined('Adminer\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 = get_val("SHOW CREATE $type " . idf_escape($name), 2);
|
||||
preg_match("~\\(((?:$pattern\\s*,?)*)\\)\\s*" . ($type == "FUNCTION" ? "RETURNS\\s+$type_pattern\\s+" : "") . "(.*)~is", $create, $match);
|
||||
@@ -977,7 +1013,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],
|
||||
@@ -1019,9 +1055,10 @@ if (!defined('Adminer\DRIVER')) {
|
||||
}
|
||||
|
||||
/** Get last auto increment ID
|
||||
* @param Result or true
|
||||
* @return string
|
||||
*/
|
||||
function last_id() {
|
||||
function last_id($result) {
|
||||
return get_val("SELECT LAST_INSERT_ID()"); // mysql_insert_id() truncates bigint
|
||||
}
|
||||
|
||||
@@ -1121,10 +1158,17 @@ if (!defined('Adminer\DRIVER')) {
|
||||
}
|
||||
|
||||
/** Get server variables
|
||||
* @return array [$name => $value]
|
||||
* @return array [[$name, $value]]
|
||||
*/
|
||||
function show_variables() {
|
||||
return get_key_vals("SHOW VARIABLES");
|
||||
return get_rows("SHOW VARIABLES");
|
||||
}
|
||||
|
||||
/** Get status variables
|
||||
* @return array [[$name, $value]]
|
||||
*/
|
||||
function show_status() {
|
||||
return get_rows("SHOW STATUS");
|
||||
}
|
||||
|
||||
/** Get process list
|
||||
@@ -1134,13 +1178,6 @@ if (!defined('Adminer\DRIVER')) {
|
||||
return get_rows("SHOW FULL PROCESSLIST");
|
||||
}
|
||||
|
||||
/** Get status variables
|
||||
* @return array [$name => $value]
|
||||
*/
|
||||
function show_status() {
|
||||
return get_key_vals("SHOW STATUS");
|
||||
}
|
||||
|
||||
/** Convert field in select and edit
|
||||
* @param array one element from fields()
|
||||
* @return string
|
||||
@@ -1177,7 +1214,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) {
|
||||
|
@@ -5,10 +5,11 @@ $drivers["oracle"] = "Oracle (beta)";
|
||||
|
||||
if (isset($_GET["oracle"])) {
|
||||
define('Adminer\DRIVER', "oracle");
|
||||
if (extension_loaded("oci8")) {
|
||||
if (extension_loaded("oci8") && $_GET["ext"] != "pdo") {
|
||||
class Db {
|
||||
var $extension = "oci8", $_link, $_result, $server_info, $affected_rows, $errno, $error;
|
||||
var $_current_db;
|
||||
public $extension = "oci8", $flavor = '', $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,11 +62,11 @@ 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() {
|
||||
@@ -74,21 +75,19 @@ if (isset($_GET["oracle"])) {
|
||||
|
||||
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 + 1);
|
||||
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,35 @@ 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->orgname = $return->name;
|
||||
$return->type = oci_field_type($this->_result, $column);
|
||||
$return->name = oci_field_name($this->result, $column);
|
||||
$return->type = oci_field_type($this->result, $column); //! map to MySQL numbers
|
||||
$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 +146,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 +157,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);
|
||||
@@ -244,10 +246,6 @@ ORDER BY 1"
|
||||
return get_val("SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET'"); //! respect $db
|
||||
}
|
||||
|
||||
function engines() {
|
||||
return array();
|
||||
}
|
||||
|
||||
function logged_user() {
|
||||
return get_val("SELECT USER FROM DUAL");
|
||||
}
|
||||
@@ -492,7 +490,7 @@ AND c_src.TABLE_NAME = " . q($table);
|
||||
return apply_queries("DROP TABLE", $tables);
|
||||
}
|
||||
|
||||
function last_id() {
|
||||
function last_id($result) {
|
||||
return 0; //!
|
||||
}
|
||||
|
||||
@@ -514,11 +512,29 @@ AND c_src.TABLE_NAME = " . q($table);
|
||||
}
|
||||
|
||||
function show_variables() {
|
||||
return get_key_vals('SELECT name, display_value FROM v$parameter');
|
||||
return get_rows('SELECT name, display_value FROM v$parameter');
|
||||
}
|
||||
|
||||
function show_status() {
|
||||
$return = array();
|
||||
$rows = get_rows('SELECT * FROM v$instance');
|
||||
foreach (reset($rows) as $key => $val) {
|
||||
$return[] = array($key, $val);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
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\'
|
||||
@@ -526,11 +542,6 @@ ORDER BY PROCESS
|
||||
');
|
||||
}
|
||||
|
||||
function show_status() {
|
||||
$rows = get_rows('SELECT * FROM v$instance');
|
||||
return reset($rows);
|
||||
}
|
||||
|
||||
function convert_field($field) {
|
||||
}
|
||||
|
||||
|
@@ -5,9 +5,10 @@ $drivers["pgsql"] = "PostgreSQL";
|
||||
|
||||
if (isset($_GET["pgsql"])) {
|
||||
define('Adminer\DRIVER', "pgsql");
|
||||
if (extension_loaded("pgsql")) {
|
||||
if (extension_loaded("pgsql") && $_GET["ext"] != "pdo") {
|
||||
class Db {
|
||||
var $extension = "PgSQL", $_link, $_result, $_string, $_database = true, $server_info, $affected_rows, $error, $timeout;
|
||||
public $extension = "PgSQL", $flavor = '', $server_info, $affected_rows, $error, $timeout;
|
||||
private $link, $result, $string, $database = true;
|
||||
|
||||
function _error($errno, $error) {
|
||||
if (ini_bool("html_errors")) {
|
||||
@@ -21,59 +22,56 @@ 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);
|
||||
$this->server_info = $version["server"];
|
||||
pg_set_client_encoding($this->_link, "UTF8");
|
||||
if ($this->link) {
|
||||
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 +87,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 +101,53 @@ 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->name = pg_field_name($this->_result, $column);
|
||||
$return->orgname = $return->name;
|
||||
$return->type = pg_field_type($this->_result, $column);
|
||||
$return->orgtable = pg_field_table($this->result, $column);
|
||||
$return->name = pg_field_name($this->result, $column);
|
||||
$return->type = pg_field_type($this->result, $column); //! map to MySQL numbers
|
||||
$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 +167,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 +192,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);
|
||||
@@ -243,6 +236,13 @@ if (isset($_GET["pgsql"])) {
|
||||
$this->types[lang('User types')] = array_flip($types);
|
||||
}
|
||||
|
||||
function insertReturning($table) {
|
||||
$auto_increment = array_filter(fields($table), function ($field) {
|
||||
return $field['auto_increment'];
|
||||
});
|
||||
return (count($auto_increment) == 1 ? " RETURNING " . idf_escape(key($auto_increment)) : "");
|
||||
}
|
||||
|
||||
function insertUpdate($table, $rows, $primary) {
|
||||
global $connection;
|
||||
foreach ($rows as $set) {
|
||||
@@ -265,8 +265,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;
|
||||
}
|
||||
|
||||
@@ -280,11 +280,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) {
|
||||
@@ -299,13 +299,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,11 +323,18 @@ if (isset($_GET["pgsql"])) {
|
||||
}
|
||||
|
||||
function connect($credentials) {
|
||||
global $drivers;
|
||||
$connection = new Db;
|
||||
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
|
||||
if (min_version(9, 0, $connection)) {
|
||||
$connection->query("SET application_name = 'Adminer'");
|
||||
}
|
||||
$version = $connection->result("SELECT version()");
|
||||
$connection->flavor = (preg_match('~CockroachDB~', $version) ? 'cockroach' : '');
|
||||
$connection->server_info = preg_replace('~^\D*([\d.]+[-\w]*).*~', '\1', $version);
|
||||
if ($connection->flavor == 'cockroach') { // we don't use "PostgreSQL / CockroachDB" by default because it's too long
|
||||
$drivers[DRIVER] = "CockroachDB";
|
||||
}
|
||||
return $connection;
|
||||
}
|
||||
return $connection->error;
|
||||
@@ -353,10 +361,6 @@ ORDER BY datname");
|
||||
return get_val("SELECT datcollate FROM pg_database WHERE datname = " . q($db));
|
||||
}
|
||||
|
||||
function engines() {
|
||||
return array();
|
||||
}
|
||||
|
||||
function logged_user() {
|
||||
return get_val("SELECT user");
|
||||
}
|
||||
@@ -428,7 +432,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
|
||||
@@ -456,8 +467,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]);
|
||||
}
|
||||
@@ -474,7 +486,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();
|
||||
@@ -658,7 +675,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) {
|
||||
@@ -695,7 +711,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";
|
||||
}
|
||||
@@ -752,13 +773,14 @@ ORDER BY SPECIFIC_NAME');
|
||||
function routine_id($name, $row) {
|
||||
$return = array();
|
||||
foreach ($row["fields"] as $field) {
|
||||
$return[] = $field["type"];
|
||||
$length = $field["length"];
|
||||
$return[] = $field["type"] . ($length ? "($length)" : "");
|
||||
}
|
||||
return idf_escape($name) . "(" . implode(", ", $return) . ")";
|
||||
}
|
||||
|
||||
function last_id() {
|
||||
return 0; // there can be several sequences
|
||||
function last_id($result) {
|
||||
return (is_object($result) && $result->num_rows ? $result->fetch_column(0) : 0);
|
||||
}
|
||||
|
||||
function explain($connection, $query) {
|
||||
@@ -851,7 +873,7 @@ AND typelem = 0"
|
||||
// sequences for fields
|
||||
if (preg_match('~nextval\(\'([^\']+)\'\)~', $field['default'], $matches)) {
|
||||
$sequence_name = $matches[1];
|
||||
$sq = reset(get_rows((min_version(10)
|
||||
$sq = first(get_rows((min_version(10)
|
||||
? "SELECT *, cache_size AS cache_value FROM pg_sequences WHERE schemaname = current_schema() AND sequencename = " . q(idf_unescape($sequence_name))
|
||||
: "SELECT * FROM $sequence_name"
|
||||
), null, "-- "));
|
||||
@@ -920,7 +942,7 @@ AND typelem = 0"
|
||||
}
|
||||
|
||||
function show_variables() {
|
||||
return get_key_vals("SHOW ALL");
|
||||
return get_rows("SHOW ALL");
|
||||
}
|
||||
|
||||
function process_list() {
|
||||
@@ -935,7 +957,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 preg_match('~^(check|database|table|columns|sql|indexes|descidx|comment|view|' . (min_version(9.3) ? 'materializedview|' : '') . 'scheme|' . (min_version(11) ? 'procedure|' : '') . 'routine|sequence|trigger|type|variables|drop_col'
|
||||
. ($connection->flavor == 'cockroach' ? '' : '|processlist') // https://github.com/cockroachdb/cockroach/issues/24745
|
||||
. '|kill|dump)$~', $feature)
|
||||
;
|
||||
}
|
||||
|
||||
function kill_process($val) {
|
||||
|
@@ -5,40 +5,41 @@ $drivers["sqlite"] = "SQLite";
|
||||
|
||||
if (isset($_GET["sqlite"])) {
|
||||
define('Adminer\DRIVER', "sqlite");
|
||||
if (class_exists("SQLite3")) {
|
||||
if (class_exists("SQLite3") && $_GET["ext"] != "pdo") {
|
||||
|
||||
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) . "'"
|
||||
: "x'" . reset(unpack('H*', $string)) . "'"
|
||||
? "'" . $this->link->escapeString($string) . "'"
|
||||
: "x'" . first(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),
|
||||
"type" => $type,
|
||||
"name" => $this->result->columnName($column),
|
||||
"type" => ($type == SQLITE3_TEXT ? 15 : 0),
|
||||
"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", "", "");
|
||||
@@ -98,6 +100,7 @@ if (isset($_GET["sqlite"])) {
|
||||
|
||||
if (class_exists('Adminer\SqliteDb')) {
|
||||
class Db extends SqliteDb {
|
||||
public $flavor = '';
|
||||
|
||||
function __construct() {
|
||||
parent::__construct(":memory:");
|
||||
@@ -113,14 +116,6 @@ if (isset($_GET["sqlite"])) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function multi_query($query) {
|
||||
return $this->_result = $this->query($query);
|
||||
}
|
||||
|
||||
function next_result() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +127,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 +137,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 +170,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]);
|
||||
}
|
||||
}
|
||||
@@ -217,10 +212,6 @@ if (isset($_GET["sqlite"])) {
|
||||
return get_val("PRAGMA encoding"); // there is no database list so $db == DB
|
||||
}
|
||||
|
||||
function engines() {
|
||||
return array();
|
||||
}
|
||||
|
||||
function logged_user() {
|
||||
return get_current_user(); // should return effective user
|
||||
}
|
||||
@@ -395,7 +386,7 @@ if (isset($_GET["sqlite"])) {
|
||||
}
|
||||
try {
|
||||
$link = new SqliteDb($db);
|
||||
} catch (Exception $ex) {
|
||||
} catch (\Exception $ex) {
|
||||
$connection->error = $ex->getMessage();
|
||||
return false;
|
||||
}
|
||||
@@ -678,7 +669,7 @@ if (isset($_GET["sqlite"])) {
|
||||
return queries("BEGIN");
|
||||
}
|
||||
|
||||
function last_id() {
|
||||
function last_id($result) {
|
||||
return get_val("SELECT LAST_INSERT_ROWID()");
|
||||
}
|
||||
|
||||
@@ -720,8 +711,9 @@ if (isset($_GET["sqlite"])) {
|
||||
foreach (get_rows("PRAGMA pragma_list") as $row) {
|
||||
$name = $row["name"];
|
||||
if ($name != "pragma_list" && $name != "compile_options") {
|
||||
$return[$name] = array($name, '');
|
||||
foreach (get_rows("PRAGMA $name") as $row) {
|
||||
$return[$name] .= implode(", ", $row) . "\n";
|
||||
$return[$name][1] .= implode(", ", $row) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -731,8 +723,7 @@ if (isset($_GET["sqlite"])) {
|
||||
function show_status() {
|
||||
$return = array();
|
||||
foreach (get_vals("PRAGMA compile_options") as $option) {
|
||||
list($key, $val) = explode("=", $option, 2);
|
||||
$return[$key] = $val;
|
||||
$return[] = explode("=", $option, 2);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
@@ -4,11 +4,10 @@ namespace Adminer;
|
||||
$TABLE = $_GET["dump"];
|
||||
|
||||
if ($_POST && !$error) {
|
||||
$cookie = "";
|
||||
foreach (array("output", "format", "db_style", "types", "routines", "events", "table_style", "auto_increment", "triggers", "data_style") as $key) {
|
||||
$cookie .= "&$key=" . urlencode($_POST[$key]);
|
||||
}
|
||||
cookie("adminer_export", substr($cookie, 1));
|
||||
save_settings(
|
||||
array_intersect_key($_POST, array_flip(array("output", "format", "db_style", "types", "routines", "events", "table_style", "auto_increment", "triggers", "data_style"))),
|
||||
"adminer_export"
|
||||
);
|
||||
$tables = array_flip((array) $_POST["tables"]) + array_flip((array) $_POST["data"]);
|
||||
$ext = dump_headers(
|
||||
(count($tables) == 1 ? key($tables) : DB),
|
||||
@@ -140,9 +139,7 @@ SET foreign_key_checks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_sql) {
|
||||
echo "-- " . gmdate("Y-m-d H:i:s e") . "\n";
|
||||
}
|
||||
$adminer->dumpFooter();
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -158,7 +155,7 @@ $data_style = array('', 'TRUNCATE+INSERT', 'INSERT');
|
||||
if (JUSH == "sql") { //! use insertUpdate() in all drivers
|
||||
$data_style[] = 'INSERT+UPDATE';
|
||||
}
|
||||
parse_str($_COOKIE["adminer_export"], $row);
|
||||
$row = get_settings("adminer_export");
|
||||
if (!$row) {
|
||||
$row = array("output" => "text", "format" => "sql", "db_style" => (DB != "" ? "" : "CREATE"), "table_style" => "DROP+CREATE", "data_style" => "INSERT");
|
||||
}
|
||||
@@ -167,9 +164,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')) : "")
|
||||
@@ -186,7 +183,7 @@ echo "<tr><th>" . lang('Data') . "<td>" . html_select('data_style', $data_style,
|
||||
?>
|
||||
</table>
|
||||
<p><input type="submit" value="<?php echo lang('Export'); ?>">
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
<?php echo input_token(); ?>
|
||||
|
||||
<table>
|
||||
<?php
|
||||
|
@@ -55,7 +55,7 @@ if ($_POST && !$error && !isset($_GET["select"])) {
|
||||
}
|
||||
} else {
|
||||
$result = $driver->insert($TABLE, $set);
|
||||
$last_id = ($result ? last_id() : 0);
|
||||
$last_id = ($result ? last_id($result) : 0);
|
||||
queries_redirect($location, lang('Item%s has been inserted.', ($last_id ? " $last_id" : "")), $result); //! link
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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";
|
||||
|
@@ -56,5 +56,5 @@ if (!$row && $EVENT != "") {
|
||||
<?php if ($EVENT != "") { ?>
|
||||
<input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $EVENT)); ?>
|
||||
<?php } ?>
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
<?php echo input_token(); ?>
|
||||
</form>
|
||||
|
@@ -1,7 +1,15 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
// caching headers added in compile.php
|
||||
if (substr($VERSION, -4) != '-dev') {
|
||||
if ($_SERVER["HTTP_IF_MODIFIED_SINCE"]) {
|
||||
header("HTTP/1.1 304 Not Modified");
|
||||
exit;
|
||||
}
|
||||
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 365*24*60*60) . " GMT");
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
||||
header("Cache-Control: immutable");
|
||||
}
|
||||
|
||||
if ($_GET["file"] == "favicon.ico") {
|
||||
header("Content-Type: image/x-icon");
|
||||
@@ -9,6 +17,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;../externals/jush/jush-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'));
|
||||
|
@@ -85,8 +85,8 @@ if (support("scheme")) {
|
||||
}
|
||||
echo lang('DB') . ": " . html_select("db", $dbs, $row["db"] != "" ? $row["db"] : $_GET["db"], $onchange);
|
||||
}
|
||||
echo input_hidden("change-js");
|
||||
?>
|
||||
<input type="hidden" name="change-js" value="">
|
||||
<noscript><p><input type="submit" name="change" value="<?php echo lang('Change'); ?>"></noscript>
|
||||
<table>
|
||||
<thead><tr><th id="label-source"><?php echo lang('Source'); ?><th id="label-target"><?php echo lang('Target'); ?></thead>
|
||||
@@ -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++;
|
||||
}
|
||||
?>
|
||||
@@ -116,5 +116,5 @@ foreach ($row["source"] as $key => $val) {
|
||||
<?php if ($name != "") { ?>
|
||||
<input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $name)); ?>
|
||||
<?php } ?>
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
<?php echo input_token(); ?>
|
||||
</form>
|
||||
|
@@ -4,8 +4,8 @@ namespace Adminer;
|
||||
// any method change in this file should be transferred to editor/include/adminer.inc.php and plugins/plugin.php
|
||||
|
||||
class Adminer {
|
||||
/** @var array operators used in select, null for all operators */
|
||||
var $operators;
|
||||
public $operators; ///< @var array operators used in select, null for all operators
|
||||
public $error = ''; ///< @var protected(set) string HTML
|
||||
|
||||
/** Name in title and navigation
|
||||
* @return string HTML code
|
||||
@@ -94,12 +94,13 @@ class Adminer {
|
||||
}
|
||||
|
||||
/** Print HTML code inside <head>
|
||||
* @return bool true to link favicon.ico and adminer.css if exists
|
||||
* @param bool dark CSS: false to disable, true to force, null to base on user preferences
|
||||
* @return bool true to link favicon.ico
|
||||
*/
|
||||
function head() {
|
||||
?>
|
||||
<link rel="stylesheet" type="text/css" href="../externals/jush/jush.css">
|
||||
<?php
|
||||
function head($dark = null) {
|
||||
// this is matched by compile.php
|
||||
echo "<link rel='stylesheet' href='../externals/jush/jush.css'>\n";
|
||||
echo ($dark !== false ? "<link rel='stylesheet'" . ($dark ? "" : " media='(prefers-color-scheme: dark)'") . " href='../externals/jush/jush-dark.css'>\n" : "");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -108,9 +109,11 @@ class Adminer {
|
||||
*/
|
||||
function css() {
|
||||
$return = array();
|
||||
$filename = "adminer.css";
|
||||
if (file_exists($filename)) {
|
||||
$return[] = "$filename?v=" . crc32(file_get_contents($filename));
|
||||
foreach (array("", "-dark") as $mode) {
|
||||
$filename = "adminer$mode.css";
|
||||
if (file_exists($filename)) {
|
||||
$return[] = "$filename?v=" . crc32(file_get_contents($filename));
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
@@ -121,8 +124,10 @@ class Adminer {
|
||||
function loginForm() {
|
||||
global $drivers;
|
||||
echo "<table class='layout'>\n";
|
||||
// this is matched by compile.php
|
||||
echo $this->loginFormField('driver', '<tr><th>' . lang('System') . '<td>', html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);"));
|
||||
echo $this->loginFormField('server', '<tr><th>' . lang('Server') . '<td>', '<input name="auth[server]" value="' . h(SERVER) . '" title="hostname[:port]" placeholder="localhost" autocapitalize="off">');
|
||||
// this is matched by compile.php
|
||||
echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input name="auth[username]" id="username" autofocus value="' . h($_GET["username"]) . '" autocomplete="username" autocapitalize="off">' . script("qs('#username').form['auth[driver]'].onchange();"));
|
||||
echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td>', '<input type="password" name="auth[password]" autocomplete="current-password">');
|
||||
echo $this->loginFormField('db', '<tr><th>' . lang('Database') . '<td>', '<input name="auth[db]" value="' . h($_GET["db"]) . '" autocapitalize="off">');
|
||||
@@ -167,7 +172,9 @@ class Adminer {
|
||||
* @return string HTML code, "" to ignore field
|
||||
*/
|
||||
function fieldName($field, $order = 0) {
|
||||
return '<span title="' . h($field["full_type"]) . '">' . h($field["field"]) . '</span>';
|
||||
$type = $field["full_type"];
|
||||
$comment = $field["comment"];
|
||||
return '<span title="' . h($type . ($comment != "" ? ($type ? ": " : "") . $comment : '')) . '">' . h($field["field"]) . '</span>';
|
||||
}
|
||||
|
||||
/** Print links after select heading
|
||||
@@ -256,6 +263,11 @@ class Adminer {
|
||||
return shorten_utf8(trim($query), 1000);
|
||||
}
|
||||
|
||||
/** Print HTML code just before the Execute button in SQL command
|
||||
*/
|
||||
function sqlPrintAfter() {
|
||||
}
|
||||
|
||||
/** Description of a row in a table
|
||||
* @param string
|
||||
* @return string SQL expression, empty string for no description
|
||||
@@ -289,13 +301,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);
|
||||
}
|
||||
|
||||
@@ -310,9 +323,10 @@ class Adminer {
|
||||
|
||||
/** Print table structure in tabular format
|
||||
* @param array data about individual fields
|
||||
* @param array
|
||||
* @return null
|
||||
*/
|
||||
function tableStructurePrint($fields) {
|
||||
function tableStructurePrint($fields, $tableStatus = null) {
|
||||
global $driver;
|
||||
echo "<div class='scrollable'>\n";
|
||||
echo "<table class='nowrap odds'>\n";
|
||||
@@ -321,8 +335,11 @@ class Adminer {
|
||||
foreach ($fields as $field) {
|
||||
echo "<tr><th>" . h($field["field"]);
|
||||
$type = h($field["full_type"]);
|
||||
echo "<td><span title='" . h($field["collation"]) . "'>"
|
||||
. (in_array($type, (array) $structured_types[lang('User types')]) ? "<a href='" . h(ME . 'type=' . urlencode($type)) . "'>$type</a>" : $type)
|
||||
$collation = h($field["collation"]);
|
||||
echo "<td><span title='$collation'>"
|
||||
. (in_array($type, (array) $structured_types[lang('User types')])
|
||||
? "<a href='" . h(ME . 'type=' . urlencode($type)) . "'>$type</a>"
|
||||
: $type . ($collation && isset($tableStatus["Collation"]) && $collation != $tableStatus["Collation"] ? " $collation" : ""))
|
||||
. "</span>"
|
||||
;
|
||||
echo ($field["null"] ? " <i>NULL</i>" : "");
|
||||
@@ -375,7 +392,7 @@ class Adminer {
|
||||
($key !== "" ? "selectFieldChange" : "selectAddRow")
|
||||
);
|
||||
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)
|
||||
. on_help("event.target.value && event.target.value.replace(/ |\$/, '(') + ')'", 1)
|
||||
. script("qsl('select').onchange = function () { helpClose();" . ($key !== "" ? "" : " qsl('select, input', this.parentNode).onchange();") . " };", "")
|
||||
. "($column)" : $column) . "</div>\n";
|
||||
$i++;
|
||||
@@ -472,7 +489,7 @@ class Adminer {
|
||||
echo "<input type='submit' value='" . lang('Select') . "'>";
|
||||
echo " <span id='noindex' title='" . lang('Full table scan') . "'></span>";
|
||||
echo "<script" . nonce() . ">\n";
|
||||
echo "var indexColumns = ";
|
||||
echo "const indexColumns = ";
|
||||
$columns = array();
|
||||
foreach ($indexes as $index) {
|
||||
$current_key = reset($index["columns"]);
|
||||
@@ -761,7 +778,7 @@ class Adminer {
|
||||
return unconvert_field($field, $return);
|
||||
}
|
||||
|
||||
/** Returns export output options
|
||||
/** Return export output options
|
||||
* @return array
|
||||
*/
|
||||
function dumpOutput() {
|
||||
@@ -772,7 +789,7 @@ class Adminer {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Returns export format options
|
||||
/** Return export format options
|
||||
* @return array empty to disable export
|
||||
*/
|
||||
function dumpFormat() {
|
||||
@@ -937,11 +954,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
|
||||
*/
|
||||
@@ -960,31 +989,28 @@ class Adminer {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Prints navigation after Adminer title
|
||||
/** Print navigation after Adminer title
|
||||
* @param string can be "auth" if there is no database connection, "db" if there is no database selected, "ns" with invalid schema
|
||||
* @return null
|
||||
*/
|
||||
function navigation($missing) {
|
||||
global $VERSION, $drivers, $connection;
|
||||
?>
|
||||
<h1>
|
||||
<?php echo $this->name(); ?>
|
||||
<span class="version">
|
||||
<?php echo $VERSION; ?>
|
||||
<a href="https://www.adminer.org/#download"<?php echo target_blank(); ?> id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?></a>
|
||||
</span>
|
||||
</h1>
|
||||
<?php
|
||||
echo "<h1>" . $this->name() . " <span class='version'>$VERSION";
|
||||
$new_version = $_COOKIE["adminer_version"];
|
||||
echo " <a href='https://www.adminer.org/#download'" . target_blank() . " id='version'>" . (version_compare($VERSION, $new_version) < 0 ? h($new_version) : "") . "</a>";
|
||||
echo "</span></h1>\n";
|
||||
// this is matched by compile.php
|
||||
switch_lang();
|
||||
if ($missing == "auth") {
|
||||
$output = "";
|
||||
foreach ((array) $_SESSION["pwds"] as $vendor => $servers) {
|
||||
foreach ($servers as $server => $usernames) {
|
||||
$name = h(get_setting("vendor-$vendor-$server") ?: $drivers[$vendor]);
|
||||
foreach ($usernames as $username => $password) {
|
||||
if ($password !== null) {
|
||||
$dbs = $_SESSION["db"][$vendor][$server][$username];
|
||||
foreach (($dbs ? array_keys($dbs) : array("")) as $db) {
|
||||
$output .= "<li><a href='" . h(auth_url($vendor, $server, $username, $db)) . "'>($drivers[$vendor]) " . h($username . ($server != "" ? "@" . $this->serverName($server) : "") . ($db != "" ? " - $db" : "")) . "</a>\n";
|
||||
$output .= "<li><a href='" . h(auth_url($vendor, $server, $username, $db)) . "'>($name) " . h($username . ($server != "" ? "@" . $this->serverName($server) : "") . ($db != "" ? " - $db" : "")) . "</a>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -999,31 +1025,7 @@ class Adminer {
|
||||
$connection->select_db(DB);
|
||||
$tables = table_status('', true);
|
||||
}
|
||||
echo script_src("../externals/jush/modules/jush.js");
|
||||
echo script_src("../externals/jush/modules/jush-textarea.js");
|
||||
echo script_src("../externals/jush/modules/jush-txt.js");
|
||||
echo script_src("../externals/jush/modules/jush-js.js");
|
||||
if (support("sql")) {
|
||||
echo script_src("../externals/jush/modules/jush-" . JUSH . ".js");
|
||||
?>
|
||||
<script<?php echo nonce(); ?>>
|
||||
<?php
|
||||
if ($tables) {
|
||||
$links = array();
|
||||
foreach ($tables as $table => $type) {
|
||||
$links[] = preg_quote($table, '/');
|
||||
}
|
||||
echo "var jushLinks = { " . JUSH . ": [ '" . js_escape(ME) . (support("table") ? "table=" : "select=") . "\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n";
|
||||
foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) {
|
||||
echo "jushLinks.$val = jushLinks." . JUSH . ";\n";
|
||||
}
|
||||
}
|
||||
$server_info = $connection->server_info;
|
||||
?>
|
||||
bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '\1', $server_info) : ""); ?>'<?php echo (preg_match('~MariaDB~', $server_info) ? ", true" : ""); ?>);
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
$this->syntaxHighlighting($tables);
|
||||
$this->databasesPrint($missing);
|
||||
$actions = array();
|
||||
if (DB == "" || !$missing) {
|
||||
@@ -1048,7 +1050,37 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
|
||||
}
|
||||
}
|
||||
|
||||
/** Prints databases list in menu
|
||||
/** Set up syntax highlight for code and <textarea>
|
||||
* @param array result of table_status()
|
||||
*/
|
||||
function syntaxHighlighting($tables) {
|
||||
global $connection;
|
||||
// this is matched by compile.php
|
||||
echo script_src("../externals/jush/modules/jush.js");
|
||||
echo script_src("../externals/jush/modules/jush-textarea.js");
|
||||
echo script_src("../externals/jush/modules/jush-txt.js");
|
||||
echo script_src("../externals/jush/modules/jush-js.js");
|
||||
if (support("sql")) {
|
||||
echo script_src("../externals/jush/modules/jush-" . JUSH . ".js");
|
||||
echo "<script" . nonce() . ">\n";
|
||||
if ($tables) {
|
||||
$links = array();
|
||||
foreach ($tables as $table => $type) {
|
||||
$links[] = preg_quote($table, '/');
|
||||
}
|
||||
echo "var jushLinks = { " . JUSH . ": [ '" . js_escape(ME) . (support("table") ? "table=" : "select=") . "\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n";
|
||||
foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) {
|
||||
echo "jushLinks.$val = jushLinks." . JUSH . ";\n";
|
||||
}
|
||||
}
|
||||
echo "</script>\n";
|
||||
}
|
||||
echo script("syntaxHighlighting('" . (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '\1', $connection->server_info) : "") . "'"
|
||||
. ($connection->flavor == 'maria' ? ", 'maria'" : ($connection->flavor == 'cockroach' ? ", 'cockroach'" : "")) . ");"
|
||||
);
|
||||
}
|
||||
|
||||
/** Print databases list in menu
|
||||
* @param string
|
||||
* @return null
|
||||
*/
|
||||
@@ -1058,20 +1090,17 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
|
||||
if (DB && $databases && !in_array(DB, $databases)) {
|
||||
array_unshift($databases, DB);
|
||||
}
|
||||
?>
|
||||
<form action="">
|
||||
<p id="dbs">
|
||||
<?php
|
||||
echo "<form action=''>\n<p id='dbs'>\n";
|
||||
hidden_fields_get();
|
||||
$db_events = script("mixin(qsl('select'), {onmousedown: dbMouseDown, onchange: dbChange});");
|
||||
echo "<span title='" . lang('Database') . "'>" . lang('DB') . "</span>: " . ($databases
|
||||
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') . ": " . html_select("ns", array("" => "") + $adminer->schemas(), $_GET["ns"]) . $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"]);
|
||||
}
|
||||
@@ -1079,14 +1108,14 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
|
||||
}
|
||||
foreach (array("import", "sql", "schema", "dump", "privileges") as $val) {
|
||||
if (isset($_GET[$val])) {
|
||||
echo "<input type='hidden' name='$val' value=''>";
|
||||
echo input_hidden($val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
echo "</p></form>\n";
|
||||
}
|
||||
|
||||
/** Prints table list in menu
|
||||
/** Print table list in menu
|
||||
* @param array result of table_status('', true)
|
||||
* @return null
|
||||
*/
|
||||
|
@@ -19,7 +19,17 @@ if ($_COOKIE["adminer_permanent"]) {
|
||||
|
||||
function add_invalid_login() {
|
||||
global $adminer;
|
||||
$fp = file_open_lock(get_temp_dir() . "/adminer.invalid");
|
||||
$base = get_temp_dir() . "/adminer.invalid";
|
||||
// adminer.invalid may not be writable by us, try the files with random suffixes
|
||||
foreach (glob("$base*") ?: array($base) as $filename) {
|
||||
$fp = file_open_lock($filename);
|
||||
if ($fp) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$fp) {
|
||||
$fp = file_open_lock("$base-" . rand_string());
|
||||
}
|
||||
if (!$fp) {
|
||||
return;
|
||||
}
|
||||
@@ -42,7 +52,15 @@ function add_invalid_login() {
|
||||
|
||||
function check_invalid_login() {
|
||||
global $adminer;
|
||||
$invalids = unserialize(@file_get_contents(get_temp_dir() . "/adminer.invalid")); // @ - may not exist
|
||||
$invalids = array();
|
||||
foreach (glob(get_temp_dir() . "/adminer.invalid*") as $filename) {
|
||||
$fp = file_open_lock($filename);
|
||||
if ($fp) {
|
||||
$invalids = unserialize(stream_get_contents($fp));
|
||||
file_unlock($fp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$invalid = ($invalids ? $invalids[$adminer->bruteForceKey()] : array());
|
||||
$next_attempt = ($invalid[1] > 29 ? $invalid[0] - time() : 0); // allow 30 invalid attempts
|
||||
if ($next_attempt > 0) { //! do the same with permanent login
|
||||
@@ -61,7 +79,7 @@ if ($auth) {
|
||||
set_password($vendor, $server, $username, $password);
|
||||
$_SESSION["db"][$vendor][$server][$username][$db] = true;
|
||||
if ($auth["permanent"]) {
|
||||
$key = base64_encode($vendor) . "-" . base64_encode($server) . "-" . base64_encode($username) . "-" . base64_encode($db);
|
||||
$key = implode("-", array_map('base64_encode', array($vendor, $server, $username, $db)));
|
||||
$private = $adminer->permanentLogin(true);
|
||||
$permanent[$key] = "$key:" . base64_encode($private ? encrypt_string($password, $private) : "");
|
||||
cookie("adminer_permanent", implode(" ", $permanent));
|
||||
@@ -105,7 +123,7 @@ function unset_permanent() {
|
||||
cookie("adminer_permanent", implode(" ", $permanent));
|
||||
}
|
||||
|
||||
/** Renders an error message and a login form
|
||||
/** Render an error message and a login form
|
||||
* @param string plain text
|
||||
* @return null exits
|
||||
*/
|
||||
@@ -169,6 +187,9 @@ if (isset($_GET["username"]) && is_string(get_password())) {
|
||||
if ($adminer->operators === null) {
|
||||
$adminer->operators = $driver->operators;
|
||||
}
|
||||
if (Driver::$jush == 'sql' || $connection->flavor == 'cockroach') {
|
||||
save_settings(array("vendor-" . DRIVER . "-" . SERVER => $drivers[DRIVER]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@ namespace Adminer;
|
||||
|
||||
include "../adminer/include/version.inc.php";
|
||||
include "../adminer/include/errors.inc.php";
|
||||
// this is matched by compile.php
|
||||
include "../adminer/include/coverage.inc.php";
|
||||
|
||||
// disable filter.default
|
||||
@@ -21,6 +22,7 @@ if (function_exists("mb_internal_encoding")) {
|
||||
}
|
||||
|
||||
include "../adminer/include/functions.inc.php";
|
||||
include "../adminer/include/html.inc.php";
|
||||
|
||||
// used only in compiled file
|
||||
if (isset($_GET["file"])) {
|
||||
@@ -28,7 +30,9 @@ if (isset($_GET["file"])) {
|
||||
}
|
||||
|
||||
if ($_GET["script"] == "version") {
|
||||
$fp = file_open_lock(get_temp_dir() . "/adminer.version");
|
||||
$filename = get_temp_dir() . "/adminer.version";
|
||||
@unlink($filename); // it may not be writable by us, @ - it may not exist
|
||||
$fp = file_open_lock($filename);
|
||||
if ($fp) {
|
||||
file_write_unlock($fp, serialize(array("signature" => $_POST["signature"], "version" => $_POST["version"])));
|
||||
}
|
||||
@@ -62,7 +66,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,9 +76,18 @@ 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/include/plugins.inc.php";
|
||||
|
||||
if (function_exists('adminer_object')) {
|
||||
$adminer = adminer_object();
|
||||
} elseif (is_dir("adminer-plugins") || file_exists("adminer-plugins.php")) {
|
||||
$adminer = new Plugins(null);
|
||||
} else {
|
||||
$adminer = new Adminer;
|
||||
}
|
||||
|
||||
// this is matched by compile.php
|
||||
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver
|
||||
|
||||
define('Adminer\JUSH', Driver::$jush);
|
||||
@@ -86,6 +98,7 @@ define(
|
||||
preg_replace('~\?.*~', '', relative_uri()) . '?'
|
||||
. (sid() ? SID . '&' : '')
|
||||
. (SERVER !== null ? DRIVER . "=" . urlencode(SERVER) . '&' : '')
|
||||
. ($_GET["ext"] ? "ext=" . urlencode($_GET["ext"]) . '&' : '')
|
||||
. (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '')
|
||||
. (DB != "" ? 'db=' . urlencode(DB) . '&' . (isset($_GET["ns"]) ? "ns=" . urlencode($_GET["ns"]) . "&" : "") : '')
|
||||
);
|
||||
|
@@ -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);
|
||||
@@ -38,6 +44,14 @@ if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET
|
||||
}
|
||||
echo "<p>" . lang('%s version: %s through PHP extension %s', $drivers[DRIVER], "<b>" . h($connection->server_info) . "</b>", "<b>$connection->extension</b>") . "\n";
|
||||
echo "<p>" . lang('Logged as: %s', "<b>" . h(logged_user()) . "</b>") . "\n";
|
||||
if (isset($adminer->plugins) && is_array($adminer->plugins)) {
|
||||
echo "<p>" . lang('Loaded plugins') . ":\n<ul>\n";
|
||||
foreach ($adminer->plugins as $plugin) {
|
||||
$reflection = new \ReflectionObject($plugin);
|
||||
echo "<li><b>" . get_class($plugin) . "</b>" . h(preg_match('~^/[\s*]+(.+)~', $reflection->getDocComment(), $match) ? ": $match[1]" : "") . "\n";
|
||||
}
|
||||
echo "</ul>\n";
|
||||
}
|
||||
$databases = $adminer->databases();
|
||||
if ($databases) {
|
||||
$scheme = support("scheme");
|
||||
@@ -72,13 +86,13 @@ if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET
|
||||
echo (support("database")
|
||||
? "<div class='footer'><div>\n"
|
||||
. "<fieldset><legend>" . lang('Selected') . " <span id='selected'></span></legend><div>\n"
|
||||
. "<input type='hidden' name='all' value=''>" . script("qsl('input').onclick = function () { selectCount('selected', formChecked(this, /^db/)); };") // used by trCheck()
|
||||
. input_hidden("all") . script("qsl('input').onclick = function () { selectCount('selected', formChecked(this, /^db/)); };") // used by trCheck()
|
||||
. "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm() . "\n"
|
||||
. "</div></fieldset>\n"
|
||||
. "</div></div>\n"
|
||||
: ""
|
||||
);
|
||||
echo "<input type='hidden' name='token' value='$token'>\n";
|
||||
echo input_token();
|
||||
echo "</form>\n";
|
||||
echo script("tableCheck();");
|
||||
}
|
||||
|
@@ -2,9 +2,9 @@
|
||||
namespace Adminer;
|
||||
|
||||
// coverage is used in tests and removed in compilation
|
||||
if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer_coverage.ser")) {
|
||||
if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer.coverage")) {
|
||||
function save_coverage() {
|
||||
$coverage_filename = sys_get_temp_dir() . "/adminer_coverage.ser";
|
||||
$coverage_filename = sys_get_temp_dir() . "/adminer.coverage";
|
||||
$coverage = unserialize(file_get_contents($coverage_filename));
|
||||
foreach (xdebug_get_code_coverage() as $filename => $lines) {
|
||||
foreach ($lines as $l => $val) {
|
||||
|
@@ -1,10 +1,6 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
if (!ob_get_level()) {
|
||||
ob_start(null, 4096);
|
||||
}
|
||||
|
||||
/** Print HTML header
|
||||
* @param string used in title, breadcrumb and heading, should be HTML escaped
|
||||
* @param string
|
||||
@@ -19,28 +15,52 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
|
||||
page_messages($error);
|
||||
exit;
|
||||
}
|
||||
if (!ob_get_level()) {
|
||||
ob_start(null, 4096);
|
||||
}
|
||||
$title_all = $title . ($title2 != "" ? ": $title2" : "");
|
||||
$title_page = strip_tags($title_all . (SERVER != "" && SERVER != "localhost" ? h(" - " . SERVER) : "") . " - " . $adminer->name());
|
||||
// initial-scale=1 is the default but Chrome 134 on iOS is not able to zoom out without it
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="<?php echo $LANG; ?>" dir="<?php echo lang('ltr'); ?>">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="robots" content="noindex">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<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"); ?>
|
||||
<?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">
|
||||
<link rel="stylesheet" href="../adminer/static/default.css">
|
||||
<?php
|
||||
$css = $adminer->css();
|
||||
$has_light = false;
|
||||
$has_dark = false;
|
||||
foreach ($css as $filename) {
|
||||
if (strpos($filename, "adminer.css") !== false) {
|
||||
$has_light = true;
|
||||
}
|
||||
if (strpos($filename, "adminer-dark.css") !== false) {
|
||||
$has_dark = true;
|
||||
}
|
||||
}
|
||||
$dark = ($has_light
|
||||
? ($has_dark ? null : false) // both styles - autoswitching, only adminer.css - light
|
||||
: ($has_dark ?: null) // only adminer-dark.css - dark, neither - autoswitching
|
||||
);
|
||||
$media = " media='(prefers-color-scheme: dark)'";
|
||||
if ($dark !== false) {
|
||||
echo "<link rel='stylesheet'" . ($dark ? "" : $media) . " href='../adminer/static/dark.css'>\n";
|
||||
}
|
||||
echo "<meta name='color-scheme' content='" . ($dark === null ? "light dark" : ($dark ? "dark" : "light")) . "'>\n";
|
||||
// this is matched by compile.php
|
||||
echo script_src("../adminer/static/functions.js");
|
||||
echo script_src("static/editing.js");
|
||||
if ($adminer->head($dark)) {
|
||||
echo "<link rel='shortcut icon' type='image/x-icon' href='../adminer/static/favicon.ico'>\n";
|
||||
echo "<link rel='apple-touch-icon' href='../adminer/static/favicon.ico'>\n";
|
||||
}
|
||||
foreach ($css as $val) {
|
||||
echo "<link rel='stylesheet'" . (preg_match('~-dark~', $val) && !$dark ? $media : "") . " href='" . h($val) . "'>\n";
|
||||
}
|
||||
echo "\n<body class='" . lang('ltr') . " nojs'>\n";
|
||||
$filename = get_temp_dir() . "/adminer.version";
|
||||
if (!$_COOKIE["adminer_version"] && function_exists('openssl_verify') && file_exists($filename) && filemtime($filename) + 86400 > time()) { // 86400 - 1 day in seconds
|
||||
$version = unserialize(file_get_contents($filename));
|
||||
@@ -58,21 +78,16 @@ fQIDAQAB
|
||||
$_COOKIE["adminer_version"] = $version["version"]; // doesn't need to send to the browser
|
||||
}
|
||||
}
|
||||
?>
|
||||
<script<?php echo nonce(); ?>>
|
||||
mixin(document.body, {onkeydown: bodyKeydown, onclick: bodyClick<?php
|
||||
echo (isset($_COOKIE["adminer_version"]) ? "" : ", onload: partial(verifyVersion, '$VERSION', '" . js_escape(ME) . "', '" . get_token() . "')"); // $token may be empty in auth.inc.php
|
||||
?>});
|
||||
document.body.className = document.body.className.replace(/ nojs/, ' js');
|
||||
var offlineMessage = '<?php echo js_escape(lang('You are offline.')); ?>';
|
||||
var thousandsSeparator = '<?php echo js_escape(lang(',')); ?>';
|
||||
</script>
|
||||
|
||||
<div id="help" class="jush-<?php echo JUSH; ?> jsonly hidden"></div>
|
||||
<?php echo script("mixin(qs('#help'), {onmouseover: function () { helpOpen = 1; }, onmouseout: helpMouseout});"); ?>
|
||||
|
||||
<div id="content">
|
||||
<?php
|
||||
echo script("mixin(document.body, {onkeydown: bodyKeydown, onclick: bodyClick"
|
||||
. (isset($_COOKIE["adminer_version"]) ? "" : ", onload: partial(verifyVersion, '$VERSION', '" . js_escape(ME) . "', '" . get_token() . "')") // $token may be empty in auth.inc.php
|
||||
. "});
|
||||
document.body.classList.replace('nojs', 'js');
|
||||
const offlineMessage = '" . js_escape(lang('You are offline.')) . "';
|
||||
const thousandsSeparator = '" . js_escape(lang(',')) . "';")
|
||||
;
|
||||
echo "<div id='help' class='jush-" . JUSH . " jsonly hidden'></div>\n";
|
||||
echo script("mixin(qs('#help'), {onmouseover: () => { helpOpen = 1; }, onmouseout: helpMouseout});");
|
||||
echo "<div id='content'>\n";
|
||||
if ($breadcrumb !== null) {
|
||||
$link = substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1);
|
||||
echo '<p id="breadcrumb"><a href="' . h($link ?: ".") . '">' . $drivers[DRIVER] . '</a> » ';
|
||||
@@ -165,6 +180,7 @@ function get_nonce() {
|
||||
* @return null
|
||||
*/
|
||||
function page_messages($error) {
|
||||
global $adminer;
|
||||
$uri = preg_replace('~^[^?]*~', '', $_SERVER["REQUEST_URI"]);
|
||||
$messages = $_SESSION["messages"][$uri];
|
||||
if ($messages) {
|
||||
@@ -174,6 +190,9 @@ function page_messages($error) {
|
||||
if ($error) {
|
||||
echo "<div class='error'>$error</div>\n";
|
||||
}
|
||||
if ($adminer->error) { // separate <div>
|
||||
echo "<div class='error'>$adminer->error</div>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/** Print HTML footer
|
||||
@@ -181,23 +200,20 @@ function page_messages($error) {
|
||||
* @return null
|
||||
*/
|
||||
function page_footer($missing = "") {
|
||||
global $adminer, $token;
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div id="menu">
|
||||
<?php $adminer->navigation($missing); ?>
|
||||
</div>
|
||||
|
||||
<?php if ($missing != "auth") { ?>
|
||||
global $adminer;
|
||||
echo "</div>\n\n<div id='menu'>\n";
|
||||
$adminer->navigation($missing);
|
||||
echo "</div>\n\n";
|
||||
if ($missing != "auth") {
|
||||
?>
|
||||
<form action="" method="post">
|
||||
<p class="logout">
|
||||
<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; ?>">
|
||||
<?php echo input_token(); ?>
|
||||
</p>
|
||||
</form>
|
||||
<?php } ?>
|
||||
<?php
|
||||
}
|
||||
echo script("setupSubmitHighlight(document);");
|
||||
}
|
||||
|
@@ -26,23 +26,23 @@ 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
|
||||
@@ -66,6 +66,13 @@ abstract class SqlDriver {
|
||||
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]
|
||||
@@ -91,7 +98,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);
|
||||
}
|
||||
@@ -135,7 +142,15 @@ abstract class SqlDriver {
|
||||
return queries("INSERT INTO " . table($table) . ($set
|
||||
? " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")"
|
||||
: " DEFAULT VALUES"
|
||||
));
|
||||
) . $this->insertReturning($table));
|
||||
}
|
||||
|
||||
/** Get RETURNING clause for INSERT queries, PostgreSQL specific
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function insertReturning($table) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/** Insert or update data in table
|
||||
@@ -201,8 +216,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)
|
||||
);
|
||||
}
|
||||
@@ -237,6 +252,13 @@ abstract class SqlDriver {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Get supported engines
|
||||
* @return array
|
||||
*/
|
||||
function engines() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/** Check whether table supports indexes
|
||||
* @param array result of table_status()
|
||||
* @return bool
|
||||
|
@@ -25,12 +25,14 @@ function select($result, $connection2 = null, $orgtables = array(), $limit = 0)
|
||||
for ($j=0; $j < count($row); $j++) {
|
||||
$field = $result->fetch_field();
|
||||
$name = $field->name;
|
||||
$orgtable = $field->orgtable;
|
||||
$orgname = $field->orgname;
|
||||
$return[$field->table] = $orgtable;
|
||||
$orgtable = (isset($field->orgtable) ? $field->orgtable : "");
|
||||
$orgname = (isset($field->orgname) ? $field->orgname : $name);
|
||||
if ($orgtables && JUSH == "sql") { // MySQL EXPLAIN
|
||||
$links[$j] = ($name == "table" ? "table=" : ($name == "possible_keys" ? "indexes=" : null));
|
||||
} elseif ($orgtable != "") {
|
||||
if (isset($field->table)) {
|
||||
$return[$field->table] = $orgtable;
|
||||
}
|
||||
if (!isset($indexes[$orgtable])) {
|
||||
// find primary key in each table
|
||||
$indexes[$orgtable] = array();
|
||||
@@ -90,7 +92,8 @@ function select($result, $connection2 = null, $orgtables = array(), $limit = 0)
|
||||
if ($link) {
|
||||
$val = "<a href='" . h($link) . "'" . (is_url($link) ? target_blank() : '') . ">$val</a>";
|
||||
}
|
||||
echo "<td>$val";
|
||||
// https://dev.mysql.com/doc/dev/mysql-server/latest/field__types_8h.html
|
||||
echo "<td" . ($types[$key] <= 9 || $types[$key] == 246 ? " class='number'" : "") . ">$val";
|
||||
}
|
||||
}
|
||||
echo ($i ? "</table>\n</div>" : "<p class='message'>" . lang('No rows.')) . "\n";
|
||||
@@ -119,31 +122,6 @@ function referencable_primary($self) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Get settings stored in a cookie
|
||||
* @return array
|
||||
*/
|
||||
function adminer_settings() {
|
||||
parse_str($_COOKIE["adminer_settings"], $settings);
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/** Get setting stored in a cookie
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
function adminer_setting($key) {
|
||||
$settings = adminer_settings();
|
||||
return $settings[$key];
|
||||
}
|
||||
|
||||
/** Store settings to a cookie
|
||||
* @param array
|
||||
* @return bool
|
||||
*/
|
||||
function set_adminer_settings($settings) {
|
||||
return cookie("adminer_settings", http_build_query($settings + adminer_settings()));
|
||||
}
|
||||
|
||||
/** Print SQL <textarea> tag
|
||||
* @param string
|
||||
* @param string or array in which case [0] of every element is used
|
||||
@@ -209,7 +187,7 @@ function json_row($key, $val = null) {
|
||||
function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_types = array()) {
|
||||
global $driver;
|
||||
$type = $field["type"];
|
||||
?><td><select name="<?php echo h($key); ?>[type]" class="type" aria-labelledby="label-type"><?php
|
||||
echo "<td><select name='" . h($key) . "[type]' class='type' aria-labelledby='label-type'>";
|
||||
if ($type && !array_key_exists($type, $driver->types()) && !isset($foreign_keys[$type]) && !in_array($type, $extra_types)) {
|
||||
$extra_types[] = $type;
|
||||
}
|
||||
@@ -218,19 +196,24 @@ function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_ty
|
||||
$structured_types[lang('Foreign keys')] = $foreign_keys;
|
||||
}
|
||||
echo optionlist(array_merge($extra_types, $structured_types), $type);
|
||||
?></select><td><input
|
||||
name="<?php echo h($key); ?>[length]"
|
||||
value="<?php echo h($field["length"]); ?>"
|
||||
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 "</select><td>";
|
||||
echo "<input name='" . h($key) . "[length]' value='" . h($field["length"]) . "' size='3'"
|
||||
. (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : "") //! type="number" with enabled JavaScript
|
||||
. " aria-labelledby='label-length'>";
|
||||
echo "<td class='options'>";
|
||||
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 +290,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))
|
||||
)
|
||||
));
|
||||
@@ -343,54 +326,49 @@ function type_class($type) {
|
||||
function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = array()) {
|
||||
global $driver;
|
||||
$fields = array_values($fields);
|
||||
$default_class = (($_POST ? $_POST["defaults"] : adminer_setting("defaults")) ? "" : " class='hidden'");
|
||||
$comment_class = (($_POST ? $_POST["comments"] : adminer_setting("comments")) ? "" : " class='hidden'");
|
||||
?>
|
||||
<thead><tr>
|
||||
<?php echo ($type == "PROCEDURE" ? "<td>" : ""); ?>
|
||||
<th id="label-name"><?php echo ($type == "TABLE" ? lang('Column name') : lang('Parameter name')); ?>
|
||||
<td id="label-type"><?php echo lang('Type'); ?><textarea id="enum-edit" rows="4" cols="12" wrap="off" style="display: none;"></textarea><?php echo script("qs('#enum-edit').onblur = editingLengthBlur;"); ?>
|
||||
<td id="label-length"><?php echo lang('Length'); ?>
|
||||
<td><?php echo lang('Options'); /* no label required, options have their own label */ ?>
|
||||
<?php if ($type == "TABLE") { ?>
|
||||
<td id="label-null">NULL
|
||||
<td><input type="radio" name="auto_increment_col" value=""><abbr id="label-ai" title="<?php echo lang('Auto Increment'); ?>">AI</abbr><?php echo doc_link(array(
|
||||
'sql' => "example-auto-increment.html",
|
||||
'mariadb' => "auto_increment/",
|
||||
'sqlite' => "autoinc.html",
|
||||
'pgsql' => "datatype-numeric.html#DATATYPE-SERIAL",
|
||||
'mssql' => "t-sql/statements/create-table-transact-sql-identity-property",
|
||||
)); ?>
|
||||
<td id="label-default"<?php echo $default_class; ?>><?php echo lang('Default value'); ?>
|
||||
<?php echo (support("comment") ? "<td id='label-comment'$comment_class>" . lang('Comment') : ""); ?>
|
||||
<?php } ?>
|
||||
<td><?php echo "<input type='image' class='icon' name='add[" . (support("move_col") ? 0 : count($fields)) . "]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>" . script("row_count = " . count($fields) . ";"); ?>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$default_class = (($_POST ? $_POST["defaults"] : get_setting("defaults")) ? "" : " class='hidden'");
|
||||
$comment_class = (($_POST ? $_POST["comments"] : get_setting("comments")) ? "" : " class='hidden'");
|
||||
echo "<thead><tr>\n";
|
||||
echo ($type == "PROCEDURE" ? "<td>" : "");
|
||||
echo "<th id='label-name'>" . ($type == "TABLE" ? lang('Column name') : lang('Parameter name'));
|
||||
echo "<td id='label-type'>" . lang('Type') . "<textarea id='enum-edit' rows='4' cols='12' wrap='off' style='display: none;'></textarea>" . script("qs('#enum-edit').onblur = editingLengthBlur;");
|
||||
echo "<td id='label-length'>" . lang('Length');
|
||||
echo "<td>" . lang('Options'); // no label required, options have their own label
|
||||
if ($type == "TABLE") {
|
||||
echo "<td id='label-null'>NULL\n";
|
||||
echo "<td><input type='radio' name='auto_increment_col' value=''><abbr id='label-ai' title='" . lang('Auto Increment') . "'>AI</abbr>";
|
||||
echo doc_link(array(
|
||||
'sql' => "example-auto-increment.html",
|
||||
'mariadb' => "auto_increment/",
|
||||
'sqlite' => "autoinc.html",
|
||||
'pgsql' => "datatype-numeric.html#DATATYPE-SERIAL",
|
||||
'mssql' => "t-sql/statements/create-table-transact-sql-identity-property",
|
||||
));
|
||||
echo "<td id='label-default'$default_class>" . lang('Default value');
|
||||
echo (support("comment") ? "<td id='label-comment'$comment_class>" . lang('Comment') : "");
|
||||
}
|
||||
echo "<td><input type='image' class='icon' name='add[" . (support("move_col") ? 0 : count($fields)) . "]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>" . script("row_count = " . count($fields) . ";");
|
||||
echo "</thead>\n<tbody>\n";
|
||||
echo script("mixin(qsl('tbody'), {onclick: editingClick, onkeydown: editingKeydown, oninput: editingInput});");
|
||||
foreach ($fields as $i => $field) {
|
||||
$i++;
|
||||
$orig = $field[($_POST ? "orig" : "field")];
|
||||
$display = (isset($_POST["add"][$i-1]) || (isset($field["field"]) && !$_POST["drop_col"][$i])) && (support("drop_col") || $orig == "");
|
||||
?>
|
||||
<tr<?php echo ($display ? "" : " style='display: none;'"); ?>>
|
||||
<?php echo ($type == "PROCEDURE" ? "<td>" . html_select("fields[$i][inout]", explode("|", $driver->inout), $field["inout"]) : "") . "<th>"; ?>
|
||||
<?php if ($display) { ?>
|
||||
<input name="fields[<?php echo $i; ?>][field]" value="<?php echo h($field["field"]); ?>" data-maxlength="64" autocapitalize="off" aria-labelledby="label-name">
|
||||
<?php } ?>
|
||||
<input type="hidden" name="fields[<?php echo $i; ?>][orig]" value="<?php echo h($orig); ?>"><?php edit_type("fields[$i]", $field, $collations, $foreign_keys); ?>
|
||||
<?php
|
||||
echo "<tr" . ($display ? "" : " style='display: none;'") . ">\n";
|
||||
echo ($type == "PROCEDURE" ? "<td>" . html_select("fields[$i][inout]", explode("|", $driver->inout), $field["inout"]) : "") . "<th>";
|
||||
if ($display) {
|
||||
echo "<input name='fields[$i][field]' value='" . h($field["field"]) . "' data-maxlength='64' autocapitalize='off' aria-labelledby='label-name'>";
|
||||
}
|
||||
echo input_hidden("fields[$i][orig]", $orig);
|
||||
edit_type("fields[$i]", $field, $collations, $foreign_keys);
|
||||
if ($type == "TABLE") {
|
||||
?>
|
||||
<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
|
||||
echo "<td>" . checkbox("fields[$i][null]", 1, $field["null"], "", "", "block", "label-null");
|
||||
echo "<td><label class='block'><input type='radio' name='auto_increment_col' value='$i'" . ($field["auto_increment"] ? " checked" : "") . " aria-labelledby='label-ai'></label>";
|
||||
echo "<td$default_class>" . ($driver->generated
|
||||
? html_select("fields[$i][generated]", array_merge(array("", "DEFAULT"), $driver->generated), $field["generated"]) . " "
|
||||
: checkbox("fields[$i][generated]", 1, $field["generated"], "", "", "", "label-default")
|
||||
);
|
||||
?>
|
||||
<input name="fields[<?php echo $i; ?>][default]" value="<?php echo h($field["default"]); ?>" aria-labelledby="label-default"><?php
|
||||
echo "<input name='fields[$i][default]' value='" . h($field["default"]) . "' aria-labelledby='label-default'>";
|
||||
echo (support("comment") ? "<td$comment_class><input name='fields[$i][comment]' value='" . h($field["comment"]) . "' data-maxlength='" . (min_version(5.5) ? 1024 : 255) . "' aria-labelledby='label-comment'>" : "");
|
||||
}
|
||||
echo "<td>";
|
||||
@@ -620,26 +598,17 @@ function doc_link($paths, $text = "<sup>?</sup>") {
|
||||
$urls = array(
|
||||
'sql' => "https://dev.mysql.com/doc/refman/$version/en/",
|
||||
'sqlite' => "https://www.sqlite.org/",
|
||||
'pgsql' => "https://www.postgresql.org/docs/$version/",
|
||||
'pgsql' => "https://www.postgresql.org/docs/" . ($connection->flavor == 'cockroach' ? "current" : $version) . "/",
|
||||
'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->flavor == '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
|
||||
|
@@ -1,7 +1,10 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
error_reporting(6135); // errors and warnings
|
||||
error_reporting(24575); // all but E_DEPRECATED (overriding mysqli methods without types is deprecated)
|
||||
set_error_handler(function ($errno, $errstr) {
|
||||
return !!preg_match('~^(Trying to access array offset on( value of type)? null|Undefined (array key|property))~', $errstr);
|
||||
}, E_WARNING);
|
||||
// "offset on null" mutes $_GET["fields"][0] if there's no ?fields[]= (62017e3 is a wrong fix for this)
|
||||
// "Undefined array key" mutes $_GET["q"] if there's no ?q=
|
||||
// "Undefined offset" and "Undefined index" are older messages for the same thing
|
||||
return !!preg_match('~^(Trying to access array offset on( value of type)? null|Undefined (array key|offset|index))~', $errstr);
|
||||
}, E_WARNING | E_NOTICE); // warning since PHP 8.0
|
||||
|
@@ -20,6 +20,14 @@ function adminer() {
|
||||
return $adminer;
|
||||
}
|
||||
|
||||
/** Get Driver object
|
||||
* @return Driver
|
||||
*/
|
||||
function driver() {
|
||||
global $driver;
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/** Get Adminer version
|
||||
* @return string
|
||||
*/
|
||||
@@ -40,6 +48,15 @@ function idf_unescape($idf) {
|
||||
return str_replace($last . $last, $last, substr($idf, 1, -1));
|
||||
}
|
||||
|
||||
/** Shortcut for $connection->quote($string)
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function q($string) {
|
||||
global $connection;
|
||||
return $connection->quote($string);
|
||||
}
|
||||
|
||||
/** Escape string to use inside ''
|
||||
* @param string
|
||||
* @return string
|
||||
@@ -122,164 +139,6 @@ function charset($connection) {
|
||||
return (min_version("5.5.3", 0, $connection) ? "utf8mb4" : "utf8"); // SHOW CHARSET would require an extra query
|
||||
}
|
||||
|
||||
/** Return <script> element
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function script($source, $trailing = "\n") {
|
||||
return "<script" . nonce() . ">$source</script>$trailing";
|
||||
}
|
||||
|
||||
/** Return <script src> element
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function script_src($url) {
|
||||
return "<script src='" . h($url) . "'" . nonce() . "></script>\n";
|
||||
}
|
||||
|
||||
/** Get a nonce="" attribute with CSP nonce
|
||||
* @return string
|
||||
*/
|
||||
function nonce() {
|
||||
return ' nonce="' . get_nonce() . '"';
|
||||
}
|
||||
|
||||
/** Get a target="_blank" attribute
|
||||
* @return string
|
||||
*/
|
||||
function target_blank() {
|
||||
return ' target="_blank" rel="noreferrer noopener"';
|
||||
}
|
||||
|
||||
/** Escape for HTML
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function h($string) {
|
||||
return str_replace("\0", "�", htmlspecialchars($string, ENT_QUOTES, 'utf-8'));
|
||||
}
|
||||
|
||||
/** Convert \n to <br>
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function nl_br($string) {
|
||||
return str_replace("\n", "<br>", $string); // nl2br() uses XHTML before PHP 5.3
|
||||
}
|
||||
|
||||
/** Generate HTML checkbox
|
||||
* @param string
|
||||
* @param string
|
||||
* @param bool
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function checkbox($name, $value, $checked, $label = "", $onclick = "", $class = "", $labelled_by = "") {
|
||||
$return = "<input type='checkbox' name='$name' value='" . h($value) . "'"
|
||||
. ($checked ? " checked" : "")
|
||||
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
|
||||
. ">"
|
||||
. ($onclick ? script("qsl('input').onclick = function () { $onclick };", "") : "")
|
||||
;
|
||||
return ($label != "" || $class ? "<label" . ($class ? " class='$class'" : "") . ">$return" . h($label) . "</label>" : $return);
|
||||
}
|
||||
|
||||
/** Generate list of HTML options
|
||||
* @param array array of strings or arrays (creates optgroup)
|
||||
* @param mixed
|
||||
* @param bool always use array keys for value="", otherwise only string keys are used
|
||||
* @return string
|
||||
*/
|
||||
function optionlist($options, $selected = null, $use_keys = false) {
|
||||
$return = "";
|
||||
foreach ($options as $k => $v) {
|
||||
$opts = array($k => $v);
|
||||
if (is_array($v)) {
|
||||
$return .= '<optgroup label="' . h($k) . '">';
|
||||
$opts = $v;
|
||||
}
|
||||
foreach ($opts as $key => $val) {
|
||||
$return .= '<option'
|
||||
. ($use_keys || is_string($key) ? ' value="' . h($key) . '"' : '')
|
||||
. ($selected !== null && ($use_keys || is_string($key) ? (string) $key : $val) === $selected ? ' selected' : '')
|
||||
. '>' . h($val)
|
||||
;
|
||||
}
|
||||
if (is_array($v)) {
|
||||
$return .= '</optgroup>';
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** 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 };", "") : "")
|
||||
;
|
||||
}
|
||||
$return = "";
|
||||
foreach ($options as $key => $val) {
|
||||
$return .= "<label><input type='radio' name='" . h($name) . "' value='" . h($key) . "'" . ($key == $value ? " checked" : "") . ">" . h($val) . "</label>";
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Get onclick confirmation
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function confirm($message = "", $selector = "qsl('input')") {
|
||||
return script("$selector.onclick = function () { return confirm('" . ($message ? js_escape($message) : lang('Are you sure?')) . "'); };", "");
|
||||
}
|
||||
|
||||
/** Print header for hidden fieldset (close by </div></fieldset>)
|
||||
* @param string
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return null
|
||||
*/
|
||||
function print_fieldset($id, $legend, $visible = false) {
|
||||
echo "<fieldset><legend>";
|
||||
echo "<a href='#fieldset-$id'>$legend</a>";
|
||||
echo script("qsl('a').onclick = partial(toggle, 'fieldset-$id');", "");
|
||||
echo "</legend>";
|
||||
echo "<div id='fieldset-$id'" . ($visible ? "" : " class='hidden'") . ">\n";
|
||||
}
|
||||
|
||||
/** Return class='active' if $bold is true
|
||||
* @param bool
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function bold($bold, $class = "") {
|
||||
return ($bold ? " class='active $class'" : ($class ? " class='$class'" : ""));
|
||||
}
|
||||
|
||||
/** Escape string for JavaScript apostrophes
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function js_escape($string) {
|
||||
return addcslashes($string, "\r\n'\\/"); // slash for <script>
|
||||
}
|
||||
|
||||
/** Get INI boolean value
|
||||
* @param string
|
||||
* @return bool
|
||||
@@ -328,15 +187,6 @@ function get_password() {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Shortcut for $connection->quote($string)
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function q($string) {
|
||||
global $connection;
|
||||
return $connection->quote($string);
|
||||
}
|
||||
|
||||
/** Get single value from database
|
||||
* @param string
|
||||
* @param int
|
||||
@@ -452,14 +302,14 @@ 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
|
||||
: " = " . unconvert_field($fields[$key], q($val))
|
||||
)))
|
||||
: (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";
|
||||
}
|
||||
}
|
||||
@@ -529,11 +379,39 @@ function cookie($name, $value, $lifetime = 2592000) {
|
||||
);
|
||||
}
|
||||
|
||||
/** Get settings stored in a cookie
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
function get_settings($cookie) {
|
||||
parse_str($_COOKIE[$cookie], $settings);
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/** Get setting stored in a cookie
|
||||
* @param string
|
||||
* @param string
|
||||
* @return mixed
|
||||
*/
|
||||
function get_setting($key, $cookie = "adminer_settings") {
|
||||
$settings = get_settings($cookie);
|
||||
return $settings[$key];
|
||||
}
|
||||
|
||||
/** Store settings to a cookie
|
||||
* @param array
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
function save_settings($settings, $cookie = "adminer_settings") {
|
||||
return cookie($cookie, http_build_query($settings + get_settings($cookie)));
|
||||
}
|
||||
|
||||
/** Restart stopped session
|
||||
* @return null
|
||||
*/
|
||||
function restart_session() {
|
||||
if (!ini_bool("session.use_cookies")) {
|
||||
if (!ini_bool("session.use_cookies") && (!function_exists('session_status') || session_status() == 1)) { // 1 - PHP_SESSION_NONE, session_status() available since PHP 5.4
|
||||
session_start();
|
||||
}
|
||||
}
|
||||
@@ -578,10 +456,17 @@ function set_session($key, $val) {
|
||||
*/
|
||||
function auth_url($vendor, $server, $username, $db = null) {
|
||||
global $drivers;
|
||||
preg_match('~([^?]*)\??(.*)~', remove_from_uri(implode("|", array_keys($drivers)) . "|username|" . ($db !== null ? "db|" : "") . session_name()), $match);
|
||||
$uri = remove_from_uri(implode("|", array_keys($drivers))
|
||||
. "|username|ext|"
|
||||
. ($db !== null ? "db|" : "")
|
||||
. ($vendor == 'mssql' || $vendor == 'pgsql' ? "" : "ns|") // we don't have access to support() here
|
||||
. session_name())
|
||||
;
|
||||
preg_match('~([^?]*)\??(.*)~', $uri, $match);
|
||||
return "$match[1]?"
|
||||
. (sid() ? SID . "&" : "")
|
||||
. ($vendor != "server" || $server != "" ? urlencode($vendor) . "=" . urlencode($server) . "&" : "")
|
||||
. ($_GET["ext"] ? "ext=" . urlencode($_GET["ext"]) . "&" : "")
|
||||
. "username=" . urlencode($username)
|
||||
. ($db != "" ? "&db=" . urlencode($db) : "")
|
||||
. ($match[2] ? "&$match[2]" : "")
|
||||
@@ -713,24 +598,13 @@ function remove_from_uri($param = "") {
|
||||
return substr(preg_replace("~(?<=[?&])($param" . (SID ? "" : "|" . session_name()) . ")=[^&]*&~", '', relative_uri() . "&"), 0, -1);
|
||||
}
|
||||
|
||||
/** Generate page number for pagination
|
||||
* @param int
|
||||
* @param int
|
||||
* @return string
|
||||
*/
|
||||
function pagination($page, $current) {
|
||||
return " " . ($page == $current
|
||||
? $page + 1
|
||||
: '<a href="' . h(remove_from_uri("page") . ($page ? "&page=$page" . ($_GET["next"] ? "&next=" . urlencode($_GET["next"]) : "") : "")) . '">' . ($page + 1) . "</a>"
|
||||
);
|
||||
}
|
||||
|
||||
/** Get file contents from $_FILES
|
||||
* @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;
|
||||
@@ -752,17 +626,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;
|
||||
}
|
||||
|
||||
@@ -824,36 +698,6 @@ function friendly_url($val) {
|
||||
return preg_replace('~\W~i', '-', $val);
|
||||
}
|
||||
|
||||
/** Print hidden fields
|
||||
* @param array
|
||||
* @param array
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
function hidden_fields($process, $ignore = array(), $prefix = '') {
|
||||
$return = false;
|
||||
foreach ($process as $key => $val) {
|
||||
if (!in_array($key, $ignore)) {
|
||||
if (is_array($val)) {
|
||||
hidden_fields($val, array(), $key);
|
||||
} else {
|
||||
$return = true;
|
||||
echo '<input type="hidden" name="' . h($prefix ? $prefix . "[$key]" : $key) . '" value="' . h($val) . '">';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Print hidden fields for GET forms
|
||||
* @return null
|
||||
*/
|
||||
function hidden_fields_get() {
|
||||
echo (sid() ? '<input type="hidden" name="' . session_name() . '" value="' . h(session_id()) . '">' : '');
|
||||
echo (SERVER !== null ? '<input type="hidden" name="' . DRIVER . '" value="' . h(SERVER) . '">' : "");
|
||||
echo '<input type="hidden" name="username" value="' . h($_GET["username"]) . '">';
|
||||
}
|
||||
|
||||
/** Get status of a single table and fall back to name on error
|
||||
* @param string
|
||||
* @param bool
|
||||
@@ -879,179 +723,6 @@ function column_foreign_keys($table) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Print enum input field
|
||||
* @param string "radio"|"checkbox"
|
||||
* @param string
|
||||
* @param array
|
||||
* @param mixed int|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>" : "");
|
||||
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>';
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Print edit input field
|
||||
* @param array one field from fields()
|
||||
* @param mixed
|
||||
* @param string
|
||||
* @return null
|
||||
*/
|
||||
function input($field, $value, $function) {
|
||||
global $driver, $adminer;
|
||||
$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
|
||||
$function = "json";
|
||||
}
|
||||
$reset = (JUSH == "mssql" && $field["auto_increment"]);
|
||||
if ($reset && !$_POST["save"]) {
|
||||
$function = null;
|
||||
}
|
||||
$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";
|
||||
$enums = $driver->enumLength($field);
|
||||
if ($enums) {
|
||||
$field["type"] = "enum";
|
||||
$field["length"] = $enums;
|
||||
}
|
||||
if ($field["type"] == "enum") {
|
||||
echo h($functions[""]) . "<td>" . $adminer->editInput($_GET["edit"], $field, $attrs, $value);
|
||||
} else {
|
||||
$has_function = (in_array($function, $functions) || isset($functions[$function]));
|
||||
echo (count($functions) > 1
|
||||
? "<select name='function[$name]'$disabled>" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>"
|
||||
. on_help("getTarget(event).value.replace(/^SQL\$/, '')", 1)
|
||||
. script("qsl('select').onchange = functionChange;", "")
|
||||
: h(reset($functions))
|
||||
) . '<td>';
|
||||
$input = $adminer->editInput($_GET["edit"], $field, $attrs, $value); // usage in call is without a table
|
||||
if ($input != "") {
|
||||
echo $input;
|
||||
} 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
|
||||
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>';
|
||||
}
|
||||
} elseif (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
|
||||
echo "<input type='file' name='fields-$name'>";
|
||||
} elseif (($text = preg_match('~text|lob|memo~i', $field["type"])) || preg_match("~\n~", $value)) {
|
||||
if ($text && JUSH != "sqlite") {
|
||||
$attrs .= " cols='50' rows='12'";
|
||||
} else {
|
||||
$rows = min(12, substr_count($value, "\n") + 1);
|
||||
$attrs .= " cols='30' rows='$rows'" . ($rows == 1 ? " style='height: 1.2em;'" : ""); // 1.2em - line-height
|
||||
}
|
||||
echo "<textarea$attrs>" . h($value) . '</textarea>';
|
||||
} elseif ($function == "json" || preg_match('~^jsonb?$~', $field["type"])) {
|
||||
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)
|
||||
);
|
||||
if (JUSH == 'sql' && min_version(5.6) && preg_match('~time~', $field["type"])) {
|
||||
$maxlength += 7; // microtime
|
||||
}
|
||||
// type='date' and type='time' display localized value which may be confusing, type='datetime' uses 'T' as date and time separator
|
||||
echo "<input"
|
||||
. ((!$has_function || $function === "") && preg_match('~(?<!o)int(?!er)~', $field["type"]) && !preg_match('~\[\]~', $field["full_type"]) ? " type='number'" : "")
|
||||
. " value='" . h($value) . "'" . ($maxlength ? " data-maxlength='$maxlength'" : "")
|
||||
. (preg_match('~char|binary~', $field["type"]) && $maxlength > 20 ? " size='40'" : "")
|
||||
. "$attrs>"
|
||||
;
|
||||
}
|
||||
echo $adminer->editHint($_GET["edit"], $field, $value);
|
||||
// skip 'original'
|
||||
$first = 0;
|
||||
foreach ($functions as $key => $val) {
|
||||
if ($key === "" || !$val) {
|
||||
break;
|
||||
}
|
||||
$first++;
|
||||
}
|
||||
if ($first) {
|
||||
echo script("mixin(qsl('td'), {onchange: partial(skipOriginal, $first), oninput: function () { this.onchange(); }});");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Process edit input field
|
||||
* @param one field from fields()
|
||||
* @return string or false to leave the original value
|
||||
*/
|
||||
function process_input($field) {
|
||||
global $adminer, $driver;
|
||||
|
||||
if (stripos($field["default"], "GENERATED ALWAYS AS ") === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$idf = bracket_escape($field["field"]);
|
||||
$function = $_POST["function"][$idf];
|
||||
$value = $_POST["fields"][$idf];
|
||||
if ($field["type"] == "enum" || $driver->enumLength($field)) {
|
||||
if ($value == -1) {
|
||||
return false;
|
||||
}
|
||||
if ($value == "") {
|
||||
return "NULL";
|
||||
}
|
||||
}
|
||||
if ($field["type"] == "enum") {
|
||||
return +$value;
|
||||
}
|
||||
if ($field["auto_increment"] && $value == "") {
|
||||
return null;
|
||||
}
|
||||
if ($function == "orig") {
|
||||
return (preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"]) ? idf_escape($field["field"]) : false);
|
||||
}
|
||||
if ($function == "NULL") {
|
||||
return "NULL";
|
||||
}
|
||||
if ($field["type"] == "set") {
|
||||
return array_sum((array) $value);
|
||||
}
|
||||
if ($function == "json") {
|
||||
$function = "";
|
||||
$value = json_decode($value, true);
|
||||
if (!is_array($value)) {
|
||||
return false; //! report errors
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
if (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
|
||||
$file = get_file("fields-$idf");
|
||||
if (!is_string($file)) {
|
||||
return false; //! report errors
|
||||
}
|
||||
return $driver->quoteBinary($file);
|
||||
}
|
||||
return $adminer->processInput($field, $value, $function);
|
||||
}
|
||||
|
||||
/** Compute fields() from $_POST edit data
|
||||
* @return array
|
||||
*/
|
||||
@@ -1077,29 +748,6 @@ function fields_from_edit() {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Print results of search in all tables
|
||||
* @uses $_GET["where"][0]
|
||||
* @uses $_POST["tables"]
|
||||
* @return null
|
||||
*/
|
||||
function search_tables() {
|
||||
global $adminer, $connection;
|
||||
$_GET["where"][0]["val"] = $_POST["query"];
|
||||
$sep = "<ul>\n";
|
||||
foreach (table_status('', true) as $table => $table_status) {
|
||||
$name = $adminer->tableName($table_status);
|
||||
if (isset($table_status["Engine"]) && $name != "" && (!$_POST["tables"] || in_array($table, $_POST["tables"]))) {
|
||||
$result = $connection->query("SELECT" . limit("1 FROM " . table($table), " WHERE " . implode(" AND ", $adminer->selectSearchProcess(fields($table), array())), 1));
|
||||
if (!$result || $result->fetch_row()) {
|
||||
$print = "<a href='" . h(ME . "select=" . urlencode($table) . "&where[0][op]=" . urlencode($_GET["where"][0]["op"]) . "&where[0][val]=" . urlencode($_GET["where"][0]["val"])) . "'>$name</a>";
|
||||
echo "$sep<li>" . ($result ? $print : "<p class='error'>$print: " . error()) . "\n";
|
||||
$sep = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
echo ($sep ? "<p class='message'>" . lang('No tables.') : "</ul>") . "\n";
|
||||
}
|
||||
|
||||
/** Send headers for export
|
||||
* @param string
|
||||
* @param bool
|
||||
@@ -1113,6 +761,9 @@ function dump_headers($identifier, $multi_table = false) {
|
||||
header("Content-Disposition: attachment; filename=" . $adminer->dumpFilename($identifier) . ".$return" . ($output != "file" && preg_match('~^[0-9a-z]+$~', $output) ? ".$output" : ""));
|
||||
}
|
||||
session_write_close();
|
||||
if (!ob_get_level()) {
|
||||
ob_start(null, 4096);
|
||||
}
|
||||
ob_flush();
|
||||
flush();
|
||||
return $return;
|
||||
@@ -1165,15 +816,18 @@ function get_temp_dir() {
|
||||
* @return resource or null for error
|
||||
*/
|
||||
function file_open_lock($filename) {
|
||||
$fp = @fopen($filename, "r+"); // @ - may not exist
|
||||
if (!$fp) { // c+ is available since PHP 5.2.6
|
||||
$fp = @fopen($filename, "w"); // @ - may not be writable
|
||||
if (!$fp) {
|
||||
return;
|
||||
}
|
||||
chmod($filename, 0660);
|
||||
if (is_link($filename)) {
|
||||
return; // https://cwe.mitre.org/data/definitions/61.html
|
||||
}
|
||||
$fp = @fopen($filename, "c+"); // @ - may not be writable
|
||||
if (!$fp) {
|
||||
return;
|
||||
}
|
||||
chmod($filename, 0660);
|
||||
if (!flock($fp, LOCK_EX)) {
|
||||
fclose($fp);
|
||||
return;
|
||||
}
|
||||
flock($fp, LOCK_EX);
|
||||
return $fp;
|
||||
}
|
||||
|
||||
@@ -1185,26 +839,45 @@ function file_write_unlock($fp, $data) {
|
||||
rewind($fp);
|
||||
fwrite($fp, $data);
|
||||
ftruncate($fp, strlen($data));
|
||||
file_unlock($fp);
|
||||
}
|
||||
|
||||
/** Unlock and close a file
|
||||
* @param resource
|
||||
*/
|
||||
function file_unlock($fp) {
|
||||
flock($fp, LOCK_UN);
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
/** Get first element of an array
|
||||
* @param array
|
||||
* @return mixed or false if not found
|
||||
*/
|
||||
function first($array) {
|
||||
// reset(f()) triggers a notice
|
||||
return reset($array);
|
||||
}
|
||||
|
||||
/** Read password from file adminer.key in temporary directory or create one
|
||||
* @param bool
|
||||
* @return string or false if the file can not be created
|
||||
*/
|
||||
function password_file($create) {
|
||||
$filename = get_temp_dir() . "/adminer.key";
|
||||
$return = @file_get_contents($filename); // @ - may not exist
|
||||
if ($return || !$create) {
|
||||
return $return;
|
||||
if (!$create && !file_exists($filename)) {
|
||||
return false;
|
||||
}
|
||||
$fp = @fopen($filename, "w"); // @ - can have insufficient rights //! is not atomic
|
||||
if ($fp) {
|
||||
chmod($filename, 0660);
|
||||
$fp = file_open_lock($filename);
|
||||
if (!$fp) {
|
||||
return false;
|
||||
}
|
||||
$return = stream_get_contents($fp);
|
||||
if (!$return) {
|
||||
$return = rand_string();
|
||||
fwrite($fp, $return);
|
||||
fclose($fp);
|
||||
file_write_unlock($fp, $return);
|
||||
} else {
|
||||
file_unlock($fp);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
@@ -1314,14 +987,7 @@ function slow_query($query) {
|
||||
$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
|
||||
?>
|
||||
<script<?php echo nonce(); ?>>
|
||||
var timeout = setTimeout(function () {
|
||||
ajax('<?php echo js_escape(ME); ?>script=kill', function () {
|
||||
}, 'kill=<?php echo $kill; ?>&token=<?php echo $token; ?>');
|
||||
}, <?php echo 1000 * $timeout; ?>);
|
||||
</script>
|
||||
<?php
|
||||
echo script("const timeout = setTimeout(() => { ajax('" . js_escape(ME) . "script=kill', function () {}, 'kill=$kill&token=$token'); }, 1000 * $timeout);");
|
||||
}
|
||||
ob_flush();
|
||||
flush();
|
||||
@@ -1387,123 +1053,3 @@ function lzw_decompress($binary) {
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Return events to display help on mouse over
|
||||
* @param string JS expression
|
||||
* @param bool JS expression
|
||||
* @return string
|
||||
*/
|
||||
function on_help($command, $side = 0) {
|
||||
return script("mixin(qsl('select, input'), {onmouseover: function (event) { helpMouseover.call(this, event, $command, $side) }, onmouseout: helpMouseout});", "");
|
||||
}
|
||||
|
||||
/** Print edit data form
|
||||
* @param string
|
||||
* @param array
|
||||
* @param mixed
|
||||
* @param bool
|
||||
* @return null
|
||||
*/
|
||||
function edit_form($table, $fields, $row, $update) {
|
||||
global $adminer, $token, $error;
|
||||
$table_name = $adminer->tableName(table_status1($table, true));
|
||||
page_header(
|
||||
($update ? lang('Edit') : lang('Insert')),
|
||||
$error,
|
||||
array("select" => array($table, $table_name)),
|
||||
$table_name
|
||||
);
|
||||
$adminer->editRowPrint($table, $fields, $row, $update);
|
||||
if ($row === false) {
|
||||
echo "<p class='error'>" . lang('No rows.') . "\n";
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<form action="" method="post" enctype="multipart/form-data" id="form">
|
||||
<?php
|
||||
$first = 0;
|
||||
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;");
|
||||
foreach ($fields as $name => $field) {
|
||||
echo "<tr><th>" . $adminer->fieldName($field);
|
||||
$default = $_GET["set"][bracket_escape($name)];
|
||||
if ($default === null) {
|
||||
$default = $field["default"];
|
||||
if ($field["type"] == "bit" && preg_match("~^b'([01]*)'\$~", $default, $regs)) {
|
||||
$default = $regs[1];
|
||||
}
|
||||
}
|
||||
$value = ($row !== null
|
||||
? ($row[$name] != "" && JUSH == "sql" && preg_match("~enum|set~", $field["type"])
|
||||
? (is_array($row[$name]) ? array_sum($row[$name]) : +$row[$name])
|
||||
: (is_bool($row[$name]) ? +$row[$name] : $row[$name])
|
||||
)
|
||||
: (!$update && $field["auto_increment"]
|
||||
? ""
|
||||
: (isset($_GET["select"]) ? false : $default)
|
||||
)
|
||||
);
|
||||
if (!$_POST["save"] && is_string($value)) {
|
||||
$value = $adminer->editVal($value, $field);
|
||||
}
|
||||
$function = ($_POST["save"]
|
||||
? (string) $_POST["function"][$name]
|
||||
: ($update && preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"])
|
||||
? "now"
|
||||
: ($value === false ? null : ($value !== null ? '' : 'NULL'))
|
||||
)
|
||||
);
|
||||
if (!$_POST && !$update && $value == $field["default"] && preg_match('~^[\w.]+\(~', $value)) {
|
||||
$function = "SQL";
|
||||
}
|
||||
if (preg_match("~time~", $field["type"]) && preg_match('~^CURRENT_TIMESTAMP~i', $value)) {
|
||||
$value = "";
|
||||
$function = "now";
|
||||
}
|
||||
if ($field["type"] == "uuid" && $value == "uuid()") {
|
||||
$value = "";
|
||||
$function = "uuid";
|
||||
}
|
||||
if ($field["auto_increment"] || $function == "now" || $function == "uuid") {
|
||||
$first++;
|
||||
}
|
||||
input($field, $value, $function);
|
||||
echo "\n";
|
||||
}
|
||||
if (!support("table")) {
|
||||
echo "<tr>"
|
||||
. "<th><input name='field_keys[]'>"
|
||||
. script("qsl('input').oninput = fieldChange;")
|
||||
. "<td class='function'>" . html_select("field_funs[]", $adminer->editFunctions(array("null" => isset($_GET["select"]))))
|
||||
. "<td><input name='field_vals[]'>"
|
||||
. "\n"
|
||||
;
|
||||
}
|
||||
echo "</table>\n";
|
||||
}
|
||||
echo "<p>\n";
|
||||
if ($fields) {
|
||||
echo "<input type='submit' value='" . lang('Save') . "'>\n";
|
||||
if (!isset($_GET["select"])) {
|
||||
echo "<input type='submit' name='insert' value='" . ($update
|
||||
? lang('Save and continue edit')
|
||||
: lang('Save and insert next')
|
||||
) . "' title='Ctrl+Shift+Enter'>\n";
|
||||
echo ($update ? script("qsl('input').onclick = function () { return !ajaxForm(this.form, '" . lang('Saving') . "…', this); };") : "");
|
||||
}
|
||||
}
|
||||
echo ($update ? "<input type='submit' name='delete' value='" . lang('Delete') . "'>" . confirm() . "\n"
|
||||
: ($_POST || !$fields ? "" : script("focus(qsa('td', qs('#form'))[2*$first+1].firstChild);"))
|
||||
);
|
||||
if (isset($_GET["select"])) {
|
||||
hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"]));
|
||||
}
|
||||
?>
|
||||
<input type="hidden" name="referer" value="<?php echo h(isset($_POST["referer"]) ? $_POST["referer"] : $_SERVER["HTTP_REFERER"]); ?>">
|
||||
<input type="hidden" name="save" value="1">
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
536
adminer/include/html.inc.php
Normal file
536
adminer/include/html.inc.php
Normal file
@@ -0,0 +1,536 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
/** Return <script> element
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function script($source, $trailing = "\n") {
|
||||
return "<script" . nonce() . ">$source</script>$trailing";
|
||||
}
|
||||
|
||||
/** Return <script src> element
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function script_src($url) {
|
||||
return "<script src='" . h($url) . "'" . nonce() . "></script>\n";
|
||||
}
|
||||
|
||||
/** Get a nonce="" attribute with CSP nonce
|
||||
* @return string
|
||||
*/
|
||||
function nonce() {
|
||||
return ' nonce="' . get_nonce() . '"';
|
||||
}
|
||||
|
||||
/** Get <input type="hidden">
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string HTML
|
||||
*/
|
||||
function input_hidden($name, $value = "") {
|
||||
return "<input type='hidden' name='" . h($name) . "' value='" . h($value) . "'>\n";
|
||||
}
|
||||
|
||||
/** Get <input type="hidden" name="token">
|
||||
* @param string token to use instead of global $token
|
||||
* @return string HTML
|
||||
*/
|
||||
function input_token($special = "") {
|
||||
global $token;
|
||||
return input_hidden("token", ($special ?: $token));
|
||||
}
|
||||
|
||||
/** Get a target="_blank" attribute
|
||||
* @return string
|
||||
*/
|
||||
function target_blank() {
|
||||
return ' target="_blank" rel="noreferrer noopener"';
|
||||
}
|
||||
|
||||
/** Escape for HTML
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function h($string) {
|
||||
return str_replace("\0", "�", htmlspecialchars($string, ENT_QUOTES, 'utf-8'));
|
||||
}
|
||||
|
||||
/** Convert \n to <br>
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function nl_br($string) {
|
||||
return str_replace("\n", "<br>", $string); // nl2br() uses XHTML before PHP 5.3
|
||||
}
|
||||
|
||||
/** Generate HTML checkbox
|
||||
* @param string
|
||||
* @param string
|
||||
* @param bool
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function checkbox($name, $value, $checked, $label = "", $onclick = "", $class = "", $labelled_by = "") {
|
||||
$return = "<input type='checkbox' name='$name' value='" . h($value) . "'"
|
||||
. ($checked ? " checked" : "")
|
||||
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
|
||||
. ">"
|
||||
. ($onclick ? script("qsl('input').onclick = function () { $onclick };", "") : "")
|
||||
;
|
||||
return ($label != "" || $class ? "<label" . ($class ? " class='$class'" : "") . ">$return" . h($label) . "</label>" : $return);
|
||||
}
|
||||
|
||||
/** Generate list of HTML options
|
||||
* @param array array of strings or arrays (creates optgroup)
|
||||
* @param mixed
|
||||
* @param bool always use array keys for value="", otherwise only string keys are used
|
||||
* @return string
|
||||
*/
|
||||
function optionlist($options, $selected = null, $use_keys = false) {
|
||||
$return = "";
|
||||
foreach ($options as $k => $v) {
|
||||
$opts = array($k => $v);
|
||||
if (is_array($v)) {
|
||||
$return .= '<optgroup label="' . h($k) . '">';
|
||||
$opts = $v;
|
||||
}
|
||||
foreach ($opts as $key => $val) {
|
||||
$return .= '<option'
|
||||
. ($use_keys || is_string($key) ? ' value="' . h($key) . '"' : '')
|
||||
. ($selected !== null && ($use_keys || is_string($key) ? (string) $key : $val) === $selected ? ' selected' : '')
|
||||
. '>' . h($val)
|
||||
;
|
||||
}
|
||||
if (is_array($v)) {
|
||||
$return .= '</optgroup>';
|
||||
}
|
||||
}
|
||||
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
|
||||
* @return string
|
||||
*/
|
||||
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>";
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Get onclick confirmation
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function confirm($message = "", $selector = "qsl('input')") {
|
||||
return script("$selector.onclick = () => confirm('" . ($message ? js_escape($message) : lang('Are you sure?')) . "');", "");
|
||||
}
|
||||
|
||||
/** Print header for hidden fieldset (close by </div></fieldset>)
|
||||
* @param string
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return null
|
||||
*/
|
||||
function print_fieldset($id, $legend, $visible = false) {
|
||||
echo "<fieldset><legend>";
|
||||
echo "<a href='#fieldset-$id'>$legend</a>";
|
||||
echo script("qsl('a').onclick = partial(toggle, 'fieldset-$id');", "");
|
||||
echo "</legend>";
|
||||
echo "<div id='fieldset-$id'" . ($visible ? "" : " class='hidden'") . ">\n";
|
||||
}
|
||||
|
||||
/** Return class='active' if $bold is true
|
||||
* @param bool
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function bold($bold, $class = "") {
|
||||
return ($bold ? " class='active $class'" : ($class ? " class='$class'" : ""));
|
||||
}
|
||||
|
||||
/** Escape string for JavaScript apostrophes
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function js_escape($string) {
|
||||
return addcslashes($string, "\r\n'\\/"); // slash for <script>
|
||||
}
|
||||
|
||||
/** Generate page number for pagination
|
||||
* @param int
|
||||
* @param int
|
||||
* @return string
|
||||
*/
|
||||
function pagination($page, $current) {
|
||||
return " " . ($page == $current
|
||||
? $page + 1
|
||||
: '<a href="' . h(remove_from_uri("page") . ($page ? "&page=$page" . ($_GET["next"] ? "&next=" . urlencode($_GET["next"]) : "") : "")) . '">' . ($page + 1) . "</a>"
|
||||
);
|
||||
}
|
||||
|
||||
/** Print hidden fields
|
||||
* @param array
|
||||
* @param array
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
function hidden_fields($process, $ignore = array(), $prefix = '') {
|
||||
$return = false;
|
||||
foreach ($process as $key => $val) {
|
||||
if (!in_array($key, $ignore)) {
|
||||
if (is_array($val)) {
|
||||
hidden_fields($val, array(), $key);
|
||||
} else {
|
||||
$return = true;
|
||||
echo input_hidden(($prefix ? $prefix . "[$key]" : $key), $val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Print hidden fields for GET forms
|
||||
* @return null
|
||||
*/
|
||||
function hidden_fields_get() {
|
||||
echo (sid() ? input_hidden(session_name(), session_id()) : '');
|
||||
echo (SERVER !== null ? input_hidden(DRIVER, SERVER) : "");
|
||||
echo input_hidden("username", $_GET["username"]);
|
||||
}
|
||||
|
||||
/** Print enum or set input field
|
||||
* @param string "radio"|"checkbox"
|
||||
* @param string
|
||||
* @param 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 === $empty) ? " checked" : "") . "><i>" . lang('empty') . "</i></label>" : "");
|
||||
foreach ($matches[1] as $i => $val) {
|
||||
$val = stripcslashes(str_replace("''", "'", $val));
|
||||
$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;
|
||||
}
|
||||
|
||||
/** Print edit input field
|
||||
* @param array one field from fields()
|
||||
* @param mixed
|
||||
* @param string
|
||||
* @param bool
|
||||
* @return null
|
||||
*/
|
||||
function input($field, $value, $function, $autofocus = false) {
|
||||
global $driver, $adminer;
|
||||
$name = h(bracket_escape($field["field"]));
|
||||
echo "<td class='function'>";
|
||||
if (is_array($value) && !$function) {
|
||||
$value = json_encode($value, 128 | 64 | 256); // 128 - JSON_PRETTY_PRINT, 64 - JSON_UNESCAPED_SLASHES, 256 - JSON_UNESCAPED_UNICODE available since PHP 5.4
|
||||
$function = "json";
|
||||
}
|
||||
$reset = (JUSH == "mssql" && $field["auto_increment"]);
|
||||
if ($reset && !$_POST["save"]) {
|
||||
$function = null;
|
||||
}
|
||||
$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" . ($autofocus ? " autofocus" : "");
|
||||
$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 {
|
||||
$has_function = (in_array($function, $functions) || isset($functions[$function]));
|
||||
echo (count($functions) > 1
|
||||
? "<select name='function[$name]'$disabled>" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>"
|
||||
. on_help("event.target.value.replace(/^SQL\$/, '')", 1)
|
||||
. script("qsl('select').onchange = functionChange;", "")
|
||||
: h(reset($functions))
|
||||
) . '<td>';
|
||||
$input = $adminer->editInput($_GET["edit"], $field, $attrs, $value); // usage in call is without a table
|
||||
if ($input != "") {
|
||||
echo $input;
|
||||
} 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") {
|
||||
preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
|
||||
foreach ($matches[1] as $i => $val) {
|
||||
$val = stripcslashes(str_replace("''", "'", $val));
|
||||
$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'>";
|
||||
} elseif ($function == "json" || preg_match('~^jsonb?$~', $field["type"])) {
|
||||
echo "<textarea$attrs cols='50' rows='12' class='jush-js'>" . h($value) . '</textarea>';
|
||||
} elseif (($text = preg_match('~text|lob|memo~i', $field["type"])) || preg_match("~\n~", $value)) {
|
||||
if ($text && JUSH != "sqlite") {
|
||||
$attrs .= " cols='50' rows='12'";
|
||||
} else {
|
||||
$rows = min(12, substr_count($value, "\n") + 1);
|
||||
$attrs .= " cols='30' rows='$rows'";
|
||||
}
|
||||
echo "<textarea$attrs>" . 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)
|
||||
);
|
||||
if (JUSH == 'sql' && min_version(5.6) && preg_match('~time~', $field["type"])) {
|
||||
$maxlength += 7; // microtime
|
||||
}
|
||||
// type='date' and type='time' display localized value which may be confusing, type='datetime' uses 'T' as date and time separator
|
||||
echo "<input"
|
||||
. ((!$has_function || $function === "") && preg_match('~(?<!o)int(?!er)~', $field["type"]) && !preg_match('~\[\]~', $field["full_type"]) ? " type='number'" : "")
|
||||
. " value='" . h($value) . "'" . ($maxlength ? " data-maxlength='$maxlength'" : "")
|
||||
. (preg_match('~char|binary~', $field["type"]) && $maxlength > 20 ? " size='" . ($maxlength > 99 ? 60 : 40) . "'" : "")
|
||||
. "$attrs>"
|
||||
;
|
||||
}
|
||||
echo $adminer->editHint($_GET["edit"], $field, $value);
|
||||
// skip 'original'
|
||||
$first = 0;
|
||||
foreach ($functions as $key => $val) {
|
||||
if ($key === "" || !$val) {
|
||||
break;
|
||||
}
|
||||
$first++;
|
||||
}
|
||||
if ($first && count($functions) > 1) {
|
||||
echo script("qsl('td').oninput = partial(skipOriginal, $first);");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Process edit input field
|
||||
* @param one field from fields()
|
||||
* @return string or false to leave the original value
|
||||
*/
|
||||
function process_input($field) {
|
||||
global $adminer, $driver;
|
||||
if (stripos($field["default"], "GENERATED ALWAYS AS ") === 0) {
|
||||
return null;
|
||||
}
|
||||
$idf = bracket_escape($field["field"]);
|
||||
$function = $_POST["function"][$idf];
|
||||
$value = $_POST["fields"][$idf];
|
||||
if ($field["type"] == "enum" || $driver->enumLength($field)) {
|
||||
if ($value == -1) {
|
||||
return false;
|
||||
}
|
||||
if ($value == "") {
|
||||
return "NULL";
|
||||
}
|
||||
}
|
||||
if ($field["auto_increment"] && $value == "") {
|
||||
return null;
|
||||
}
|
||||
if ($function == "orig") {
|
||||
return (preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"]) ? idf_escape($field["field"]) : false);
|
||||
}
|
||||
if ($function == "NULL") {
|
||||
return "NULL";
|
||||
}
|
||||
if ($field["type"] == "set") {
|
||||
$value = implode(",", (array) $value);
|
||||
}
|
||||
if ($function == "json") {
|
||||
$function = "";
|
||||
$value = json_decode($value, true);
|
||||
if (!is_array($value)) {
|
||||
return false; //! report errors
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
if (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
|
||||
$file = get_file("fields-$idf");
|
||||
if (!is_string($file)) {
|
||||
return false; //! report errors
|
||||
}
|
||||
return $driver->quoteBinary($file);
|
||||
}
|
||||
return $adminer->processInput($field, $value, $function);
|
||||
}
|
||||
|
||||
/** Print results of search in all tables
|
||||
* @uses $_GET["where"][0]
|
||||
* @uses $_POST["tables"]
|
||||
* @return null
|
||||
*/
|
||||
function search_tables() {
|
||||
global $adminer, $connection;
|
||||
$_GET["where"][0]["val"] = $_POST["query"];
|
||||
$sep = "<ul>\n";
|
||||
foreach (table_status('', true) as $table => $table_status) {
|
||||
$name = $adminer->tableName($table_status);
|
||||
if (isset($table_status["Engine"]) && $name != "" && (!$_POST["tables"] || in_array($table, $_POST["tables"]))) {
|
||||
$result = $connection->query("SELECT" . limit("1 FROM " . table($table), " WHERE " . implode(" AND ", $adminer->selectSearchProcess(fields($table), array())), 1));
|
||||
if (!$result || $result->fetch_row()) {
|
||||
$print = "<a href='" . h(ME . "select=" . urlencode($table) . "&where[0][op]=" . urlencode($_GET["where"][0]["op"]) . "&where[0][val]=" . urlencode($_GET["where"][0]["val"])) . "'>$name</a>";
|
||||
echo "$sep<li>" . ($result ? $print : "<p class='error'>$print: " . error()) . "\n";
|
||||
$sep = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
echo ($sep ? "<p class='message'>" . lang('No tables.') : "</ul>") . "\n";
|
||||
}
|
||||
|
||||
/** Return events to display help on mouse over
|
||||
* @param string JS expression
|
||||
* @param bool JS expression
|
||||
* @return string
|
||||
*/
|
||||
function on_help($command, $side = 0) {
|
||||
return script("mixin(qsl('select, input'), {onmouseover: function (event) { helpMouseover.call(this, event, $command, $side) }, onmouseout: helpMouseout});", "");
|
||||
}
|
||||
|
||||
/** Print edit data form
|
||||
* @param string
|
||||
* @param array
|
||||
* @param mixed
|
||||
* @param bool
|
||||
* @return null
|
||||
*/
|
||||
function edit_form($table, $fields, $row, $update) {
|
||||
global $adminer, $error;
|
||||
$table_name = $adminer->tableName(table_status1($table, true));
|
||||
page_header(
|
||||
($update ? lang('Edit') : lang('Insert')),
|
||||
$error,
|
||||
array("select" => array($table, $table_name)),
|
||||
$table_name
|
||||
);
|
||||
$adminer->editRowPrint($table, $fields, $row, $update);
|
||||
if ($row === false) {
|
||||
echo "<p class='error'>" . lang('No rows.') . "\n";
|
||||
return;
|
||||
}
|
||||
echo "<form action='' method='post' enctype='multipart/form-data' id='form'>\n";
|
||||
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;");
|
||||
$autofocus = !$_POST;
|
||||
foreach ($fields as $name => $field) {
|
||||
echo "<tr><th>" . $adminer->fieldName($field);
|
||||
$default = $_GET["set"][bracket_escape($name)];
|
||||
if ($default === null) {
|
||||
$default = $field["default"];
|
||||
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])
|
||||
? implode(",", $row[$name])
|
||||
: (is_bool($row[$name]) ? +$row[$name] : $row[$name])
|
||||
)
|
||||
: (!$update && $field["auto_increment"]
|
||||
? ""
|
||||
: (isset($_GET["select"]) ? false : $default)
|
||||
)
|
||||
);
|
||||
if (!$_POST["save"] && is_string($value)) {
|
||||
$value = $adminer->editVal($value, $field);
|
||||
}
|
||||
$function = ($_POST["save"]
|
||||
? (string) $_POST["function"][$name]
|
||||
: ($update && preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"])
|
||||
? "now"
|
||||
: ($value === false ? null : ($value !== null ? '' : 'NULL'))
|
||||
)
|
||||
);
|
||||
if (!$_POST && !$update && $value == $field["default"] && preg_match('~^[\w.]+\(~', $value)) {
|
||||
$function = "SQL";
|
||||
}
|
||||
if (preg_match("~time~", $field["type"]) && preg_match('~^CURRENT_TIMESTAMP~i', $value)) {
|
||||
$value = "";
|
||||
$function = "now";
|
||||
}
|
||||
if ($field["type"] == "uuid" && $value == "uuid()") {
|
||||
$value = "";
|
||||
$function = "uuid";
|
||||
}
|
||||
if ($autofocus !== false) {
|
||||
$autofocus = ($field["auto_increment"] || $function == "now" || $function == "uuid" ? null : true); // null - don't autofocus this input but check the next one
|
||||
}
|
||||
input($field, $value, $function, $autofocus);
|
||||
if ($autofocus) {
|
||||
$autofocus = false;
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
if (!support("table") && !fields($table)) {
|
||||
echo "<tr>"
|
||||
. "<th><input name='field_keys[]'>"
|
||||
. script("qsl('input').oninput = fieldChange;")
|
||||
. "<td class='function'>" . html_select("field_funs[]", $adminer->editFunctions(array("null" => isset($_GET["select"]))))
|
||||
. "<td><input name='field_vals[]'>"
|
||||
. "\n"
|
||||
;
|
||||
}
|
||||
echo "</table>\n";
|
||||
}
|
||||
echo "<p>\n";
|
||||
if ($fields) {
|
||||
echo "<input type='submit' value='" . lang('Save') . "'>\n";
|
||||
if (!isset($_GET["select"])) {
|
||||
echo "<input type='submit' name='insert' value='" . ($update
|
||||
? lang('Save and continue edit')
|
||||
: lang('Save and insert next')
|
||||
) . "' title='Ctrl+Shift+Enter'>\n";
|
||||
echo ($update ? script("qsl('input').onclick = function () { return !ajaxForm(this.form, '" . lang('Saving') . "…', this); };") : "");
|
||||
}
|
||||
}
|
||||
echo ($update ? "<input type='submit' name='delete' value='" . lang('Delete') . "'>" . confirm() . "\n" : "");
|
||||
if (isset($_GET["select"])) {
|
||||
hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"]));
|
||||
}
|
||||
echo input_hidden("referer", (isset($_POST["referer"]) ? $_POST["referer"] : $_SERVER["HTTP_REFERER"]));
|
||||
echo input_hidden("save", 1);
|
||||
echo input_token();
|
||||
echo "</form>\n";
|
||||
}
|
@@ -45,6 +45,7 @@ $langs = array(
|
||||
'th' => 'ภาษาไทย', // Panya Saraphi, elect.tu@gmail.com - http://www.opencart2u.com/
|
||||
'tr' => 'Türkçe', // Bilgehan Korkmaz - turktron.com
|
||||
'uk' => 'Українська', // Valerii Kryzhov
|
||||
'uz' => 'Oʻzbekcha', // Junaydullaev Inoyatullokhon - https://av.uz/
|
||||
'vi' => 'Tiếng Việt', // Giang Manh @ manhgd google mail
|
||||
'zh' => '简体中文', // Mr. Lodar, vea - urn2.net - vea.urn2@gmail.com
|
||||
'zh-tw' => '繁體中文', // http://tzangms.com
|
||||
@@ -63,10 +64,12 @@ function get_lang() {
|
||||
* @param int
|
||||
* @return string
|
||||
*/
|
||||
// this is matched by compile.php
|
||||
function lang($idf, $number = null) {
|
||||
global $LANG, $translations;
|
||||
$translation = ($translations[$idf] ?: $idf);
|
||||
if (is_array($translation)) {
|
||||
// this is matched by compile.php
|
||||
$pos = ($number == 1 ? 0
|
||||
: ($LANG == 'cs' || $LANG == 'sk' ? ($number && $number < 5 ? 1 : 2) // different forms for 1, 2-4, other
|
||||
: ($LANG == 'fr' ? (!$number ? 0 : 1) // different forms for 0-1, other
|
||||
@@ -74,11 +77,12 @@ 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
|
||||
: 1 // different forms for 1, other
|
||||
)))))))); // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
|
||||
: (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];
|
||||
}
|
||||
$translation = str_replace("'", '’', $translation); // translations can contain HTML or be used in optionlist (we couldn't escape them here) but they can also be used e.g. in title='' //! escape plaintext translations
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
$format = str_replace("%d", "%s", $translation);
|
||||
@@ -93,7 +97,7 @@ function switch_lang() {
|
||||
echo "<form action='' method='post'>\n<div id='lang'>";
|
||||
echo lang('Language') . ": " . html_select("lang", $langs, $LANG, "this.form.submit();");
|
||||
echo " <input type='submit' value='" . lang('Use') . "' class='hidden'>\n";
|
||||
echo "<input type='hidden' name='token' value='" . get_token() . "'>\n"; // $token may be empty in auth.inc.php
|
||||
echo input_token(get_token()); // $token may be empty in auth.inc.php
|
||||
echo "</div>\n</form>\n";
|
||||
}
|
||||
|
||||
|
@@ -4,14 +4,16 @@ 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 $flavor = '', $server_info, $affected_rows, $errno, $error;
|
||||
protected $pdo;
|
||||
private $result;
|
||||
|
||||
function dsn($dsn, $username, $password, $options = array()) {
|
||||
$options[\PDO::ATTR_ERRMODE] = \PDO::ERRMODE_SILENT;
|
||||
$options[\PDO::ATTR_STATEMENT_CLASS] = array('Adminer\PdoDbStatement');
|
||||
try {
|
||||
$this->pdo = new \PDO($dsn, $username, $password, $options);
|
||||
} catch (Exception $ex) {
|
||||
} catch (\Exception $ex) {
|
||||
auth_error(h($ex->getMessage()));
|
||||
}
|
||||
$this->server_info = @$this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION);
|
||||
@@ -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) {
|
||||
@@ -70,12 +72,12 @@ if (extension_loaded('pdo')) {
|
||||
return false;
|
||||
}
|
||||
$row = $result->fetch();
|
||||
return $row[$field];
|
||||
return $row ? $row[$field] : false;
|
||||
}
|
||||
}
|
||||
|
||||
class PdoDbStatement extends \PDOStatement {
|
||||
var $_offset = 0, $num_rows;
|
||||
public $_offset = 0, $num_rows;
|
||||
|
||||
function fetch_assoc() {
|
||||
return $this->fetch(\PDO::FETCH_ASSOC);
|
||||
@@ -85,11 +87,15 @@ if (extension_loaded('pdo')) {
|
||||
return $this->fetch(\PDO::FETCH_NUM);
|
||||
}
|
||||
|
||||
function fetch_column($field) {
|
||||
return $this->fetchColumn($field);
|
||||
}
|
||||
|
||||
function fetch_field() {
|
||||
$row = (object) $this->getColumnMeta($this->_offset++);
|
||||
$row->orgtable = $row->table;
|
||||
$row->orgname = $row->name;
|
||||
$row->charsetnr = (in_array("blob", (array) $row->flags) ? 63 : 0);
|
||||
$type = $row->pdo_type;
|
||||
$row->type = ($type == \PDO::PARAM_INT ? 0 : 15);
|
||||
$row->charsetnr = ($type == \PDO::PARAM_LOB || (isset($row->flags) && in_array("blob", (array) $row->flags)) ? 63 : 0);
|
||||
return $row;
|
||||
}
|
||||
|
||||
|
427
adminer/include/plugins.inc.php
Normal file
427
adminer/include/plugins.inc.php
Normal file
@@ -0,0 +1,427 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
class Plugins extends Adminer {
|
||||
public $plugins; ///< @var protected(set) array
|
||||
|
||||
/** Register plugins
|
||||
* @param array object instances or null to autoload plugins from adminer-plugins/
|
||||
*/
|
||||
function __construct($plugins) {
|
||||
if ($plugins === null) {
|
||||
$plugins = array();
|
||||
$basename = "adminer-plugins";
|
||||
if (is_dir($basename)) {
|
||||
foreach (glob("$basename/*.php") as $filename) {
|
||||
$include = include_once "./$filename";
|
||||
}
|
||||
}
|
||||
$help = " href='https://www.adminer.org/plugins/#use'" . target_blank();
|
||||
if (file_exists("$basename.php")) {
|
||||
$include = include_once "./$basename.php"; // example: return array(new AdminerLoginOtp($secret))
|
||||
if (is_array($include)) {
|
||||
foreach ($include as $plugin) {
|
||||
$plugins[get_class($plugin)] = $plugin;
|
||||
}
|
||||
} else {
|
||||
$this->error .= lang('%s must <a%s>return an array</a>.', "<b>$basename.php</b>", $help) . "<br>";
|
||||
}
|
||||
}
|
||||
foreach (get_declared_classes() as $class) {
|
||||
if (!$plugins[$class] && preg_match('~^Adminer\w~i', $class)) {
|
||||
$reflection = new \ReflectionClass($class);
|
||||
$constructor = $reflection->getConstructor();
|
||||
if ($constructor && $constructor->getNumberOfRequiredParameters()) {
|
||||
$this->error .= lang('<a%s>Configure</a> %s in %s.', $help, "<b>$class</b>", "<b>$basename.php</b>") . "<br>";
|
||||
} else {
|
||||
$plugins[$class] = new $class;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->plugins = $plugins;
|
||||
}
|
||||
|
||||
private function callParent($function, $args) {
|
||||
return call_user_func_array(array('parent', $function), $args);
|
||||
}
|
||||
|
||||
private function applyPlugin($function, $params) {
|
||||
$args = array();
|
||||
foreach ($params as $key => $val) {
|
||||
// some plugins accept params by reference - we don't need to propage it outside, just to the other plugins
|
||||
$args[] = &$params[$key];
|
||||
}
|
||||
foreach ($this->plugins as $plugin) {
|
||||
if (method_exists($plugin, $function)) {
|
||||
$return = call_user_func_array(array($plugin, $function), $args);
|
||||
if ($return !== null) {
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->callParent($function, $args);
|
||||
}
|
||||
|
||||
private function appendPlugin($function, $args) {
|
||||
$return = $this->callParent($function, $args);
|
||||
foreach ($this->plugins as $plugin) {
|
||||
if (method_exists($plugin, $function)) {
|
||||
$value = call_user_func_array(array($plugin, $function), $args);
|
||||
if ($value) {
|
||||
$return += $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
// appendPlugin
|
||||
|
||||
function dumpFormat() {
|
||||
$args = func_get_args();
|
||||
return $this->appendPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function dumpOutput() {
|
||||
$args = func_get_args();
|
||||
return $this->appendPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function editRowPrint($table, $fields, $row, $update) {
|
||||
$args = func_get_args();
|
||||
return $this->appendPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function editFunctions($field) {
|
||||
$args = func_get_args();
|
||||
return $this->appendPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
// applyPlugin
|
||||
|
||||
function name() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function credentials() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function connectSsl() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function permanentLogin($create = false) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function bruteForceKey() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function serverName($server) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function database() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function schemas() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function databases($flush = true) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function queryTimeout() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function headers() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function csp() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function head($dark = null) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function css() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function loginForm() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function loginFormField($name, $heading, $value) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function login($login, $password) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function tableName($tableStatus) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function fieldName($field, $order = 0) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectLinks($tableStatus, $set = "") {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function foreignKeys($table) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function backwardKeys($table, $tableName) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function backwardKeysPrint($backwardKeys, $row) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectQuery($query, $start, $failed = false) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function sqlCommandQuery($query) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function sqlPrintAfter() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function rowDescription($table) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function rowDescriptions($rows, $foreignKeys) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectLink($val, $field) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectVal($val, $link, $field, $original) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function editVal($val, $field) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function tableStructurePrint($fields, $tableStatus = null) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function tableIndexesPrint($indexes) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectColumnsPrint($select, $columns) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectSearchPrint($where, $columns, $indexes) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectOrderPrint($order, $columns, $indexes) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectLimitPrint($limit) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectLengthPrint($text_length) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectActionPrint($indexes) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectCommandPrint() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectImportPrint() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectEmailPrint($emailFields, $columns) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectColumnsProcess($columns, $indexes) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectSearchProcess($fields, $indexes) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectOrderProcess($fields, $indexes) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectLimitProcess() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectLengthProcess() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectEmailProcess($where, $foreignKeys) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function selectQueryBuild($select, $where, $group, $order, $limit, $page) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function messageQuery($query, $time, $failed = false) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function editInput($table, $field, $attrs, $value) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function editHint($table, $field, $value) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function processInput($field, $value, $function = "") {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function dumpDatabase($db) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function dumpTable($table, $style, $is_view = 0) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function dumpData($table, $style, $query) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function dumpFilename($identifier) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function dumpHeaders($identifier, $multi_table = false) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function dumpFooter() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function importServerPath() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function homepage() {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function navigation($missing) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function syntaxHighlighting($tables) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function databasesPrint($missing) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
function tablesPrint($tables) {
|
||||
$args = func_get_args();
|
||||
return $this->applyPlugin(__FUNCTION__, $args);
|
||||
}
|
||||
}
|
@@ -2,8 +2,7 @@
|
||||
namespace Adminer;
|
||||
|
||||
class TmpFile {
|
||||
var $handler;
|
||||
var $size;
|
||||
private $handler, $size;
|
||||
|
||||
function __construct() {
|
||||
$this->handler = tmpfile();
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
$VERSION = "5.0.2";
|
||||
$VERSION = "5.1.0";
|
||||
|
@@ -6,6 +6,7 @@
|
||||
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
|
||||
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||
*/
|
||||
// this is matched by compile.php
|
||||
|
||||
namespace Adminer;
|
||||
|
||||
@@ -15,6 +16,7 @@ include "./include/tmpfile.inc.php";
|
||||
if (isset($_GET["select"]) && ($_POST["edit"] || $_POST["clone"]) && !$_POST["save"]) {
|
||||
$_GET["edit"] = $_GET["select"];
|
||||
}
|
||||
// this is matched by compile.php
|
||||
if (isset($_GET["callf"])) {
|
||||
$_GET["call"] = $_GET["callf"];
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@ if (JUSH == "mongo") { // doesn't support primary key
|
||||
}
|
||||
$row = $_POST;
|
||||
if ($row) {
|
||||
set_adminer_settings(array("index_options" => $row["options"]));
|
||||
save_settings(array("index_options" => $row["options"]));
|
||||
}
|
||||
if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) {
|
||||
$alter = array();
|
||||
@@ -97,7 +97,7 @@ if (!$row) {
|
||||
$row["indexes"] = $indexes;
|
||||
}
|
||||
$lengths = (JUSH == "sql" || JUSH == "mssql");
|
||||
$show_options = ($_POST ? $_POST["options"] : adminer_setting("index_options"));
|
||||
$show_options = ($_POST ? $_POST["options"] : get_setting("index_options"));
|
||||
?>
|
||||
|
||||
<form action="" method="post">
|
||||
@@ -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"]);
|
||||
@@ -155,5 +155,5 @@ foreach ($row["indexes"] as $index) {
|
||||
</div>
|
||||
<p>
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
<?php echo input_token(); ?>
|
||||
</form>
|
||||
|
@@ -266,3 +266,5 @@ $translations = array(
|
||||
'Edit all' => 'تعديل الكل',
|
||||
'HH:MM:SS' => 'HH:MM:SS',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php ar` to update this file
|
||||
|
@@ -256,7 +256,7 @@ $translations = array(
|
||||
// in-place editing in select
|
||||
'Modify' => 'Промяна',
|
||||
'Ctrl+click on a value to modify it.' => 'Ctrl+щракване в стойността, за да я промените.',
|
||||
'Use edit link to modify this value.' => 'Използвайте "редакция" за промяна на данните.',
|
||||
'Use edit link to modify this value.' => 'Използвайте \'редакция\' за промяна на данните.',
|
||||
|
||||
// %s can contain auto-increment value
|
||||
'Item%s has been inserted.' => 'Елементи%s бяха вмъкнати.',
|
||||
@@ -335,3 +335,5 @@ $translations = array(
|
||||
'Type has been created.' => 'Вида беше създаден.',
|
||||
'Alter type' => 'Промяна на вид',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php bg` to update this file
|
||||
|
@@ -266,3 +266,5 @@ $translations = array(
|
||||
'Edit all' => 'সবগুলো সম্পাদনা করুন',
|
||||
'HH:MM:SS' => 'HH:MM:SS',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php bn` to update this file
|
||||
|
@@ -320,3 +320,5 @@ $translations = array(
|
||||
'Type has been created.' => 'tip je spašen.',
|
||||
'Alter type' => 'Ažuriraj tip',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php bs` to update this file
|
||||
|
@@ -267,3 +267,5 @@ $translations = array(
|
||||
'Edit all' => 'Edita-ho tot',
|
||||
'HH:MM:SS' => 'HH:MM:SS',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php ca` to update this file
|
||||
|
@@ -13,6 +13,9 @@ $translations = array(
|
||||
'Logged as: %s' => 'Přihlášen jako: %s',
|
||||
'Logout successful.' => 'Odhlášení proběhlo v pořádku.',
|
||||
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Díky za použití Admineru, <a href="https://www.adminer.org/cs/donation/">přispějte</a> na vývoj.',
|
||||
'Loaded plugins' => 'Nahrané pluginy',
|
||||
'%s must <a%s>return an array</a>.' => '%s musí <a%s>vracet pole</a>.',
|
||||
'<a%s>Configure</a> %s in %s.' => '<a%s>Nakonfigurujte</a> %s v %s.',
|
||||
'Invalid credentials.' => 'Neplatné přihlašovací údaje.',
|
||||
'There is a space in the input password which might be the cause.' => 'Problém může být, že je v zadaném hesle mezera.',
|
||||
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer nepodporuje přístup k databázi bez hesla, <a href="https://www.adminer.org/cs/password/"%s>více informací</a>.',
|
||||
@@ -356,3 +359,5 @@ $translations = array(
|
||||
'Check has been altered.' => 'Kontrola byla změněna.',
|
||||
'Check has been dropped.' => 'Kontrola byla odstraněna.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php cs` to update this file
|
||||
|
@@ -281,3 +281,5 @@ $translations = array(
|
||||
'Alter type' => 'Ændre type',
|
||||
'Saving' => 'Gemmer',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php da` to update this file
|
||||
|
@@ -302,4 +302,12 @@ $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',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php de` to update this file
|
||||
|
@@ -335,3 +335,5 @@ $translations = array(
|
||||
'Type has been created.' => 'Ο τύπος δημιουργήθηκε.',
|
||||
'Alter type' => 'Τροποποίηση τύπου',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php el` to update this file
|
||||
|
@@ -15,3 +15,5 @@ $translations = array(
|
||||
'%d in total' => '%d in total',
|
||||
'%d query(s) executed OK.' => array('%d query executed OK.', '%d queries executed OK.'),
|
||||
);
|
||||
|
||||
// run `php ../../lang.php en` to update this file
|
||||
|
@@ -44,6 +44,7 @@ $translations = array(
|
||||
'Save and insert next' => 'Guardar e insertar siguiente',
|
||||
'Delete' => 'Eliminar',
|
||||
'Database' => 'Base de datos',
|
||||
'DB' => 'BD',
|
||||
'Routines' => 'Procedimientos',
|
||||
'Indexes have been altered.' => 'Índices actualizados.',
|
||||
'Indexes' => 'Índices',
|
||||
@@ -62,18 +63,22 @@ $translations = array(
|
||||
'Page' => 'Página',
|
||||
'Query executed OK, %d row(s) affected.' => array('Consulta ejecutada, %d registro afectado.', 'Consulta ejecutada, %d registros afectados.'),
|
||||
'Error in query' => 'Error al ejecutar consulta',
|
||||
'Unknown error.' => 'Error desconocido.',
|
||||
'Warnings' => 'Advertencias',
|
||||
'ATTACH queries are not supported.' => 'Consultas tipo ATTACH no soportadas.',
|
||||
'Execute' => 'Ejecutar',
|
||||
'Table' => 'Tabla',
|
||||
'Foreign keys' => 'Claves externas',
|
||||
'Triggers' => 'Disparadores',
|
||||
'View' => 'Vista',
|
||||
'Materialized view' => 'Vista materializada',
|
||||
'Unable to select the table' => 'No es posible seleccionar la tabla',
|
||||
'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Vuelva a enviar los datos del formulario.',
|
||||
'Comment' => 'Comentario',
|
||||
'Default values' => 'Valores predeterminados',
|
||||
'%d byte(s)' => array('%d byte', '%d bytes'),
|
||||
'No commands to execute.' => 'No es posible ejecutar ningún comando.',
|
||||
'Unable to upload a file.' => 'No es posible importar el archivo.',
|
||||
'No commands to execute.' => 'Ningún comando para ejecutar.',
|
||||
'Unable to upload a file.' => 'No es posible cargar el archivo.',
|
||||
'File upload' => 'Importar archivo',
|
||||
'File uploads are disabled.' => 'Importación de archivos deshablilitada.',
|
||||
'Routine has been called, %d row(s) affected.' => array('Consulta ejecutada, %d registro afectado.', 'Consulta ejecutada, %d registros afectados.'),
|
||||
@@ -83,9 +88,9 @@ $translations = array(
|
||||
'Session support must be enabled.' => 'Deben estar habilitadas las sesiones.',
|
||||
'Session expired, please login again.' => 'Sesión caducada, por favor escriba su clave de nuevo.',
|
||||
'Text length' => 'Longitud de texto',
|
||||
'Foreign key has been dropped.' => 'Clave externa eliminada.',
|
||||
'Foreign key has been altered.' => 'Clave externa modificada.',
|
||||
'Foreign key has been created.' => 'Clave externa creada.',
|
||||
'Foreign key has been dropped.' => 'Clave foranea eliminada.',
|
||||
'Foreign key has been altered.' => 'Clave foranea modificada.',
|
||||
'Foreign key has been created.' => 'Clave foranea creada.',
|
||||
'Foreign key' => 'Clave externa',
|
||||
'Target table' => 'Tabla de destino',
|
||||
'Change' => 'Modificar',
|
||||
@@ -140,6 +145,8 @@ $translations = array(
|
||||
'Grant' => 'Conceder',
|
||||
'Revoke' => 'Impedir',
|
||||
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'POST data demasiado grande. Reduzca el tamaño o aumente la directiva de configuración %s.',
|
||||
'You can upload a big SQL file via FTP and import it from server.' => 'Usted puede cargar un SQL grande mediante FTP e importarlo desde el servidor.',
|
||||
'You are offline.' => 'Usted no esta en linea.',
|
||||
'Logged as: %s' => 'Logueado como: %s',
|
||||
'Move up' => 'Mover arriba',
|
||||
'Move down' => 'Mover abajo',
|
||||
@@ -147,8 +154,8 @@ $translations = array(
|
||||
'Aggregation' => 'Agregados',
|
||||
'Export' => 'Exportar',
|
||||
'Output' => 'Salida',
|
||||
'open' => 'mostrar',
|
||||
'save' => 'archivo',
|
||||
'open' => 'abrir',
|
||||
'save' => 'guardar',
|
||||
'Format' => 'Formato',
|
||||
'Tables' => 'Tablas',
|
||||
'Data' => 'Datos',
|
||||
@@ -195,6 +202,7 @@ $translations = array(
|
||||
'Partition name' => 'Nombre de partición',
|
||||
'Values' => 'Valores',
|
||||
'%d row(s) have been imported.' => array('%d registro importado.', '%d registros importados.'),
|
||||
'File must be in UTF-8 encoding.' => 'El archivo tiene que ser codificacion UTF-8.',
|
||||
'anywhere' => 'donde sea',
|
||||
'Import' => 'Importar',
|
||||
'Stop on error' => 'Parar en caso de error',
|
||||
@@ -256,7 +264,7 @@ $translations = array(
|
||||
'Attachments' => 'Adjuntos',
|
||||
'%d query(s) executed OK.' => array('%d sentencia SQL ejecutada correctamente.', '%d sentencias SQL ejecutadas correctamente.'),
|
||||
'Show only errors' => 'Mostrar solamente errores',
|
||||
'Refresh' => 'Refrescar',
|
||||
'Refresh' => 'Actualizar',
|
||||
'Invalid schema.' => 'Esquema inválido.',
|
||||
'Please use one of the extensions %s.' => 'Por favor, use una de las extensiones %s.',
|
||||
'now' => 'ahora',
|
||||
@@ -266,4 +274,28 @@ $translations = array(
|
||||
'Permanent link' => 'Enlace permanente',
|
||||
'Edit all' => 'Editar todos',
|
||||
'HH:MM:SS' => 'HH:MM:SS',
|
||||
|
||||
'Loaded plugins' => 'Plugins cargados',
|
||||
// '<b>%s</b> must return an array.' => '<b>%s</b> tiene que retornar un arreglo.',
|
||||
// 'Configure <b>%s</b> in <b>%s</b>.' => 'Configurar <b>%s</b> en <b>%s</b>.',
|
||||
'There is a space in the input password which might be the cause.' => 'Hay un espacio en el password, lo cual puede ser la causa.',
|
||||
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer no soporta accesar una base de datos sin clave, <a href="https://www.adminer.org/en/password/"%s>Ver detalles</a>.',
|
||||
'Database does not support password.' => 'La base de datos no soporta password.',
|
||||
'Too many unsuccessful logins, try again in %d minute(s).' => array('Muchos intentos de acceso Intente en %d minutos.'),
|
||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Password maestro expirado. <a href="https://www.adminer.org/en/extension/"%s>Implemente</a> %s metodo para hacerlo permanente.',
|
||||
'If you did not send this request from Adminer then close this page.' => 'Si no puede enviar la solicitud por Adminer entonces cierre esta pagina.',
|
||||
'Connecting to privileged ports is not allowed.' => 'Conexiones a puertos privilegiados no son permitidas.',
|
||||
'Disable %s or enable %s or %s extensions.' => 'Desactivar %s o activar %s o %s extensiones.',
|
||||
'The action will be performed after successful login with the same credentials.' => 'La operacion sera ejecutada despues de ingresar nuevamente con las mismas credenciales.',
|
||||
'You have no privileges to update this table.' => 'Usted no tiene privilegios para actualizar esta tabla.',
|
||||
|
||||
// Table check constraints
|
||||
'Checks' => 'Chequeos',
|
||||
'Create check' => 'Crear chequeo',
|
||||
'Alter check' => 'Cambiar chequeo',
|
||||
'Check has been created.' => 'Chequeo creado.',
|
||||
'Check has been altered.' => 'Chequeo cambiado.',
|
||||
'Check has been dropped.' => 'Chequeo eliminado.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php es` to update this file
|
||||
|
@@ -267,3 +267,5 @@ $translations = array(
|
||||
'Edit all' => 'Muuda kõiki',
|
||||
'HH:MM:SS' => 'HH:MM:SS',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php et` to update this file
|
||||
|
@@ -333,3 +333,5 @@ $translations = array(
|
||||
'Type has been created.' => 'نوع ایجاد شد.',
|
||||
'Alter type' => 'ویرایش نوع',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php fa` to update this file
|
||||
|
@@ -349,3 +349,5 @@ $translations = array(
|
||||
'Database does not support password.' => 'Tietokanta ei tue salasanaa.',
|
||||
'Disable %s or enable %s or %s extensions.' => 'Poista käytöstä %s tai ota käyttöön laajennus %s tai %s.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php fi` to update this file
|
||||
|
@@ -242,7 +242,7 @@ $translations = array(
|
||||
'Type has been dropped.' => 'Le type a été supprimé.',
|
||||
'Type has been created.' => 'Le type a été créé.',
|
||||
'Ctrl+click on a value to modify it.' => 'Ctrl+cliquez sur une valeur pour la modifier.',
|
||||
'Use edit link to modify this value.' => 'Utilisez le lien "modifier" pour modifier cette valeur.',
|
||||
'Use edit link to modify this value.' => 'Utilisez le lien \'modifier\' pour modifier cette valeur.',
|
||||
'last' => 'dernière',
|
||||
'From server' => 'Depuis le serveur',
|
||||
'System' => 'Système',
|
||||
@@ -302,3 +302,5 @@ $translations = array(
|
||||
'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.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php fr` to update this file
|
||||
|
@@ -290,3 +290,5 @@ $translations = array(
|
||||
'yes' => 'si',
|
||||
'no' => 'non',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php gl` to update this file
|
||||
|
@@ -292,3 +292,5 @@ $translations = array(
|
||||
'yes' => 'כן',
|
||||
'no' => 'לא',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php he` to update this file
|
||||
|
@@ -266,3 +266,5 @@ $translations = array(
|
||||
'Edit all' => 'Összes szerkesztése',
|
||||
'HH:MM:SS' => 'óó:pp:mm',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php hu` to update this file
|
||||
|
@@ -315,3 +315,5 @@ $translations = array(
|
||||
'Type has been created.' => 'Jenis berhasil dibuat.',
|
||||
'Alter type' => 'Ubah jenis',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php id` to update this file
|
||||
|
@@ -302,3 +302,5 @@ $translations = array(
|
||||
'yes' => 'si',
|
||||
'no' => 'no',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php it` to update this file
|
||||
|
@@ -3,17 +3,24 @@ namespace Adminer;
|
||||
|
||||
$translations = array(
|
||||
'Login' => 'ログイン',
|
||||
'Logout successful.' => 'ログアウト',
|
||||
'Invalid credentials.' => '不正なログイン',
|
||||
'Logout successful.' => 'ログアウトしました。',
|
||||
'Invalid credentials.' => '不正なログインです。',
|
||||
'Server' => 'サーバ',
|
||||
'Username' => 'ユーザ名',
|
||||
'Password' => 'パスワード',
|
||||
'Loaded plugins' => '読込済プラグイン',
|
||||
'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>)',
|
||||
'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>)',
|
||||
'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 関数を用います。',
|
||||
'Select database' => 'データベースを選択してください',
|
||||
'Invalid database.' => '不正なデータベース',
|
||||
'Table has been dropped.' => 'テーブルを削除しました',
|
||||
'Table has been altered.' => 'テーブルを変更しました',
|
||||
'Table has been created.' => 'テーブルを作成しました',
|
||||
'Alter table' => 'テーブルの変更',
|
||||
'Invalid database.' => '不正なデータベースです。',
|
||||
'Table has been dropped.' => 'テーブルを削除しました。',
|
||||
'Table has been altered.' => 'テーブルを変更しました。',
|
||||
'Table has been created.' => 'テーブルを作成しました。',
|
||||
'Alter table' => 'テーブルを変更',
|
||||
'Create table' => 'テーブルを作成',
|
||||
'Table name' => 'テーブル名',
|
||||
'engine' => 'エンジン',
|
||||
@@ -25,10 +32,11 @@ $translations = array(
|
||||
'Options' => '設定',
|
||||
'Save' => '保存',
|
||||
'Drop' => '削除',
|
||||
'Database has been dropped.' => 'データベースを削除しました',
|
||||
'Database has been created.' => 'データベースを作成しました',
|
||||
'Database has been renamed.' => 'データベースの名前を変えました',
|
||||
'Database has been altered.' => 'データベースを変更しました',
|
||||
'Drop %s?' => '%s を削除しますか?',
|
||||
'Database has been dropped.' => 'データベースを削除しました。',
|
||||
'Database has been created.' => 'データベースを作成しました。',
|
||||
'Database has been renamed.' => 'データベースの名前を変えました。',
|
||||
'Database has been altered.' => 'データベースを変更しました。',
|
||||
'Alter database' => 'データベースを変更',
|
||||
'Create database' => 'データベースを作成',
|
||||
'SQL command' => 'SQLコマンド',
|
||||
@@ -36,15 +44,17 @@ $translations = array(
|
||||
'Use' => '使用',
|
||||
'No tables.' => 'テーブルがありません。',
|
||||
'select' => '選択',
|
||||
'Item has been deleted.' => '項目を削除しました',
|
||||
'Item has been updated.' => '項目を更新しました',
|
||||
'Item has been deleted.' => '項目を削除しました。',
|
||||
'Item has been updated.' => '項目を更新しました。',
|
||||
'Edit' => '編集',
|
||||
'Insert' => '挿入',
|
||||
'Save and insert next' => '保存/追加',
|
||||
'Delete' => '削除',
|
||||
'You have no privileges to update this table.' => 'このテーブルを更新する権限がありません。',
|
||||
'Database' => 'データベース',
|
||||
'DB' => 'DB',
|
||||
'Routines' => 'ルーチン',
|
||||
'Indexes have been altered.' => '索引を変更しました',
|
||||
'Indexes have been altered.' => '索引を変更しました。',
|
||||
'Indexes' => '索引',
|
||||
'Alter indexes' => '索引の変更',
|
||||
'Add next' => '追加',
|
||||
@@ -55,36 +65,46 @@ $translations = array(
|
||||
'Sort' => 'ソート',
|
||||
'descending' => '降順',
|
||||
'Limit' => '制約',
|
||||
'No rows.' => '行がありません',
|
||||
'Limit rows' => '行数の制約',
|
||||
'No rows.' => '行がありません。',
|
||||
'Action' => '動作',
|
||||
'edit' => '編集',
|
||||
'Page' => 'ページ',
|
||||
'Query executed OK, %d row(s) affected.' => 'クエリーを実行しました。%d 行を変更しました',
|
||||
'Query executed OK, %d row(s) affected.' => 'クエリーを実行しました。%d 行を変更しました。',
|
||||
'Error in query' => 'クエリーのエラー',
|
||||
'Unknown error.' => '不明なエラーです。',
|
||||
'Warnings' => '警告',
|
||||
'ATTACH queries are not supported.' => 'ATTACH クエリーは対応していません。',
|
||||
'Execute' => '実行',
|
||||
'Table' => 'テーブル',
|
||||
'Foreign keys' => '外部キー',
|
||||
'Triggers' => 'トリガー',
|
||||
'View' => 'ビュー',
|
||||
'Materialized view' => 'マテビュー',
|
||||
'Full table scan' => 'テーブルの全スキャン',
|
||||
'Unable to select the table' => 'テーブルを選択できません',
|
||||
'Invalid CSRF token. Send the form again.' => '不正なCSRFトークン。再送信してください',
|
||||
'Invalid CSRF token. Send the form again.' => '不正なCSRFトークン。再送信してください。',
|
||||
'If you did not send this request from Adminer then close this page.' => 'Adminerからのリクエストを送信しない場合はこのページを閉じてください。',
|
||||
'Comment' => 'コメント',
|
||||
'Default values' => '規定値',
|
||||
'%d byte(s)' => '%d バイト',
|
||||
'No commands to execute.' => '実行するコマンドがありません',
|
||||
'Unable to upload a file.' => 'ファイルをアップロードできません',
|
||||
'No commands to execute.' => '実行するコマンドがありません。',
|
||||
'Unable to upload a file.' => 'ファイルをアップロードできません。',
|
||||
'File upload' => 'ファイルをアップロード',
|
||||
'File uploads are disabled.' => 'ファイルのアップロードが無効です',
|
||||
'Routine has been called, %d row(s) affected.' => 'ルーチンを呼びました。%d 行を変更しました',
|
||||
'File uploads are disabled.' => 'ファイルのアップロードが無効です。',
|
||||
'Routine has been called, %d row(s) affected.' => 'ルーチンを呼びました。%d 行を変更しました。',
|
||||
'Call' => '呼出し',
|
||||
'No extension' => '拡張機能がありません',
|
||||
'None of the supported PHP extensions (%s) are available.' => 'PHPの拡張機能(%s)がセットアップされていません',
|
||||
'Session support must be enabled.' => 'セッションを有効にしてください',
|
||||
'Session expired, please login again.' => 'セッションの期限切れ。ログインし直してください',
|
||||
'None of the supported PHP extensions (%s) are available.' => 'PHPの拡張機能(%s)がセットアップされていません。',
|
||||
'Connecting to privileged ports is not allowed.' => '特権ポートへの接続は許可されていません。',
|
||||
'Disable %s or enable %s or %s extensions.' => '%s を無効にするか、拡張機能 %s または %s を有効にしてください。',
|
||||
'Session support must be enabled.' => 'セッションを有効にしてください。',
|
||||
'Session expired, please login again.' => 'セッションの期限切れ。ログインし直してください。',
|
||||
'The action will be performed after successful login with the same credentials.' => '同じアカウントで正しくログインすると作業を実行します。',
|
||||
'Text length' => '文字列の長さ',
|
||||
'Foreign key has been dropped.' => '外部キーを削除しました',
|
||||
'Foreign key has been altered.' => '外部キーを変更しました',
|
||||
'Foreign key has been created.' => '外部キーを作成しました',
|
||||
'Foreign key has been dropped.' => '外部キーを削除しました。',
|
||||
'Foreign key has been altered.' => '外部キーを変更しました。',
|
||||
'Foreign key has been created.' => '外部キーを作成しました。',
|
||||
'Foreign key' => '外キー',
|
||||
'Target table' => 'テーブル',
|
||||
'Change' => '変更',
|
||||
@@ -97,49 +117,52 @@ $translations = array(
|
||||
'ON UPDATE' => 'ON UPDATE',
|
||||
'Index Type' => '索引の型',
|
||||
'length' => '長さ',
|
||||
'View has been dropped.' => 'ビューを削除しました',
|
||||
'View has been altered.' => 'ビューを変更しました',
|
||||
'View has been created.' => 'ビューを作成しました',
|
||||
'View has been dropped.' => 'ビューを削除しました。',
|
||||
'View has been altered.' => 'ビューを変更しました。',
|
||||
'View has been created.' => 'ビューを作成しました。',
|
||||
'Alter view' => 'ビューを変更',
|
||||
'Create view' => 'ビューを作成',
|
||||
'Name' => '名称',
|
||||
'Process list' => 'プロセス一覧',
|
||||
'%d process(es) have been killed.' => '%d プロセスを強制終了しました',
|
||||
'%d process(es) have been killed.' => '%d プロセスを強制終了しました。',
|
||||
'Kill' => '強制終了',
|
||||
'Parameter name' => '参数名',
|
||||
'Database schema' => '構造',
|
||||
'Create procedure' => 'プロシージャの作成',
|
||||
'Create function' => '関数の作成',
|
||||
'Routine has been dropped.' => 'ルーチンを作成',
|
||||
'Routine has been altered.' => 'ルーチンを変更',
|
||||
'Routine has been created.' => 'ルーチンを作成',
|
||||
'Routine has been dropped.' => 'ルーチンを作成しました。',
|
||||
'Routine has been altered.' => 'ルーチンを変更しました。',
|
||||
'Routine has been created.' => 'ルーチンを作成しました。',
|
||||
'Alter function' => '関数の変更',
|
||||
'Alter procedure' => 'プロシージャの変更',
|
||||
'Return type' => '戻り値の型',
|
||||
'Add trigger' => 'トリガーの追加',
|
||||
'Trigger has been dropped.' => 'トリガーを削除しました',
|
||||
'Trigger has been altered.' => 'トリガーを変更しました',
|
||||
'Trigger has been created.' => 'トリガーを追加しました',
|
||||
'Trigger has been dropped.' => 'トリガーを削除しました。',
|
||||
'Trigger has been altered.' => 'トリガーを変更しました。',
|
||||
'Trigger has been created.' => 'トリガーを追加しました。',
|
||||
'Alter trigger' => 'トリガーの変更',
|
||||
'Create trigger' => 'トリガーの作成',
|
||||
'Time' => '時間',
|
||||
'Event' => 'イベント',
|
||||
'%s version: %s through PHP extension %s' => '%sバージョン:%s、 PHP拡張機能 %s',
|
||||
'%d / ' => '%d / ',
|
||||
'%d row(s)' => '%d 行',
|
||||
'Remove' => '除外',
|
||||
'Are you sure?' => '実行しますか?',
|
||||
'Privileges' => '権限',
|
||||
'Create user' => 'ユーザを作成',
|
||||
'User has been dropped.' => 'ユーザを削除',
|
||||
'User has been altered.' => 'ユーザを変更',
|
||||
'User has been created.' => 'ユーザを作成',
|
||||
'User has been dropped.' => 'ユーザを削除しました。',
|
||||
'User has been altered.' => 'ユーザを変更しました。',
|
||||
'User has been created.' => 'ユーザを作成しました。',
|
||||
'Hashed' => 'Hashed',
|
||||
'Column' => '列',
|
||||
'Routine' => 'ルーチン',
|
||||
'Grant' => '権限の付与',
|
||||
'Revoke' => '権限の取消し',
|
||||
'Logged as: %s' => 'ログ:%s',
|
||||
'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 設定を大きくしてください。',
|
||||
'You can upload a big SQL file via FTP and import it from server.' => '大きなSQLファイルは、FTP経由でアップロードしてサーバからインポートしてください。',
|
||||
'You are offline.' => 'オフライン状態です。',
|
||||
'Move up' => '上',
|
||||
'Move down' => '下',
|
||||
'Export' => 'エクスポート',
|
||||
@@ -151,9 +174,9 @@ $translations = array(
|
||||
'Format' => '形式',
|
||||
'Functions' => '関数',
|
||||
'Aggregation' => '集合',
|
||||
'Event has been dropped.' => '削除しました',
|
||||
'Event has been altered.' => '変更しました',
|
||||
'Event has been created.' => '作成しました',
|
||||
'Event has been dropped.' => 'イベントを削除しました。',
|
||||
'Event has been altered.' => 'イベントを変更しました。',
|
||||
'Event has been created.' => 'イベントを作成しました。',
|
||||
'Alter event' => '変更',
|
||||
'Create event' => '作成',
|
||||
'Start' => '開始',
|
||||
@@ -164,8 +187,8 @@ $translations = array(
|
||||
'Events' => 'イベント',
|
||||
'Schedule' => 'スケジュール',
|
||||
'At given time' => '指定時刻',
|
||||
'Tables have been truncated.' => 'テーブルをtruncateしました',
|
||||
'Tables have been moved.' => 'テーブルを移動しました',
|
||||
'Tables have been truncated.' => 'テーブルを空にしました。',
|
||||
'Tables have been moved.' => 'テーブルを移動しました。',
|
||||
'Tables and views' => 'テーブルとビュー',
|
||||
'Engine' => 'エンジン',
|
||||
'Collation' => '照合順序',
|
||||
@@ -177,6 +200,7 @@ $translations = array(
|
||||
'0123456789' => '0123456789',
|
||||
'Analyze' => '分析',
|
||||
'Optimize' => '最適化',
|
||||
'Vacuum' => '不要領域の回収',
|
||||
'Check' => 'チェック',
|
||||
'Repair' => '修復',
|
||||
'Truncate' => '空にする',
|
||||
@@ -184,16 +208,18 @@ $translations = array(
|
||||
'Move' => '移動',
|
||||
'Save and continue edit' => '保存して継続',
|
||||
'original' => '元',
|
||||
'%d item(s) have been affected.' => '%d を更新しました',
|
||||
'%d item(s) have been affected.' => '%d 個を更新しました。',
|
||||
'Whole result' => '全結果',
|
||||
'Tables have been dropped.' => 'テーブルを削除しました',
|
||||
'Tables have been dropped.' => 'テーブルを削除しました。',
|
||||
'Tables have been optimized.' => 'テーブルを最適化しました。',
|
||||
'Clone' => 'クローン',
|
||||
'Maximum number of allowed fields exceeded. Please increase %s.' => '定義可能な最大フィールド数を越えました。%s を増やしてください。',
|
||||
'Partition by' => 'パーティション',
|
||||
'Partitions' => 'パーティション',
|
||||
'Partition name' => 'パーティション名',
|
||||
'Values' => '値',
|
||||
'%d row(s) have been imported.' => '%d 行をインポートしました',
|
||||
'%d row(s) have been imported.' => '%d 行をインポートしました。',
|
||||
'File must be in UTF-8 encoding.' => 'ファイルをUTF-8で保存してください。',
|
||||
'Show structure' => '構造',
|
||||
'anywhere' => '任意',
|
||||
'Import' => 'インポート',
|
||||
@@ -208,7 +234,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' => '文字列',
|
||||
@@ -219,49 +245,51 @@ $translations = array(
|
||||
'From' => '差出人',
|
||||
'Subject' => '題名',
|
||||
'Send' => '送信',
|
||||
'%d e-mail(s) have been sent.' => '%d メールを送信しました',
|
||||
'%d e-mail(s) have been sent.' => '%d メールを送信しました。',
|
||||
'Webserver file %s' => 'Webサーバファイル %s',
|
||||
'File does not exist.' => 'ファイルは存在しません',
|
||||
'File does not exist.' => 'ファイルは存在しません。',
|
||||
'%d in total' => '合計 %d',
|
||||
'Permanent login' => '永続的にログイン',
|
||||
'Databases have been dropped.' => 'データベースを削除しました',
|
||||
'Databases have been dropped.' => 'データベースを削除しました。',
|
||||
'Search data in tables' => 'データを検索する',
|
||||
'Schema' => 'スキーマ',
|
||||
'Alter schema' => 'スキーマ変更',
|
||||
'Create schema' => 'スキーマ追加',
|
||||
'Schema has been dropped.' => 'スキーマを削除しました',
|
||||
'Schema has been created.' => 'スキーマを追加しました',
|
||||
'Schema has been altered.' => 'スキーマを変更しました',
|
||||
'Schema has been dropped.' => 'スキーマを削除しました。',
|
||||
'Schema has been created.' => 'スキーマを追加しました。',
|
||||
'Schema has been altered.' => 'スキーマを変更しました。',
|
||||
'Sequences' => 'シーケンス',
|
||||
'Create sequence' => 'シーケンス作成',
|
||||
'Alter sequence' => 'シーケンス変更',
|
||||
'Sequence has been dropped.' => 'シーケンスを削除しました',
|
||||
'Sequence has been created.' => 'シーケンスを追加しました',
|
||||
'Sequence has been altered.' => 'シーケンスを変更しました',
|
||||
'Sequence has been dropped.' => 'シーケンスを削除しました。',
|
||||
'Sequence has been created.' => 'シーケンスを追加しました。',
|
||||
'Sequence has been altered.' => 'シーケンスを変更しました。',
|
||||
'User types' => 'ユーザー定義型',
|
||||
'Create type' => 'ユーザー定義型作成',
|
||||
'Alter type' => 'ユーザー定義型変更',
|
||||
'Type has been dropped.' => 'ユーザー定義型を削除しました',
|
||||
'Type has been created.' => 'ユーザー定義型を追加しました',
|
||||
'Use edit link to modify this value.' => 'リンクを編集する',
|
||||
'Type has been dropped.' => 'ユーザー定義型を削除しました。',
|
||||
'Type has been created.' => 'ユーザー定義型を追加しました。',
|
||||
'Ctrl+click on a value to modify it.' => 'Ctrl+クリックで値を修正します。',
|
||||
'Use edit link to modify this value.' => 'この値を修正するとリンクを編集します。',
|
||||
'last' => '最終',
|
||||
'From server' => 'サーバーから実行',
|
||||
'System' => 'データベース種類',
|
||||
'empty' => '空',
|
||||
'Network' => 'ネットワーク型',
|
||||
'Geometry' => 'ジオメトリ型',
|
||||
'File exists.' => 'ファイルが既に存在します',
|
||||
'File exists.' => 'ファイルが既に存在します。',
|
||||
'Attachments' => '添付ファイル',
|
||||
'Item%s has been inserted.' => '%s項目を挿入しました',
|
||||
'Item%s has been inserted.' => '%s項目を挿入しました。',
|
||||
'now' => '現在の日時',
|
||||
'%d query(s) executed OK.' => '%d クエリーを実行しました',
|
||||
'%d query(s) executed OK.' => '%d クエリーを実行しました。',
|
||||
'Show only errors' => 'エラーのみ表示',
|
||||
'Refresh' => 'リフレッシュ',
|
||||
'Invalid schema.' => '無効なスキーマ',
|
||||
'Please use one of the extensions %s.' => 'いずれかの拡張機能を使ってください %s',
|
||||
'Invalid schema.' => '無効なスキーマです。',
|
||||
'Please use one of the extensions %s.' => '%s のいずれかの拡張機能を使ってください。',
|
||||
'ltr' => 'ltr',
|
||||
'Tables have been copied.' => 'テーブルをコピーしました',
|
||||
'Tables have been copied.' => 'テーブルをコピーしました。',
|
||||
'Copy' => 'コピー',
|
||||
'overwrite' => '上書き',
|
||||
'Permanent link' => 'パーマネントリンク',
|
||||
'Edit all' => 'すべて編集',
|
||||
'HH:MM:SS' => '時:分:秒',
|
||||
@@ -275,4 +303,14 @@ $translations = array(
|
||||
'yes' => 'はい',
|
||||
'no' => 'いいえ',
|
||||
'Default value' => '既定値',
|
||||
|
||||
// Table check constraints
|
||||
'Checks' => 'チェック',
|
||||
'Create check' => 'チェックを作成',
|
||||
'Alter check' => 'チェックを変更',
|
||||
'Check has been created.' => 'チェックを作成しました。',
|
||||
'Check has been altered.' => 'チェックを変更しました。',
|
||||
'Check has been dropped.' => 'チェックを削除しました。',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php ja` to update this file
|
||||
|
@@ -302,3 +302,5 @@ $translations = array(
|
||||
'Database does not support password.' => 'ბაზაში არაა მხარდაჭერილი პაროლი.',
|
||||
'Disable %s or enable %s or %s extensions.' => 'გათიშეთ %s ან ჩართეთ %s ან %s გაფართოება.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php ka` to update this file
|
||||
|
@@ -279,3 +279,5 @@ $translations = array(
|
||||
'You can upload a big SQL file via FTP and import it from server.' => '큰 SQL 파일은 FTP를 통하여 업로드하여 서버에서 가져올 수 있습니다.',
|
||||
'You have no privileges to update this table.' => '이 테이블을 업데이트할 권한이 없습니다.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php ko` to update this file
|
||||
|
@@ -311,3 +311,5 @@ $translations = array(
|
||||
'Type has been created.' => 'Tipas sukurtas.',
|
||||
'Alter type' => 'Keisti tipą',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php lt` to update this file
|
||||
|
@@ -243,7 +243,7 @@ $translations = array(
|
||||
'Type has been dropped.' => 'Tips dzēsts.',
|
||||
'Type has been created.' => 'Tips izveidots.',
|
||||
'Ctrl+click on a value to modify it.' => 'Lai izmainītu vērtību, izmanto Ctrl + peles klikšķi.',
|
||||
'Use edit link to modify this value.' => 'Izmainīt vērtību var tikai ar saiti "Izmainīt".',
|
||||
'Use edit link to modify this value.' => 'Izmainīt vērtību var tikai ar saiti \'Izmainīt\'.',
|
||||
'last' => 'pēdējā',
|
||||
'From server' => 'No servera',
|
||||
'System' => 'Sistēma',
|
||||
@@ -302,3 +302,5 @@ $translations = array(
|
||||
'Unknown error.' => 'Nezināma kļūda.',
|
||||
'Database does not support password.' => 'Datubāze neatbalsta paroli.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php lv` to update this file
|
||||
|
@@ -339,3 +339,5 @@ $translations = array(
|
||||
'Type has been created.' => 'Jenis telah dibuat.',
|
||||
'Alter type' => 'Ubah jenis',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php ms` to update this file
|
||||
|
@@ -243,7 +243,7 @@ $translations = array(
|
||||
'Type has been dropped.' => 'Type verwijderd.',
|
||||
'Type has been created.' => 'Type aangemaakt.',
|
||||
'Ctrl+click on a value to modify it.' => 'Ctrl+klik op een waarde om deze te bewerken.',
|
||||
'Use edit link to modify this value.' => 'Gebruik de link "bewerk" om deze waarde te wijzigen.',
|
||||
'Use edit link to modify this value.' => 'Gebruik de link \'bewerk\' om deze waarde te wijzigen.',
|
||||
'last' => 'laatste',
|
||||
'From server' => 'Van server',
|
||||
'System' => 'Databasesysteem',
|
||||
@@ -302,3 +302,5 @@ $translations = array(
|
||||
'yes' => 'ja',
|
||||
'no' => 'neen',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php nl` to update this file
|
||||
|
@@ -281,3 +281,5 @@ $translations = array(
|
||||
'Alter type' => 'Endre type',
|
||||
'Saving' => 'Lagrer',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php no` to update this file
|
||||
|
@@ -13,6 +13,9 @@ $translations = array(
|
||||
'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ż <a href="https://www.adminer.org/pl/donation/">dotację</a>.',
|
||||
'Loaded plugins' => 'Wczytane wtyczki',
|
||||
'%s must <a%s>return an array</a>.' => '%s musi <a%s>zwrócić tablicę</a>.',
|
||||
'<a%s>Configure</a> %s in %s.' => '<a%s>Skonfiguruj</a> %s w %s.',
|
||||
'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>.',
|
||||
@@ -356,3 +359,5 @@ $translations = array(
|
||||
'Check has been altered.' => 'Kontrola została zmieniona.',
|
||||
'Check has been dropped.' => 'Kontrola została usunięta.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php pl` to update this file
|
||||
|
@@ -262,3 +262,5 @@ $translations = array(
|
||||
'now' => 'agora',
|
||||
'ltr' => 'ltr',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php pt-br` to update this file
|
||||
|
@@ -262,3 +262,5 @@ $translations = array(
|
||||
'now' => 'agora',
|
||||
'ltr' => 'ltr',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php pt` to update this file
|
||||
|
@@ -267,3 +267,5 @@ $translations = array(
|
||||
'Edit all' => 'Editează tot',
|
||||
'HH:MM:SS' => 'HH:MM:SS',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php ro` to update this file
|
||||
|
@@ -303,3 +303,5 @@ $translations = array(
|
||||
'Database does not support password.' => 'База данных не поддерживает пароль.',
|
||||
'Disable %s or enable %s or %s extensions.' => 'Отключите %s или включите расширения %s или %s.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php ru` to update this 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,12 @@ $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á.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php sk` to update this file
|
||||
|
@@ -306,3 +306,5 @@ $translations = array(
|
||||
'Type has been created.' => 'Tip je ustvarjen.',
|
||||
'Alter type' => 'Spremeni tip',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php sl` to update this file
|
||||
|
@@ -318,3 +318,5 @@ $translations = array(
|
||||
'Type has been created.' => 'тип је креиран.',
|
||||
'Alter type' => 'Уреди тип',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php sr` to update this file
|
||||
|
@@ -348,3 +348,5 @@ $translations = array(
|
||||
'Type has been created.' => 'Typ har skapats.',
|
||||
'Alter type' => 'Ändra typ',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php sv` to update this file
|
||||
|
@@ -266,3 +266,5 @@ $translations = array(
|
||||
'Edit all' => 'அனைத்தையும் தொகு',
|
||||
'HH:MM:SS' => 'HH:MM:SS',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php ta` to update this file
|
||||
|
@@ -267,3 +267,5 @@ $translations = array(
|
||||
'Edit all' => 'แก้ไขทั้งหมด',
|
||||
'HH:MM:SS' => 'HH:MM:SS',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php th` to update this file
|
||||
|
@@ -342,3 +342,5 @@ $translations = array(
|
||||
'Type has been created.' => 'Tür oluşturuldu.',
|
||||
'Alter type' => 'Türü değiştir',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php tr` to update this file
|
||||
|
@@ -345,3 +345,5 @@ $translations = array(
|
||||
'Unknown error.' => 'Невідома помилка.',
|
||||
'Database does not support password.' => 'База даних не підтримує пароль.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php uk` to update this file
|
||||
|
365
adminer/lang/uz.inc.php
Normal file
365
adminer/lang/uz.inc.php
Normal file
@@ -0,0 +1,365 @@
|
||||
<?php
|
||||
namespace Adminer;
|
||||
|
||||
$translations = array(
|
||||
// label for database system selection (MySQL, SQLite, ...)
|
||||
'System' => 'Tizim',
|
||||
'Server' => 'Server',
|
||||
'Username' => 'Foydalanuvchi nomi',
|
||||
'Password' => 'Parol',
|
||||
'Permanent login' => 'Doimiy kirish',
|
||||
'Login' => 'Kirish',
|
||||
'Logout' => 'Chiqish',
|
||||
'Logged as: %s' => 'Siz kirgansiz: %s',
|
||||
'Logout successful.' => 'Muvaffaqiyatli chiqdingiz.',
|
||||
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Adminer dasturidan foydalanganingiz uchun rahmat, <a href="https://www.adminer.org/en/donation/">xayriya qilishni</a> o\'ylab ko\'ring.',
|
||||
'Loaded plugins' => 'Yuklangan plaginlar',
|
||||
'%s must <a%s>return an array</a>.' => '%s <a%s>massiv qaytarishi</a> kerak.',
|
||||
'<a%s>Configure</a> %s in %s.' => '%s ni %s ichida <a%s>sozlang</a>.',
|
||||
'Invalid credentials.' => 'Noto\'g\'ri ma\'lumotlar.',
|
||||
'There is a space in the input password which might be the cause.' => 'Kiritilgan parolda bo\'sh joy bor, bu sabab bo\'lishi mumkin.',
|
||||
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer parolsiz ma\'lumotlar bazasiga kirishni qo\'llab-quvvatlamaydi, <a href="https://www.adminer.org/en/password/"%s>ko\'proq ma\'lumot</a>.',
|
||||
'Database does not support password.' => 'Ma\'lumotlar bazasi parolni qo\'llab-quvvatlamaydi.',
|
||||
'Too many unsuccessful logins, try again in %d minute(s).' => array('Juda ko\'p muvaffaqiyatsiz urinishlar, %d daqiqadan so\'ng qayta urining.', 'Juda ko\'p muvaffaqiyatsiz urinishlar, %d daqiqadan so\'ng qayta urining.'),
|
||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Asosiy parol muddati tugadi. Uni doimiy qilish uchun %s usulini <a href="https://www.adminer.org/en/extension/"%s>amalga oshiring</a>.',
|
||||
'Language' => 'Til',
|
||||
'Invalid CSRF token. Send the form again.' => 'Noto\'g\'ri CSRF belgisi. Shaklni qayta yuboring.',
|
||||
'If you did not send this request from Adminer then close this page.' => 'Agar bu so\'rovni Adminerdan yuborgan bo\'lmasangiz, ushbu sahifani yoping.',
|
||||
'No extension' => 'Kengaytma yo\'q',
|
||||
// %s contains the list of the extensions, e.g. 'mysqli, PDO_MySQL'
|
||||
'None of the supported PHP extensions (%s) are available.' => 'Qo\'llab-quvvatlanadigan PHP kengaytmalarining (%s) hech biri mavjud emas.',
|
||||
'Connecting to privileged ports is not allowed.' => 'Imtiyozli portlarga ulanishga ruxsat berilmagan.',
|
||||
'Disable %s or enable %s or %s extensions.' => '%s ni o\'chiring yoki %s yoki %s kengaytmalarini yoqing.',
|
||||
'Session support must be enabled.' => 'Sessiya qo\'llab-quvvatlashi yoqilgan bo\'lishi kerak.',
|
||||
'Session expired, please login again.' => 'Sessiya muddati tugadi, iltimos, qayta kiring.',
|
||||
'The action will be performed after successful login with the same credentials.' => 'Amal bir xil ma\'lumotlar bilan muvaffaqiyatli kirishdan so\'ng amalga oshiriladi.',
|
||||
'%s version: %s through PHP extension %s' => '%s versiyasi: %s PHP kengaytmasi %s orqali',
|
||||
'Refresh' => 'Yangilash',
|
||||
|
||||
// text direction - 'ltr' or 'rtl'
|
||||
'ltr' => 'ltr',
|
||||
|
||||
'Privileges' => 'Imtiyozlar',
|
||||
'Create user' => 'Foydalanuvchi yaratish',
|
||||
'User has been dropped.' => 'Foydalanuvchi o\'chirildi.',
|
||||
'User has been altered.' => 'Foydalanuvchi o\'zgartirildi.',
|
||||
'User has been created.' => 'Foydalanuvchi yaratildi.',
|
||||
'Hashed' => 'Xeshlangan',
|
||||
'Column' => 'Ustun',
|
||||
'Routine' => 'Protsedura',
|
||||
'Grant' => 'Berish',
|
||||
'Revoke' => 'Bekor qilish',
|
||||
|
||||
'Process list' => 'Jarayonlar ro\'yxati',
|
||||
'%d process(es) have been killed.' => array('%d jarayon to\'xtatildi.', '%d jarayonlar to\'xtatildi.'),
|
||||
'Kill' => 'To\'xtatish',
|
||||
|
||||
'Variables' => 'O\'zgaruvchilar',
|
||||
'Status' => 'Holat',
|
||||
|
||||
'SQL command' => 'SQL buyrug\'i',
|
||||
'%d query(s) executed OK.' => array('%d so\'rov muvaffaqiyatli bajarildi.', '%d so\'rovlar muvaffaqiyatli bajarildi.'),
|
||||
'Query executed OK, %d row(s) affected.' => array('So\'rov muvaffaqiyatli bajarildi, %d qator o\'zgartirildi.', 'So\'rov muvaffaqiyatli bajarildi, %d qatorlar o\'zgartirildi.'),
|
||||
'No commands to execute.' => 'Bajariladigan buyruqlar yo\'q.',
|
||||
'Error in query' => 'So\'rovda xatolik',
|
||||
'Unknown error.' => 'Noma\'lum xatolik.',
|
||||
'Warnings' => 'Ogohlantirishlar',
|
||||
'ATTACH queries are not supported.' => 'ATTACH so\'rovlari qo\'llab-quvvatlanmaydi.',
|
||||
'Execute' => 'Bajarish',
|
||||
'Stop on error' => 'Xatoda to\'xtash',
|
||||
'Show only errors' => 'Faqat xatolarni ko\'rsatish',
|
||||
// sprintf() format for time of the command
|
||||
'%.3f s' => '%.3f s',
|
||||
'History' => 'Tarix',
|
||||
'Clear' => 'Tozalash',
|
||||
'Edit all' => 'Hammasini tahrirlash',
|
||||
|
||||
'File upload' => 'Fayl yuklash',
|
||||
'From server' => 'Serverdan',
|
||||
'Webserver file %s' => 'Veb-server fayli %s',
|
||||
'Run file' => 'Faylni ishga tushirish',
|
||||
'File does not exist.' => 'Fayl mavjud emas.',
|
||||
'File uploads are disabled.' => 'Fayl yuklash o\'chirilgan.',
|
||||
'Unable to upload a file.' => 'Faylni yuklab bo\'lmadi.',
|
||||
'Maximum allowed file size is %sB.' => 'Maksimal ruxsat etilgan fayl hajmi %sB.',
|
||||
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Juda katta POST ma\'lumotlari. Ma\'lumotlarni kamaytiring yoki %s konfiguratsiya direktivasini oshiring.',
|
||||
'You can upload a big SQL file via FTP and import it from server.' => 'Katta SQL faylini FTP orqali yuklab, uni serverdan import qilishingiz mumkin.',
|
||||
'You are offline.' => 'Siz oflayndasiz.',
|
||||
|
||||
'Export' => 'Eksport',
|
||||
'Output' => 'Natija',
|
||||
'open' => 'ochish',
|
||||
'save' => 'saqlash',
|
||||
'Saving' => 'Saqlanmoqda',
|
||||
'Format' => 'Format',
|
||||
'Data' => 'Ma\'lumotlar',
|
||||
|
||||
'Database' => 'Ma\'lumotlar bazasi',
|
||||
'DB' => 'MB',
|
||||
'Use' => 'Foydalanish',
|
||||
'Select database' => 'Ma\'lumotlar bazasini tanlash',
|
||||
'Invalid database.' => 'Noto\'g\'ri ma\'lumotlar bazasi.',
|
||||
'Database has been dropped.' => 'Ma\'lumotlar bazasi o\'chirildi.',
|
||||
'Databases have been dropped.' => 'Ma\'lumotlar bazalari o\'chirildi.',
|
||||
'Database has been created.' => 'Ma\'lumotlar bazasi yaratildi.',
|
||||
'Database has been renamed.' => 'Ma\'lumotlar bazasi qayta nomlandi.',
|
||||
'Database has been altered.' => 'Ma\'lumotlar bazasi o\'zgartirildi.',
|
||||
'Alter database' => 'Ma\'lumotlar bazasini o\'zgartirish',
|
||||
'Create database' => 'Ma\'lumotlar bazasini yaratish',
|
||||
'Database schema' => 'Ma\'lumotlar bazasi sxemasi',
|
||||
|
||||
// link to current database schema layout
|
||||
'Permanent link' => 'Doimiy havola',
|
||||
|
||||
// thousands separator - must contain single byte
|
||||
',' => ' ',
|
||||
'0123456789' => '0123456789',
|
||||
'Engine' => 'Dvigatel',
|
||||
'Collation' => 'Kodlash',
|
||||
'Data Length' => 'Ma\'lumotlar hajmi',
|
||||
'Index Length' => 'Indeks hajmi',
|
||||
'Data Free' => 'Bo\'sh ma\'lumotlar',
|
||||
'Rows' => 'Qatorlar',
|
||||
'%d in total' => 'Jami %d',
|
||||
'Analyze' => 'Tahlil qilish',
|
||||
'Optimize' => 'Optimallash',
|
||||
'Vacuum' => 'Tozalash',
|
||||
'Check' => 'Tekshirish',
|
||||
'Repair' => 'Ta\'mirlash',
|
||||
'Truncate' => 'Bo\'shatish',
|
||||
'Tables have been truncated.' => 'Jadvallar bo\'shatildi.',
|
||||
'Move to other database' => 'Boshqa ma\'lumotlar bazasiga ko\'chirish',
|
||||
'Move' => 'Ko\'chirish',
|
||||
'Tables have been moved.' => 'Jadvallar ko\'chirildi.',
|
||||
'Copy' => 'Nusxalash',
|
||||
'Tables have been copied.' => 'Jadvallar nusxalandi.',
|
||||
'overwrite' => 'qayta yozish',
|
||||
|
||||
'Routines' => 'Protseduralar',
|
||||
'Routine has been called, %d row(s) affected.' => array('Protsedura chaqirildi, %d qator o\'zgartirildi.', 'Protsedura chaqirildi, %d qatorlar o\'zgartirildi.'),
|
||||
'Call' => 'Chaqirish',
|
||||
'Parameter name' => 'Parametr nomi',
|
||||
'Create procedure' => 'Protsedura yaratish',
|
||||
'Create function' => 'Funksiya yaratish',
|
||||
'Routine has been dropped.' => 'Protsedura o\'chirildi.',
|
||||
'Routine has been altered.' => 'Protsedura o\'zgartirildi.',
|
||||
'Routine has been created.' => 'Protsedura yaratildi.',
|
||||
'Alter function' => 'Funksiyani o\'zgartirish',
|
||||
'Alter procedure' => 'Protseduranni o\'zgartirish',
|
||||
'Return type' => 'Qaytarish turi',
|
||||
|
||||
'Events' => 'Hodisalar',
|
||||
'Event has been dropped.' => 'Hodisa o\'chirildi.',
|
||||
'Event has been altered.' => 'Hodisa o\'zgartirildi.',
|
||||
'Event has been created.' => 'Hodisa yaratildi.',
|
||||
'Alter event' => 'Hodisani o\'zgartirish',
|
||||
'Create event' => 'Hodisa yaratish',
|
||||
'At given time' => 'Belgilangan vaqtda',
|
||||
'Every' => 'Har bir',
|
||||
'Schedule' => 'Jadval',
|
||||
'Start' => 'Boshlash',
|
||||
'End' => 'Tugatish',
|
||||
'On completion preserve' => 'Yakunlangandan so\'ng saqlash',
|
||||
|
||||
'Tables' => 'Jadvallar',
|
||||
'Tables and views' => 'Jadvallar va ko\'rinishlar',
|
||||
'Table' => 'Jadval',
|
||||
'No tables.' => 'Jadvallar yo\'q.',
|
||||
'Alter table' => 'Jadvalni o\'zgartirish',
|
||||
'Create table' => 'Jadval yaratish',
|
||||
'Table has been dropped.' => 'Jadval o\'chirildi.',
|
||||
'Tables have been dropped.' => 'Jadvallar o\'chirildi.',
|
||||
'Tables have been optimized.' => 'Jadvallar optimallashtirildi.',
|
||||
'Table has been altered.' => 'Jadval o\'zgartirildi.',
|
||||
'Table has been created.' => 'Jadval yaratildi.',
|
||||
'Table name' => 'Jadval nomi',
|
||||
'Show structure' => 'Tuzilishni ko\'rsatish',
|
||||
'engine' => 'dvigatel',
|
||||
'collation' => 'kodlash',
|
||||
'Column name' => 'Ustun nomi',
|
||||
'Type' => 'Tur',
|
||||
'Length' => 'Uzunlik',
|
||||
'Auto Increment' => 'Avto ko\'payish',
|
||||
'Options' => 'Variantlar',
|
||||
'Comment' => 'Izoh',
|
||||
'Default value' => 'Standart qiymat',
|
||||
'Default values' => 'Standart qiymatlar',
|
||||
'Drop' => 'O\'chirish',
|
||||
'Drop %s?' => '%s ni o\'chirasizmi?',
|
||||
'Are you sure?' => 'Ishonchingiz komilmi?',
|
||||
'Size' => 'Hajm',
|
||||
'Compute' => 'Hisoblash',
|
||||
'Move up' => 'Yuqoriga ko\'chirish',
|
||||
'Move down' => 'Pastga ko\'chirish',
|
||||
'Remove' => 'Olib tashlash',
|
||||
'Maximum number of allowed fields exceeded. Please increase %s.' => 'Ruxsat etilgan maydonlar soni oshib ketdi. Iltimos, %s ni oshiring.',
|
||||
|
||||
'Partition by' => 'Bo\'lish mezon',
|
||||
'Partitions' => 'Bo\'limlar',
|
||||
'Partition name' => 'Bo\'lim nomi',
|
||||
'Values' => 'Qiymatlar',
|
||||
|
||||
'View' => 'Ko\'rinish',
|
||||
'Materialized view' => 'Moddiy ko\'rinish',
|
||||
'View has been dropped.' => 'Ko\'rinish o\'chirildi.',
|
||||
'View has been altered.' => 'Ko\'rinish o\'zgartirildi.',
|
||||
'View has been created.' => 'Ko\'rinish yaratildi.',
|
||||
'Alter view' => 'Ko\'rinishni o\'zgartirish',
|
||||
'Create view' => 'Ko\'rinish yaratish',
|
||||
|
||||
'Indexes' => 'Indekslar',
|
||||
'Indexes have been altered.' => 'Indekslar o\'zgartirildi.',
|
||||
'Alter indexes' => 'Indekslarni o\'zgartirish',
|
||||
'Add next' => 'Keyingisini qo\'shish',
|
||||
'Index Type' => 'Indeks turi',
|
||||
'length' => 'uzunlik',
|
||||
|
||||
'Foreign keys' => 'Tashqi kalitlar',
|
||||
'Foreign key' => 'Tashqi kalit',
|
||||
'Foreign key has been dropped.' => 'Tashqi kalit o\'chirildi.',
|
||||
'Foreign key has been altered.' => 'Tashqi kalit o\'zgartirildi.',
|
||||
'Foreign key has been created.' => 'Tashqi kalit yaratildi.',
|
||||
'Target table' => 'Maqsad jadvali',
|
||||
'Change' => 'O\'zgartirish',
|
||||
'Source' => 'Manba',
|
||||
'Target' => 'Maqsad',
|
||||
'Add column' => 'Ustun qo\'shish',
|
||||
'Alter' => 'O\'zgartirish',
|
||||
'Add foreign key' => 'Tashqi kalit qo\'shish',
|
||||
'ON DELETE' => 'O\'CHIRILGANDA',
|
||||
'ON UPDATE' => 'YANGILANGANDA',
|
||||
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'Manba va maqsad ustunlari bir xil ma\'lumot turiga ega bo\'lishi kerak, maqsad ustunlarda indeks bo\'lishi kerak va havolalar qilingan ma\'lumotlar mavjud bo\'lishi kerak.',
|
||||
|
||||
'Triggers' => 'Triggerlar',
|
||||
'Add trigger' => 'Trigger qo\'shish',
|
||||
'Trigger has been dropped.' => 'Trigger o\'chirildi.',
|
||||
'Trigger has been altered.' => 'Trigger o\'zgartirildi.',
|
||||
'Trigger has been created.' => 'Trigger yaratildi.',
|
||||
'Alter trigger' => 'Triggerni o\'zgartirish',
|
||||
'Create trigger' => 'Trigger yaratish',
|
||||
'Time' => 'Vaqt',
|
||||
'Event' => 'Hodisa',
|
||||
'Name' => 'Nomi',
|
||||
|
||||
'select' => 'tanlash',
|
||||
'Select' => 'Tanlash',
|
||||
'Select data' => 'Ma\'lumotlarni tanlash',
|
||||
'Functions' => 'Funksiyalar',
|
||||
'Aggregation' => 'Agregatsiya',
|
||||
'Search' => 'Qidirish',
|
||||
'anywhere' => 'hamma joyda',
|
||||
'Search data in tables' => 'Jadvallarda ma\'lumotlarni qidirish',
|
||||
'Sort' => 'Saralash',
|
||||
'descending' => 'kamayish bo\'yicha',
|
||||
'Limit' => 'Cheklov',
|
||||
'Limit rows' => 'Qatorlarni cheklash',
|
||||
'Text length' => 'Matn uzunligi',
|
||||
'Action' => 'Amal',
|
||||
'Full table scan' => 'To\'liq jadval skanerlash',
|
||||
'Unable to select the table' => 'Jadvalni tanlab bo\'lmadi',
|
||||
'No rows.' => 'Qatorlar yo\'q.',
|
||||
// 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 qator', '%d qatorlar'),
|
||||
'Page' => 'Sahifa',
|
||||
'last' => 'oxirgi',
|
||||
'Load more data' => 'Ko\'proq ma\'lumot yuklash',
|
||||
'Loading' => 'Yuklanmoqda',
|
||||
'Whole result' => 'Butun natija',
|
||||
'%d byte(s)' => array('%d bayt', '%d baytlar'),
|
||||
|
||||
'Import' => 'Import',
|
||||
'%d row(s) have been imported.' => array('%d qator import qilindi.', '%d qatorlar import qilindi.'),
|
||||
'File must be in UTF-8 encoding.' => 'Fayl UTF-8 kodlashda bo\'lishi kerak.',
|
||||
|
||||
// in-place editing in select
|
||||
'Modify' => 'O\'zgartirish',
|
||||
'Ctrl+click on a value to modify it.' => 'Qiymatni o\'zgartirish uchun Ctrl+bosing.',
|
||||
'Use edit link to modify this value.' => 'Bu qiymatni o\'zgartirish uchun tahrir havolasidan foydalaning.',
|
||||
|
||||
// %s can contain auto-increment value, e.g. ' 123'
|
||||
'Item%s has been inserted.' => 'Element%s kiritildi.',
|
||||
'Item has been deleted.' => 'Element o\'chirildi.',
|
||||
'Item has been updated.' => 'Element yangilandi.',
|
||||
'%d item(s) have been affected.' => array('%d element o\'zgartirildi.', '%d elementlar o\'zgartirildi.'),
|
||||
'New item' => 'Yangi element',
|
||||
'original' => 'asl',
|
||||
// label for value '' in enum data type
|
||||
'empty' => 'bo\'sh',
|
||||
'edit' => 'tahrirlash',
|
||||
'Edit' => 'Tahrirlash',
|
||||
'Insert' => 'Kiritish',
|
||||
'Save' => 'Saqlash',
|
||||
'Save and continue edit' => 'Saqlash va tahrirlashni davom ettirish',
|
||||
'Save and insert next' => 'Saqlash va keyingisini kiritish',
|
||||
'Selected' => 'Tanlangan',
|
||||
'Clone' => 'Klonlash',
|
||||
'Delete' => 'O\'chirish',
|
||||
'You have no privileges to update this table.' => 'Bu jadvalni yangilash uchun sizda huquqlar yo\'q.',
|
||||
|
||||
'E-mail' => 'E-pochta',
|
||||
'From' => 'Kimdan',
|
||||
'Subject' => 'Mavzu',
|
||||
'Attachments' => 'Ilovalar',
|
||||
'Send' => 'Yuborish',
|
||||
'%d e-mail(s) have been sent.' => array('%d e-pochta yuborildi.', '%d e-pochtalar yuborildi.'),
|
||||
|
||||
// data type descriptions
|
||||
'Numbers' => 'Raqamlar',
|
||||
'Date and time' => 'Sana va vaqt',
|
||||
'Strings' => 'Matnlar',
|
||||
'Binary' => 'Ikkilik',
|
||||
'Lists' => 'Ro\'yxatlar',
|
||||
'Network' => 'Tarmoq',
|
||||
'Geometry' => 'Geometriya',
|
||||
'Relations' => 'Munosabatlar',
|
||||
|
||||
'Editor' => 'Muharrir',
|
||||
// date format in Editor: $1 yyyy, $2 yy, $3 mm, $4 m, $5 dd, $6 d
|
||||
'$1-$3-$5' => '$5.$3.$1',
|
||||
// hint for date format - use language equivalents for day, month and year shortcuts
|
||||
'[yyyy]-mm-dd' => 'dd.mm.[yyyy]',
|
||||
// hint for time format - use language equivalents for hour, minute and second shortcuts
|
||||
'HH:MM:SS' => 'SS:MM:SS',
|
||||
'now' => 'hozir',
|
||||
'yes' => 'ha',
|
||||
'no' => 'yo\'q',
|
||||
|
||||
// general SQLite error in create, drop or rename database
|
||||
'File exists.' => 'Fayl mavjud.',
|
||||
'Please use one of the extensions %s.' => 'Iltimos, kengaytmalardan birini %s foydalaning.',
|
||||
|
||||
// PostgreSQL and MS SQL schema support
|
||||
'Alter schema' => 'Sxemani o\'zgartirish',
|
||||
'Create schema' => 'Sxema yaratish',
|
||||
'Schema has been dropped.' => 'Sxema o\'chirildi.',
|
||||
'Schema has been created.' => 'Sxema yaratildi.',
|
||||
'Schema has been altered.' => 'Sxema o\'zgartirildi.',
|
||||
'Schema' => 'Sxema',
|
||||
'Invalid schema.' => 'Noto\'g\'ri sxema.',
|
||||
|
||||
// PostgreSQL sequences support
|
||||
'Sequences' => 'Ketma-ketliklar',
|
||||
'Create sequence' => 'Ketma-ketlik yaratish',
|
||||
'Sequence has been dropped.' => 'Ketma-ketlik o\'chirildi.',
|
||||
'Sequence has been created.' => 'Ketma-ketlik yaratildi.',
|
||||
'Sequence has been altered.' => 'Ketma-ketlik o\'zgartirildi.',
|
||||
'Alter sequence' => 'Ketma-ketlikni o\'zgartirish',
|
||||
|
||||
// PostgreSQL user types support
|
||||
'User types' => 'Foydalanuvchi turlari',
|
||||
'Create type' => 'Tur yaratish',
|
||||
'Type has been dropped.' => 'Tur o\'chirildi.',
|
||||
'Type has been created.' => 'Tur yaratildi.',
|
||||
'Alter type' => 'Turni o\'zgartirish',
|
||||
|
||||
// Table check constraints
|
||||
'Checks' => 'Tekshirishlar',
|
||||
'Create check' => 'Tekshirish yaratish',
|
||||
'Alter check' => 'Tekshirishni o\'zgartirish',
|
||||
'Check has been created.' => 'Tekshirish yaratildi.',
|
||||
'Check has been altered.' => 'Tekshirish o\'zgartirildi.',
|
||||
'Check has been dropped.' => 'Tekshirish o\'chirildi.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php uz` to update this file
|
@@ -327,3 +327,5 @@ $translations = array(
|
||||
'Type has been created.' => 'Đã tạo kiểu.',
|
||||
'Alter type' => 'Sửa kiểu dữ liệu',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php vi` to update this file
|
||||
|
@@ -13,6 +13,9 @@ $translations = array(
|
||||
'Logged as: %s' => 'Xx: %s',
|
||||
'Logout successful.' => 'Xx.',
|
||||
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Xx <a href="https://www.adminer.org/en/donation/">xx</a>.',
|
||||
'Loaded plugins' => 'Xx',
|
||||
'%s must <a%s>return an array</a>.' => '%s xx <a%s>xx</a>.',
|
||||
'<a%s>Configure</a> %s in %s.' => '<a%s>Xx</a> %s xx %s.',
|
||||
'Invalid credentials.' => 'Xx.',
|
||||
'There is a space in the input password which might be the cause.' => 'Xx.',
|
||||
'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>.',
|
||||
@@ -358,3 +361,5 @@ $translations = array(
|
||||
'Check has been altered.' => 'Xx.',
|
||||
'Check has been dropped.' => 'Xx.',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php xx` to update this file
|
||||
|
@@ -348,3 +348,5 @@ $translations = array(
|
||||
'Type has been created.' => '已建立類型。',
|
||||
'Alter type' => '修改類型',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php zh-tw` to update this file
|
||||
|
@@ -348,3 +348,5 @@ $translations = array(
|
||||
'Type has been created.' => '已创建类型。',
|
||||
'Alter type' => '修改类型',
|
||||
);
|
||||
|
||||
// run `php ../../lang.php zh` to update this file
|
||||
|
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
function adminer_object() {
|
||||
// required to run any plugin
|
||||
include_once "../plugins/plugin.php";
|
||||
|
||||
// autoloader
|
||||
foreach (glob("../plugins/*.php") as $filename) {
|
||||
include_once $filename;
|
||||
}
|
||||
|
||||
// enable extra drivers just by including them
|
||||
//~ include "../plugins/drivers/simpledb.php";
|
||||
|
||||
$plugins = array(
|
||||
// specify enabled plugins here
|
||||
new AdminerDatabaseHide(array('information_schema')),
|
||||
new AdminerDumpJson,
|
||||
new AdminerDumpBz2,
|
||||
new AdminerDumpZip,
|
||||
new AdminerDumpXml,
|
||||
new AdminerDumpAlter,
|
||||
//~ new AdminerSqlLog("past-" . rtrim(`git describe --tags --abbrev=0`) . ".sql"),
|
||||
//~ new AdminerTinymce("../externals/tinymce/jscripts/tiny_mce/tiny_mce_dev.js"),
|
||||
new AdminerFileUpload(""),
|
||||
new AdminerJsonColumn,
|
||||
new AdminerSlugify,
|
||||
new AdminerTranslation,
|
||||
new AdminerForeignSystem,
|
||||
new AdminerEnumOption,
|
||||
new AdminerTablesFilter,
|
||||
new AdminerEditForeign,
|
||||
);
|
||||
|
||||
/* It is possible to combine customization and plugins:
|
||||
class AdminerCustomization extends AdminerPlugin {
|
||||
}
|
||||
return new AdminerCustomization($plugins);
|
||||
*/
|
||||
|
||||
return new AdminerPlugin($plugins);
|
||||
}
|
||||
|
||||
// include original Adminer or Adminer Editor (usually named adminer.php)
|
||||
include "./index.php";
|
@@ -14,8 +14,8 @@ if (!$result) {
|
||||
|
||||
echo "<form action=''><p>\n";
|
||||
hidden_fields_get();
|
||||
echo "<input type='hidden' name='db' value='" . h(DB) . "'>\n";
|
||||
echo ($grant ? "" : "<input type='hidden' name='grant' value=''>\n");
|
||||
echo input_hidden("db", DB);
|
||||
echo ($grant ? "" : input_hidden("grant"));
|
||||
echo "<table class='odds'>\n";
|
||||
echo "<thead><tr><th>" . lang('Username') . "<th>" . lang('Server') . "<th></thead>\n";
|
||||
|
||||
|
@@ -9,6 +9,11 @@ $row["fields"] = (array) $row["fields"];
|
||||
if ($_POST && !process_fields($row["fields"]) && !$error) {
|
||||
$orig = routine($_GET["procedure"], $routine);
|
||||
$temp_name = "$row[name]_adminer_" . uniqid();
|
||||
foreach ($row["fields"] as $key => $field) {
|
||||
if ($field["field"] == "") {
|
||||
unset($row["fields"][$key]);
|
||||
}
|
||||
}
|
||||
drop_create(
|
||||
"DROP $routine " . routine_id($PROCEDURE, $orig),
|
||||
create_routine($routine, $row),
|
||||
@@ -26,14 +31,19 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
|
||||
|
||||
page_header(($PROCEDURE != "" ? (isset($_GET["function"]) ? lang('Alter function') : lang('Alter procedure')) . ": " . h($PROCEDURE) : (isset($_GET["function"]) ? lang('Create function') : lang('Create procedure'))), $error);
|
||||
|
||||
if (!$_POST && $PROCEDURE != "") {
|
||||
$row = routine($_GET["procedure"], $routine);
|
||||
$row["name"] = $PROCEDURE;
|
||||
if (!$_POST) {
|
||||
if ($PROCEDURE == "") {
|
||||
$row["language"] = "sql";
|
||||
} else {
|
||||
$row = routine($_GET["procedure"], $routine);
|
||||
$row["name"] = $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">
|
||||
@@ -58,5 +68,5 @@ if (isset($_GET["function"])) {
|
||||
<?php if ($PROCEDURE != "") { ?>
|
||||
<input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $PROCEDURE)); ?>
|
||||
<?php } ?>
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
<?php echo input_token(); ?>
|
||||
</form>
|
||||
|
@@ -56,7 +56,7 @@ if (support("kill")) {
|
||||
echo ($i + 1) . "/" . lang('%d in total', max_connections());
|
||||
echo "<p><input type='submit' value='" . lang('Kill') . "'>\n";
|
||||
}
|
||||
echo input_token();
|
||||
?>
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
</form>
|
||||
<?php echo script("tableCheck();"); ?>
|
||||
|
@@ -52,9 +52,9 @@ foreach (table_status('', true) as $table => $table_status) {
|
||||
?>
|
||||
<div id="schema" style="height: <?php echo $top; ?>em;">
|
||||
<script<?php echo nonce(); ?>>
|
||||
qs('#schema').onselectstart = function () { return false; };
|
||||
var tablePos = {<?php echo implode(",", $table_pos_js) . "\n"; ?>};
|
||||
var em = qs('#schema').offsetHeight / <?php echo $top; ?>;
|
||||
qs('#schema').onselectstart = () => false;
|
||||
const tablePos = {<?php echo implode(",", $table_pos_js) . "\n"; ?>};
|
||||
const em = qs('#schema').offsetHeight / <?php echo $top; ?>;
|
||||
document.onmousemove = schemaMousemove;
|
||||
document.onmouseup = partialArg(schemaMouseup, '<?php echo js_escape(DB); ?>');
|
||||
</script>
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -34,6 +34,6 @@ if (!$row) {
|
||||
if ($_GET["ns"] != "") {
|
||||
echo "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm(lang('Drop %s?', $_GET["ns"])) . "\n";
|
||||
}
|
||||
echo input_token();
|
||||
?>
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
</form>
|
||||
|
@@ -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", "?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ $indexes = indexes($TABLE);
|
||||
$fields = fields($TABLE);
|
||||
$foreign_keys = column_foreign_keys($TABLE);
|
||||
$oid = $table_status["Oid"];
|
||||
parse_str($_COOKIE["adminer_import"], $adminer_import);
|
||||
$adminer_import = get_settings("adminer_import");
|
||||
|
||||
$rights = array(); // privilege => 0
|
||||
$columns = array(); // selectable columns
|
||||
@@ -83,7 +83,7 @@ if ($_POST && !$error) {
|
||||
}
|
||||
$where_check = ($where_check ? "\nWHERE " . implode(" AND ", $where_check) : "");
|
||||
if ($_POST["export"]) {
|
||||
cookie("adminer_import", "output=" . urlencode($_POST["output"]) . "&format=" . urlencode($_POST["format"]));
|
||||
save_settings(array("output" => $_POST["output"], "format" => $_POST["format"]), "adminer_import");
|
||||
dump_headers($TABLE);
|
||||
$adminer->dumpTable($TABLE, "");
|
||||
$from = ($select ? implode(", ", $select) : "*")
|
||||
@@ -100,6 +100,7 @@ if ($_POST && !$error) {
|
||||
$query = implode(" UNION ALL ", $union);
|
||||
}
|
||||
$adminer->dumpData($TABLE, "table", $query);
|
||||
$adminer->dumpFooter();
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -124,11 +125,11 @@ if ($_POST && !$error) {
|
||||
$result = ($_POST["delete"]
|
||||
? $driver->delete($TABLE, $where_check)
|
||||
: ($_POST["clone"]
|
||||
? queries("INSERT $query$where_check")
|
||||
? queries("INSERT $query$where_check" . $driver->insertReturning($TABLE))
|
||||
: $driver->update($TABLE, $set, $where_check)
|
||||
)
|
||||
);
|
||||
$affected = $connection->affected_rows;
|
||||
$affected = $connection->affected_rows + (is_object($result) ? $result->num_rows : 0); // PostgreSQL with RETURNING fills num_rows
|
||||
} else {
|
||||
foreach ((array) $_POST["check"] as $val) {
|
||||
// where is not unique so OR can't be used
|
||||
@@ -149,7 +150,7 @@ if ($_POST && !$error) {
|
||||
}
|
||||
$message = lang('%d item(s) have been affected.', $affected);
|
||||
if ($_POST["clone"] && $result && $affected == 1) {
|
||||
$last_id = last_id();
|
||||
$last_id = last_id($result);
|
||||
if ($last_id) {
|
||||
$message = lang('Item%s has been inserted.', " $last_id");
|
||||
}
|
||||
@@ -194,7 +195,7 @@ if ($_POST && !$error) {
|
||||
} elseif (!preg_match('~~u', $file)) {
|
||||
$error = lang('File must be in UTF-8 encoding.');
|
||||
} else {
|
||||
cookie("adminer_import", "output=" . urlencode($adminer_import["output"]) . "&format=" . urlencode($_POST["separator"]));
|
||||
save_settings(array("output" => $adminer_import["output"], "format" => $_POST["separator"]), "adminer_import");
|
||||
$result = true;
|
||||
$cols = array_keys($fields);
|
||||
preg_match_all('~(?>"[^"]*"|[^"\r\n]+)+~', $file, $matches);
|
||||
@@ -257,8 +258,8 @@ if (!$columns && support("table")) {
|
||||
echo "<form action='' id='form'>\n";
|
||||
echo "<div style='display: none;'>";
|
||||
hidden_fields_get();
|
||||
echo (DB != "" ? '<input type="hidden" name="db" value="' . h(DB) . '">' . (isset($_GET["ns"]) ? '<input type="hidden" name="ns" value="' . h($_GET["ns"]) . '">' : "") : ""); // not used in Editor
|
||||
echo '<input type="hidden" name="select" value="' . h($TABLE) . '">';
|
||||
echo (DB != "" ? input_hidden("db", DB) . (isset($_GET["ns"]) ? input_hidden("ns", $_GET["ns"]) : "") : ""); // not used in Editor
|
||||
echo input_hidden("select", $TABLE);
|
||||
echo "</div>\n";
|
||||
$adminer->selectColumnsPrint($select, $columns);
|
||||
$adminer->selectSearchPrint($where, $search_columns, $indexes);
|
||||
@@ -451,8 +452,8 @@ 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"]);
|
||||
echo "<td id='$id'";
|
||||
$text = preg_match('~text|json|lob~', $field["type"]);
|
||||
echo "<td id='$id'" . (preg_match(number_type(), $field["type"]) && is_numeric(strip_tags($val)) ? " class='number'" : "");
|
||||
if (($_GET["modify"] && $editable) || $value !== null) {
|
||||
$h_value = h($value !== null ? $value : $row[$key]);
|
||||
echo ">" . ($text ? "<textarea name='$id' cols='30' rows='" . (substr_count($row[$key], "\n") + 1) . "'>$h_value</textarea>" : "<input name='$id' value='$h_value' size='$lengths[$key]'>");
|
||||
@@ -490,7 +491,7 @@ if (!$columns && support("table")) {
|
||||
$found_rows = ($is_group ? false : found_rows($table_status, $where));
|
||||
if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) {
|
||||
// slow with big tables
|
||||
$found_rows = reset(slow_query(count_rows($TABLE, $where, $is_group, $group)));
|
||||
$found_rows = first(slow_query(count_rows($TABLE, $where, $is_group, $group)));
|
||||
} else {
|
||||
$exact_count = false;
|
||||
}
|
||||
@@ -543,7 +544,7 @@ if (!$columns && support("table")) {
|
||||
echo "<fieldset>";
|
||||
echo "<legend>" . lang('Whole result') . "</legend>";
|
||||
$display_rows = ($exact_count ? "" : "~ ") . $found_rows;
|
||||
$onclick = "var checked = formChecked(this, /check/); selectCount('selected', this.checked ? '$display_rows' : checked); selectCount('selected2', this.checked || !checked ? '$display_rows' : checked);";
|
||||
$onclick = "const checked = formChecked(this, /check/); selectCount('selected', this.checked ? '$display_rows' : checked); selectCount('selected2', this.checked || !checked ? '$display_rows' : checked);";
|
||||
echo checkbox("all", 1, 0, ($found_rows !== false ? ($exact_count ? "" : "~ ") . lang('%d row(s)', $found_rows) : ""), $onclick) . "\n";
|
||||
echo "</fieldset>\n";
|
||||
|
||||
@@ -587,13 +588,13 @@ 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>";
|
||||
}
|
||||
|
||||
echo "<input type='hidden' name='token' value='$token'>\n";
|
||||
echo input_token();
|
||||
echo "</form>\n";
|
||||
echo (!$group && $select ? "" : script("tableCheck();"));
|
||||
}
|
||||
|
@@ -32,6 +32,6 @@ if (!$row) {
|
||||
if ($SEQUENCE != "") {
|
||||
echo "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm(lang('Drop %s?', $SEQUENCE)) . "\n";
|
||||
}
|
||||
echo input_token();
|
||||
?>
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
</form>
|
||||
|
@@ -2,9 +2,11 @@
|
||||
namespace Adminer;
|
||||
|
||||
if (!$error && $_POST["export"]) {
|
||||
save_settings(array("output" => $_POST["output"], "format" => $_POST["format"]), "adminer_import");
|
||||
dump_headers("sql");
|
||||
$adminer->dumpTable("", "");
|
||||
$adminer->dumpData("", "table", $_POST["query"]);
|
||||
$adminer->dumpFooter();
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -30,7 +32,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
|
||||
@@ -40,7 +42,7 @@ if (!$error && $_POST) {
|
||||
|
||||
if ($query != "" && strlen($query) < 1e6) { // don't add big queries
|
||||
$q = $query . (preg_match("~;[ \t\r\n]*\$~", $query) ? "" : ";"); //! doesn't work with DELIMITER |
|
||||
if (!$history || reset(end($history)) != $q) { // no repeated queries
|
||||
if (!$history || first(end($history)) != $q) { // no repeated queries
|
||||
restart_session();
|
||||
$history[] = array($q, time()); //! add elapsed time
|
||||
set_session("queries", $history_all); // required because reference is unlinked by stop_session()
|
||||
@@ -63,7 +65,7 @@ if (!$error && $_POST) {
|
||||
$errors = array();
|
||||
$parse = '[\'"' . (JUSH == "sql" ? '`#' : (JUSH == "sqlite" ? '`[' : (JUSH == "mssql" ? '[' : ''))) . ']|/\*|-- |$' . (JUSH == "pgsql" ? '|\$[^$]*\$' : '');
|
||||
$total_start = microtime(true);
|
||||
parse_str($_COOKIE["adminer_export"], $adminer_export);
|
||||
$adminer_export = get_settings("adminer_import"); // this doesn't offer SQL export so we match the import/export style at select
|
||||
$dump_format = $adminer->dumpFormat();
|
||||
unset($dump_format["sql"]);
|
||||
|
||||
@@ -88,8 +90,8 @@ if (!$error && $_POST) {
|
||||
$pattern = ($found == '/*' ? '\*/'
|
||||
: ($found == '[' ? ']'
|
||||
: (preg_match('~^-- |^#~', $found) ? "\n"
|
||||
: preg_quote($found) . ($c_style_escapes ? "|\\\\." : "")
|
||||
)));
|
||||
: preg_quote($found) . ($c_style_escapes ? "|\\\\." : "")))
|
||||
);
|
||||
|
||||
while (preg_match("($pattern|\$)s", $query, $match, PREG_OFFSET_CAPTURE, $offset)) {
|
||||
$s = $match[0][0];
|
||||
@@ -157,7 +159,7 @@ if (!$error && $_POST) {
|
||||
if (!$_POST["only_errors"]) {
|
||||
echo "<form action='' method='post'>\n";
|
||||
$num_rows = $result->num_rows;
|
||||
echo "<p>" . ($num_rows ? ($limit && $num_rows > $limit ? lang('%d / ', $limit) : "") . lang('%d row(s)', $num_rows) : "");
|
||||
echo "<p class='sql-footer'>" . ($num_rows ? ($limit && $num_rows > $limit ? lang('%d / ', $limit) : "") . lang('%d row(s)', $num_rows) : "");
|
||||
echo $time;
|
||||
if ($connection2 && preg_match("~^($space|\\()*+SELECT\\b~i", $q) && ($explain = explain($connection2, $q))) {
|
||||
echo ", <a href='#$explain_id'>Explain</a>" . script("qsl('a').onclick = partial(toggle, '$explain_id');", "");
|
||||
@@ -166,8 +168,8 @@ if (!$error && $_POST) {
|
||||
echo ", <a href='#$id'>" . lang('Export') . "</a>" . script("qsl('a').onclick = partial(toggle, '$id');", "") . "<span id='$id' class='hidden'>: "
|
||||
. html_select("output", $adminer->dumpOutput(), $adminer_export["output"]) . " "
|
||||
. html_select("format", $dump_format, $adminer_export["format"])
|
||||
. "<input type='hidden' name='query' value='" . h($q) . "'>"
|
||||
. " <input type='submit' name='export' value='" . lang('Export') . "'><input type='hidden' name='token' value='$token'></span>\n"
|
||||
. input_hidden("query", $q)
|
||||
. "<input type='submit' name='export' value='" . lang('Export') . "'>" . input_token() . "</span>\n"
|
||||
. "</form>\n"
|
||||
;
|
||||
}
|
||||
@@ -179,7 +181,7 @@ if (!$error && $_POST) {
|
||||
stop_session();
|
||||
}
|
||||
if (!$_POST["only_errors"]) {
|
||||
echo "<p class='message' title='" . h($connection->info) . "'>" . lang('Query executed OK, %d row(s) affected.', $affected) . "$time\n";
|
||||
echo "<p class='message' title='" . h(isset($connection->info) ? $connection->info : "") . "'>" . lang('Query executed OK, %d row(s) affected.', $affected) . "$time\n";
|
||||
}
|
||||
}
|
||||
echo ($warnings ? "<div id='$warnings_id' class='hidden'>\n$warnings</div>\n" : "");
|
||||
@@ -233,7 +235,9 @@ if (!isset($_GET["import"])) {
|
||||
echo "<p>";
|
||||
textarea("query", $q, 20);
|
||||
echo script(($_POST ? "" : "qs('textarea').focus();\n") . "qs('#form').onsubmit = partial(sqlSubmit, qs('#form'), '" . js_escape(remove_from_uri("sql|limit|error_stops|only_errors|history")) . "');");
|
||||
echo "<p>$execute\n";
|
||||
echo "<p>";
|
||||
$adminer->sqlPrintAfter();
|
||||
echo "$execute\n";
|
||||
echo lang('Limit rows') . ": <input type='number' name='limit' class='size' value='" . h($_POST ? $_POST["limit"] : $_GET["limit"]) . "'>\n";
|
||||
|
||||
} else {
|
||||
@@ -256,7 +260,7 @@ if (!isset($_GET["import"])) {
|
||||
|
||||
echo checkbox("error_stops", 1, ($_POST ? $_POST["error_stops"] : isset($_GET["import"]) || $_GET["error_stops"]), lang('Stop on error')) . "\n";
|
||||
echo checkbox("only_errors", 1, ($_POST ? $_POST["only_errors"] : isset($_GET["import"]) || $_GET["only_errors"]), lang('Show only errors')) . "\n";
|
||||
echo "<input type='hidden' name='token' value='$token'>\n";
|
||||
echo input_token();
|
||||
|
||||
if (!isset($_GET["import"]) && $history) {
|
||||
print_fieldset("history", lang('History'), $_GET["history"] != "");
|
||||
|
46
adminer/static/dark.css
Normal file
46
adminer/static/dark.css
Normal file
@@ -0,0 +1,46 @@
|
||||
/** @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; }
|
||||
table, 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; }
|
||||
tbody tr:hover td, tbody tr:hover th { background: #133553; }
|
||||
pre.jush { background: #11385a; }
|
||||
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: #efeaea; }
|
||||
.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; }
|
@@ -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; }
|
||||
@@ -10,27 +11,29 @@ h2 { font-size: 150%; margin: 0 0 20px -18px; padding: .8em 1em; border-bottom:
|
||||
h3 { font-weight: normal; font-size: 130%; margin: 1em 0 0; }
|
||||
form { margin: 0; }
|
||||
td table { width: 100%; margin: 0; }
|
||||
table { margin: 1em 20px 0 0; border-collapse: collapse; font-size: 90%; }
|
||||
td, th { border: 1px solid #999; padding: .2em .3em; }
|
||||
table { margin: 1em 20px 0 0; font-size: 90%; border-spacing: 0; border-width: 1px 0 0 1px; }
|
||||
table, td, th { border-color: #999; border-style: solid; }
|
||||
td, th { border-width: 0 1px 1px 0; padding: .2em .3em; margin: 0; }
|
||||
th { background: #eee; text-align: left; }
|
||||
thead { position: sticky; top: 0; }
|
||||
thead th { text-align: center; padding: .2em .5em; }
|
||||
thead td, thead th { background: #ddf; } /* position: sticky; causes Firefox to lose borders */
|
||||
thead td, thead th { background: #ddf; }
|
||||
fieldset { display: inline; vertical-align: top; padding: .5em .8em; margin: .8em .5em 0 0; border: 1px solid #999; }
|
||||
p { margin: .8em 20px 0 0; }
|
||||
img { vertical-align: middle; border: 0; }
|
||||
td img { max-width: 200px; max-height: 200px; }
|
||||
code { background: #eee; }
|
||||
tbody tr:hover td, tbody tr:hover th { background: #eee; }
|
||||
code { font-size: 110%; padding: 1px 2px; background: #eee; }
|
||||
pre { margin: 1em 0 0; }
|
||||
td pre { margin: 0; }
|
||||
pre, textarea { font: 100%/1.25 monospace; }
|
||||
pre, textarea { font: 110%/1.25 monospace; }
|
||||
pre.jush { background: #fff; }
|
||||
pre code { display: block; font-size: 100%; }
|
||||
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,17 +50,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%; }
|
||||
.sql-footer { margin-bottom: 2.5em; }
|
||||
.explain table { white-space: pre; }
|
||||
.icon { width: 18px; height: 18px; background-color: navy; }
|
||||
.icon:hover { background-color: red; }
|
||||
@@ -98,7 +100,7 @@ input.wayoff { left: -1000px; position: absolute; }
|
||||
|
||||
@media all and (max-width: 880px) {
|
||||
.pages { left: auto; }
|
||||
.logout { position: static; padding: 0 1em 1em; }
|
||||
.logout { position: static; padding: 1em; }
|
||||
#menu { position: static; width: auto; }
|
||||
#content { margin-left: 10px; }
|
||||
#lang { position: static; }
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user