1
0
mirror of https://github.com/vrana/adminer.git synced 2025-09-03 19:32:36 +02:00

Compare commits

..

53 Commits
v5.1.1 ... v4.9

Author SHA1 Message Date
Peter Knut
a134193afa Release 4.9 2024-08-21 00:07:57 +02:00
Peter Knut
8a60243459 Add script for exporting compiled adminer variants 2024-08-21 00:07:55 +02:00
Peter Knut
b94636f8a7 Properly set PHP required version 2024-08-20 23:58:16 +02:00
Peter Knut
47ccfa2a2e Avoid showing version on login page (and css/js version)
Thanks to MisterDuval (https://github.com/adminerevo/adminerevo/pull/180)
2024-08-20 23:58:16 +02:00
Adrian Jones
949b39b191 Fix uninitialized string offset
This can happen if you include an unpaired single or double quote, eg: SELECT * FROM table_name WHERE field_name = 'test
2024-08-20 23:58:16 +02:00
Denitz
09a946cb99 Skip dump of generated columns 2024-08-20 23:58:16 +02:00
Peter Knut
13258de188 Fix several bugs and security issues in AdminerFileUpload plugin 2024-08-20 23:58:16 +02:00
Peter Knut
5fe25fca67 Improve readability of the code for the query block 2024-08-20 23:58:16 +02:00
Roy Orbitson
a693e75e32 No-verify plugin breaks others
Does not need to block other plugins from using the head() method.
2024-08-20 23:58:16 +02:00
Peter Knut
de7dd4b64f Improve URL and email detection 2024-08-20 23:58:16 +02:00
Peter Knut
8a70474651 Add PHP extensions to Composer suggestions 2024-08-20 23:58:16 +02:00
Peter Knut
43a0305a23 Fix server URL validation for Oracle connections
Every driver can validate URL host and path by its own rules. Path is forbidden by default, HTTP-based drivers allow only '/' as path and Oracle driver validates path according to the EasyConnect URL format.
2024-08-20 23:58:16 +02:00
Peter Knut
bff6f8ca93 Fix linking external dependencies 2024-03-18 00:35:07 +01:00
Peter Knut
f38c0a1f13 Set saving to file as a default export option 2024-03-17 21:12:35 +01:00
Peter Knut
835c10674b Merge branch 'elastic' 2024-03-17 16:47:53 +01:00
Peter Knut
fc5a46549e Update changes.txt 2024-03-17 16:39:20 +01:00
Peter Knut
898dc9e25e Move Elastic drivers to plugins, driver for Elastic 7+ is the default 2024-03-17 16:39:20 +01:00
Peter Knut
32160b48ae Modify tables hierarchy for Elasticsearch 7
- Properly display list of databases, indexes, aliases and fields.
- Fix search and delete queries.
2024-03-17 16:39:20 +01:00
Peter Knut
6beb07a181 New Elasticsearch 7 plugin as a copy of the old one 2024-03-17 13:53:58 +01:00
Peter Knut
ee42077e54 Improve code readability by using of empty lines 2024-03-17 13:52:59 +01:00
Peter Knut
c3e2e6c58f Compatibility with Elasticsearch 7.14
- Removed empty body from requests.
- Fix deleting records.
2024-03-17 13:52:59 +01:00
Peter Knut
49effeff09 Fix global search in all tables 2024-03-17 13:10:18 +01:00
Peter Knut
857cbf03f2 Fix version condition for deprecated mapping types
Mapping types are still supported in version 6, but only one mapping type can be created.
In version 7, mapping types are deprecated and there is only one system '_doc' mapping type.
See: https://www.elastic.co/guide/en/elasticsearch/reference/6.0/removal-of-types.html
2024-03-17 13:10:18 +01:00
Peter Knut
e8c9164a77 Fix searching if "anywhere" field is selected
- Allow to search only in fields with index.
2024-03-17 13:10:18 +01:00
Peter Knut
01fe709b7a Replace deprecated "filtered" query with "bool" query
- Allow to choose "must", "should", "must_not" condition.
- Add system "_id" column to the field list. So it can be used in search condition.
2024-03-17 13:10:18 +01:00
Peter Knut
90addc5e78 Update changes.txt 2024-03-17 13:10:03 +01:00
Peter Knut
b71a456514 Fix undefined $sql variable 2024-03-17 12:38:57 +01:00
Peter Knut
4d7642a624 Merge branch 'field-privileges' 2024-03-16 23:00:11 +01:00
Peter Knut
9f8dadbb40 Add support for "order" field privilege
In Elasticsearch, text fields are not sortable.
2024-03-16 22:55:10 +01:00
Peter Knut
9968851f1e Add support for "where" field privilege
In Elasticsearch, only indexed fields are searchable.
2024-03-16 22:55:10 +01:00
Peter Knut
a5780e58af Move dependencies from submodules to Composer 2024-03-16 22:45:42 +01:00
Peter Knut
e8b40e3b9d Update hydra and pepa-lintha-dark themes 2024-03-16 22:45:42 +01:00
Peter Knut
35afd4f88c Merge branch 'login-fixes' 2024-03-16 19:15:09 +01:00
Peter Knut
38e4b51256 Update changes.txt 2024-03-16 19:14:17 +01:00
Peter Knut
55a7d3864f Change 'Invalid credentials.' message 2024-03-16 18:02:31 +01:00
Peter Knut
e69583a800 Validate server connection in SimpleDB driver 2024-03-16 18:02:31 +01:00
Peter Knut
338c81e2a3 Validate server connection in Elasticsearch and ClickHouse drivers 2024-03-16 18:02:31 +01:00
Peter Knut
9eb4d00564 Disable redirections in HTTP based drivers 2024-03-16 18:02:31 +01:00
Peter Knut
1c5947de50 Validate server input
- Allow only scheme, host and port in the server field.
- Use proper default host and port in Elasticsearch and ClickHouse driver.
2024-03-16 18:02:31 +01:00
Peter Knut
5cfd48bb68 Bump version to 4.9-dev 2024-03-16 13:23:33 +01:00
Peter Knut
20a0e4e113 Release 4.8.2 2024-03-16 13:12:36 +01:00
Peter Knut
bf80612b0d Make jush and JsShring submodules available 2024-03-16 01:03:39 +01:00
Lucas Sandery
8e848bfde4 Allow responsive styles on larger devices
and fix a media query.

Signed-off-by: Lucas Sandery <lucas-sandery@users.noreply.github.com>
(cherry picked from commit 4b0b011b93f9b684e5ab81f493f239f478fc3f2b)
2024-03-16 00:44:56 +01:00
Peter Knut
38f390ae5e Declare minimal PHP version in composer.json 2024-03-16 00:13:46 +01:00
Peter Knut
367a1b979e Merge branch 'translations' 2024-03-15 23:51:56 +01:00
Peter Knut
5dddfbdf12 Fix and complete Slovak translation 2024-03-15 23:47:20 +01:00
Lukáš Rajchl
2928b7beb8 Update Czech translation
(cherry picked from commit 7338eadd7c)
2024-03-15 23:31:07 +01:00
Anastasia
a940f85206 Update Russian translation
(cherry picked from commit 33fcfbc13b)
2024-03-15 23:29:20 +01:00
Gerry Demaret
834380aae9 Update Dutch translation
(cherry picked from commit 6024d73ae6)
2024-03-15 23:25:13 +01:00
Lionel Laffineur
3e94299256 Update French and Italian translations
(cherry picked from commit 496ab9a262)
2024-03-15 23:21:20 +01:00
Peter Knut
e99ed80ad8 Update language files 2024-03-15 23:12:06 +01:00
Hossain Ahmed Saiman
61b84cecd8 Bangla language corrections
Some informal words has been replaced with formal words. Some incorrect words has been corrected.

(cherry picked from commit a4ebae8706)

(cherry picked from commit 965598b640)
2024-03-15 23:10:27 +01:00
@krysits.COM
acf168a6da Add Latvian language translation
(cherry picked from commit fad4ce785b)
2024-03-15 23:04:00 +01:00
271 changed files with 14324 additions and 15915 deletions

View File

@@ -1,20 +0,0 @@
# https://editorconfig.org/
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.{php,css,js,xml}]
indent_style = tab
[*.json]
indent_style = space
indent_size = 4
[*.md]
indent_style = space
trim_trailing_whitespace = false
max_line_length = 120

6
.gitattributes vendored
View File

@@ -1,6 +0,0 @@
/.gitattributes export-ignore
/.github export-ignore
/.gitignore export-ignore
/.gitmodules export-ignore
/.travis.yml export-ignore
/tests export-ignore

3
.github/FUNDING.yml vendored
View File

@@ -1,3 +1,2 @@
github: vrana
patreon: jakubvrana patreon: jakubvrana
custom: ["https://www.paypal.com/donate/?item_name=Donation+to+Adminer&business=jakub%40vrana.cz"] custom: ["https://sourceforge.net/p/adminer/donate/"]

View File

@@ -1,15 +0,0 @@
---
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._

67
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,67 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '20 16 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

10
.gitignore vendored
View File

@@ -1,12 +1,6 @@
/adminer/adminer.css /adminer/adminer.css
/adminer/adminer-dark.css
/editor/adminer.css
/editor/adminer-dark.css
/adminer*.php /adminer*.php
/editor*.php /editor*.php
/tests/pdo-*.html
/tests/screenshots/
/tests/cropped/
/vendor/ /vendor/
adminer-plugins/ /composer.lock
adminer-plugins.php /temp

15
.gitmodules vendored
View File

@@ -1,9 +1,6 @@
[submodule "jush"] [submodule "designs/hydra"]
path = externals/jush path = designs/hydra
url = https://github.com/vrana/jush url = https://github.com/Niyko/Hydra-Dark-Theme-for-Adminer
[submodule "JsShrink"] [submodule "designs/pepa-linha-dark"]
path = externals/JsShrink path = designs/pepa-linha-dark
url = https://github.com/vrana/JsShrink url = https://github.com/pepa-linha/Adminer-Design-Dark/
[submodule "PhpShrink"]
path = externals/PhpShrink
url = https://github.com/vrana/PhpShrink

9
.travis.yml Normal file
View File

@@ -0,0 +1,9 @@
language: php
php:
- 5.6
- 7.1
- 7.2
- 7.3
- 7.4
- 8.0
script: git diff --name-only $TRAVIS_COMMIT_RANGE | grep '\.php$' | xargs -n1 -P8 php -l | grep -v 'No syntax errors'; test $? -eq 1

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +0,0 @@
- 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).

View File

@@ -1 +0,0 @@
Apache License 2.0 or GPL 2

View File

@@ -1,29 +0,0 @@
# 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+ (compiled file), PHP 7.4+ (source codes)
## Screenshot
![Table structure](https://www.adminer.org/static/screenshots/table.png)
## 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 distributed with Adminer, as well as many user-contributed plugins listed on the [Adminer Plugins page](https://www.adminer.org/plugins/).

View File

@@ -2,10 +2,10 @@
## Supported Versions ## Supported Versions
Only the latest published version and the latest development version (last commit) are supported. I support only the last published version and the last development version (last commit).
## Reporting a Vulnerability ## Reporting a Vulnerability
To report a vulnerability, create a new draft security advisory at [GitHub Security Advisories](https://github.com/vrana/adminer/security/advisories/new). To report a vulnerability, create a private bug at https://sourceforge.net/p/adminer/bugs-and-features/new/?private=1.
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. I handle security issues with top priority. If you don't hear from me in a week then please ping the bug. Once I accept the bug, the fix should be available and new version released within days. I will mark the bug as public after releasing a new version or declining the bug.

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $PROCEDURE = ($_GET["name"] ? $_GET["name"] : $_GET["call"]);
$PROCEDURE = ($_GET["name"] ?: $_GET["call"]);
page_header(lang('Call') . ": " . h($PROCEDURE), $error); page_header(lang('Call') . ": " . h($PROCEDURE), $error);
$routine = routine($_GET["call"], (isset($_GET["callf"]) ? "FUNCTION" : "PROCEDURE")); $routine = routine($_GET["call"], (isset($_GET["callf"]) ? "FUNCTION" : "PROCEDURE"));
@@ -19,14 +17,13 @@ foreach ($routine["fields"] as $i => $field) {
if (!$error && $_POST) { if (!$error && $_POST) {
$call = array(); $call = array();
foreach ($routine["fields"] as $key => $field) { foreach ($routine["fields"] as $key => $field) {
$val = "";
if (in_array($key, $in)) { if (in_array($key, $in)) {
$val = process_input($field); $val = process_input($field);
if ($val === false) { if ($val === false) {
$val = "''"; $val = "''";
} }
if (isset($out[$key])) { if (isset($out[$key])) {
connection()->query("SET @" . idf_escape($field["field"]) . " = $val"); $connection->query("SET @" . idf_escape($field["field"]) . " = $val");
} }
} }
$call[] = (isset($out[$key]) ? "@" . idf_escape($field["field"]) : $val); $call[] = (isset($out[$key]) ? "@" . idf_escape($field["field"]) : $val);
@@ -34,31 +31,31 @@ if (!$error && $_POST) {
$query = (isset($_GET["callf"]) ? "SELECT" : "CALL") . " " . table($PROCEDURE) . "(" . implode(", ", $call) . ")"; $query = (isset($_GET["callf"]) ? "SELECT" : "CALL") . " " . table($PROCEDURE) . "(" . implode(", ", $call) . ")";
$start = microtime(true); $start = microtime(true);
$result = connection()->multi_query($query); $result = $connection->multi_query($query);
$affected = connection()->affected_rows; // getting warnings overwrites this $affected = $connection->affected_rows; // getting warnigns overwrites this
echo adminer()->selectQuery($query, $start, !$result); echo $adminer->selectQuery($query, $start, !$result);
if (!$result) { if (!$result) {
echo "<p class='error'>" . error() . "\n"; echo "<p class='error'>" . error() . "\n";
} else { } else {
$connection2 = connect(adminer()->credentials()); $connection2 = connect();
if ($connection2) { if (is_object($connection2)) {
$connection2->select_db(DB); $connection2->select_db(DB);
} }
do { do {
$result = connection()->store_result(); $result = $connection->store_result();
if (is_object($result)) { if (is_object($result)) {
print_select_result($result, $connection2); select($result, $connection2);
} else { } else {
echo "<p class='message'>" . lang('Routine has been called, %d row(s) affected.', $affected) echo "<p class='message'>" . lang('Routine has been called, %d row(s) affected.', $affected)
. " <span class='time'>" . @date("H:i:s") . "</span>\n" // @ - time zone may be not set . " <span class='time'>" . @date("H:i:s") . "</span>\n" // @ - time zone may be not set
; ;
} }
} while (connection()->next_result()); } while ($connection->next_result());
if ($out) { if ($out) {
print_select_result(connection()->query("SELECT " . implode(", ", $out))); select($connection->query("SELECT " . implode(", ", $out)));
} }
} }
} }
@@ -67,18 +64,21 @@ if (!$error && $_POST) {
<form action="" method="post"> <form action="" method="post">
<?php <?php
if ($in) { if ($in) {
echo "<table class='layout'>\n"; echo "<table cellspacing='0' class='layout'>\n";
foreach ($in as $key) { foreach ($in as $key) {
$field = $routine["fields"][$key]; $field = $routine["fields"][$key];
$name = $field["field"]; $name = $field["field"];
echo "<tr><th>" . adminer()->fieldName($field); echo "<tr><th>" . $adminer->fieldName($field);
$value = idx($_POST["fields"], $name); $value = $_POST["fields"][$name];
if ($value != "") { if ($value != "") {
if ($field["type"] == "enum") {
$value = +$value;
}
if ($field["type"] == "set") { if ($field["type"] == "set") {
$value = implode(",", $value); $value = array_sum($value);
} }
} }
input($field, $value, idx($_POST["function"], $name, "")); // param name can be empty input($field, $value, (string) $_POST["function"][$name]); // param name can be empty
echo "\n"; echo "\n";
} }
echo "</table>\n"; echo "</table>\n";
@@ -86,31 +86,5 @@ if ($in) {
?> ?>
<p> <p>
<input type="submit" value="<?php echo lang('Call'); ?>"> <input type="submit" value="<?php echo lang('Call'); ?>">
<?php echo input_token(); ?> <input type="hidden" name="token" value="<?php echo $token; ?>">
</form> </form>
<pre>
<?php
/** Format string as table row
* @return string HTML
*/
function pre_tr(string $s): string {
return preg_replace('~^~m', '<tr>', preg_replace('~\|~', '<td>', preg_replace('~\|$~m', "", rtrim($s))));
}
$table = '(\+--[-+]+\+\n)';
$row = '(\| .* \|\n)';
echo preg_replace_callback(
"~^$table?$row$table?($row*)$table?~m",
function ($match) {
$first_row = pre_tr($match[2]);
return "<table>\n" . ($match[1] ? "<thead>$first_row</thead>\n" : $first_row) . pre_tr($match[4]) . "\n</table>";
},
preg_replace(
'~(\n( -|mysql)&gt; )(.+)~',
"\\1<code class='jush-sql'>\\3</code>",
preg_replace('~(.+)\n---+\n~', "<b>\\1</b>\n", h($routine['comment']))
)
);
?>
</pre>

View File

@@ -1,51 +0,0 @@
<?php
namespace Adminer;
$TABLE = $_GET["check"];
$name = $_GET["name"];
$row = $_POST;
if ($row && !$error) {
if (JUSH == "sqlite") {
$result = recreate_table($TABLE, $TABLE, array(), array(), array(), "", array(), "$name", ($row["drop"] ? "" : $row["clause"]));
} else {
$result = ($name == "" || queries("ALTER TABLE " . table($TABLE) . " DROP CONSTRAINT " . idf_escape($name)));
if (!$row["drop"]) {
$result = queries("ALTER TABLE " . table($TABLE) . " ADD" . ($row["name"] != "" ? " CONSTRAINT " . idf_escape($row["name"]) : "") . " CHECK ($row[clause])"); //! SQL injection
}
}
queries_redirect(
ME . "table=" . urlencode($TABLE),
($row["drop"] ? lang('Check has been dropped.') : ($name != "" ? lang('Check has been altered.') : lang('Check has been created.'))),
$result
);
}
page_header(($name != "" ? lang('Alter check') . ": " . h($name) : lang('Create check')), $error, array("table" => $TABLE));
if (!$row) {
$checks = driver()->checkConstraints($TABLE);
$row = array("name" => $name, "clause" => $checks[$name]);
}
?>
<form action="" method="post">
<p><?php
if (JUSH != "sqlite") {
echo lang('Name') . ': <input name="name" value="' . h($row["name"]) . '" data-maxlength="64" autocapitalize="off"> ';
}
echo doc_link(array(
'sql' => "create-table-check-constraints.html",
'mariadb' => "constraint/",
'pgsql' => "ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS",
'mssql' => "relational-databases/tables/create-check-constraints",
'sqlite' => "lang_createtable.html#check_constraints",
), "?");
?>
<p><?php textarea("clause", $row["clause"]); ?>
<p><input type="submit" value="<?php echo lang('Save'); ?>">
<?php if ($name != "") { ?>
<input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $name)); ?>
<?php } ?>
<?php echo input_token(); ?>
</form>

View File

@@ -1,6 +1,4 @@
<?php <?php
namespace Adminer;
$TABLE = $_GET["create"]; $TABLE = $_GET["create"];
$partition_by = array(); $partition_by = array();
foreach (array('HASH', 'LINEAR HASH', 'KEY', 'LINEAR KEY', 'RANGE', 'LIST') as $key) { foreach (array('HASH', 'LINEAR HASH', 'KEY', 'LINEAR KEY', 'RANGE', 'LIST') as $key) {
@@ -17,8 +15,8 @@ $orig_fields = array();
$table_status = array(); $table_status = array();
if ($TABLE != "") { if ($TABLE != "") {
$orig_fields = fields($TABLE); $orig_fields = fields($TABLE);
$table_status = table_status1($TABLE); $table_status = table_status($TABLE);
if (count($table_status) < 2) { // there's only the Name field if (!$table_status) {
$error = lang('No tables.'); $error = lang('No tables.');
} }
} }
@@ -30,7 +28,7 @@ if ($row["auto_increment_col"]) {
} }
if ($_POST) { if ($_POST) {
save_settings(array("comments" => $_POST["comments"], "defaults" => $_POST["defaults"])); set_adminer_settings(array("comments" => $_POST["comments"], "defaults" => $_POST["defaults"]));
} }
if ($_POST && !process_fields($row["fields"]) && !$error) { if ($_POST && !process_fields($row["fields"]) && !$error) {
@@ -48,19 +46,22 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
$foreign_key = $foreign_keys[$field["type"]]; $foreign_key = $foreign_keys[$field["type"]];
$type_field = ($foreign_key !== null ? $referencable_primary[$foreign_key] : $field); //! can collide with user defined type $type_field = ($foreign_key !== null ? $referencable_primary[$foreign_key] : $field); //! can collide with user defined type
if ($field["field"] != "") { if ($field["field"] != "") {
if (!$field["generated"]) { if (!$field["has_default"]) {
$field["default"] = null; $field["default"] = null;
} }
if ($key == $row["auto_increment_col"]) {
$field["auto_increment"] = true;
}
$process_field = process_field($field, $type_field); $process_field = process_field($field, $type_field);
$all_fields[] = array($field["orig"], $process_field, $after); $all_fields[] = array($field["orig"], $process_field, $after);
if (!$orig_field || $process_field !== process_field($orig_field, $orig_field)) { if (!$orig_field || $process_field != process_field($orig_field, $orig_field)) {
$fields[] = array($field["orig"], $process_field, $after); $fields[] = array($field["orig"], $process_field, $after);
if ($field["orig"] != "" || $after) { if ($field["orig"] != "" || $after) {
$use_all_fields = true; $use_all_fields = true;
} }
} }
if ($foreign_key !== null) { if ($foreign_key !== null) {
$foreign[idf_escape($field["field"])] = ($TABLE != "" && JUSH != "sqlite" ? "ADD" : " ") . format_foreign_key(array( $foreign[idf_escape($field["field"])] = ($TABLE != "" && $jush != "sqlite" ? "ADD" : " ") . format_foreign_key(array(
'table' => $foreign_keys[$field["type"]], 'table' => $foreign_keys[$field["type"]],
'source' => array($field["field"]), 'source' => array($field["field"]),
'target' => array($type_field["field"]), 'target' => array($type_field["field"]),
@@ -81,40 +82,21 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
} }
$partitioning = ""; $partitioning = "";
if (support("partitioning")) { if ($partition_by[$row["partition_by"]]) {
if (isset($partition_by[$row["partition_by"]])) {
$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(); $partitions = array();
if ($params["partition_by"] == 'RANGE' || $params["partition_by"] == 'LIST') { if ($row["partition_by"] == 'RANGE' || $row["partition_by"] == 'LIST') {
foreach ($params["partition_names"] as $key => $name) { foreach (array_filter($row["partition_names"]) as $key => $val) {
$value = $params["partition_values"][$key]; $value = $row["partition_values"][$key];
$partitions[] = "\n PARTITION " . idf_escape($name) . " VALUES " . ($params["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection $partitions[] = "\n PARTITION " . idf_escape($val) . " VALUES " . ($row["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection
} }
} }
// $params["partition"] can be expression, not only column $partitioning .= "\nPARTITION BY $row[partition_by]($row[partition])" . ($partitions // $row["partition"] can be expression, not only column
$partitioning .= "\nPARTITION BY $params[partition_by]($params[partition])"; ? " (" . implode(",", $partitions) . "\n)"
if ($partitions) { : ($row["partitions"] ? " PARTITIONS " . (+$row["partitions"]) : "")
$partitioning .= " (" . implode(",", $partitions) . "\n)"; );
} elseif ($params["partitions"]) { } elseif (support("partitioning") && preg_match("~partitioned~", $table_status["Create_options"])) {
$partitioning .= " PARTITIONS " . (+$params["partitions"]);
}
}
} elseif (preg_match("~partitioned~", $table_status["Create_options"])) {
$partitioning .= "\nREMOVE PARTITIONING"; $partitioning .= "\nREMOVE PARTITIONING";
} }
}
$message = lang('Table has been altered.'); $message = lang('Table has been altered.');
if ($TABLE == "") { if ($TABLE == "") {
@@ -126,7 +108,7 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
queries_redirect(ME . (support("table") ? "table=" : "select=") . urlencode($name), $message, alter_table( queries_redirect(ME . (support("table") ? "table=" : "select=") . urlencode($name), $message, alter_table(
$TABLE, $TABLE,
$name, $name,
(JUSH == "sqlite" && ($use_all_fields || $foreign) ? $all_fields : $fields), ($jush == "sqlite" && ($use_all_fields || $foreign) ? $all_fields : $fields),
$foreign, $foreign,
($row["Comment"] != $table_status["Comment"] ? $row["Comment"] : null), ($row["Comment"] != $table_status["Comment"] ? $row["Comment"] : null),
($row["Engine"] && $row["Engine"] != $table_status["Engine"] ? $row["Engine"] : ""), ($row["Engine"] && $row["Engine"] != $table_status["Engine"] ? $row["Engine"] : ""),
@@ -140,7 +122,6 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
page_header(($TABLE != "" ? lang('Alter table') : lang('Create table')), $error, array("table" => $TABLE), h($TABLE)); page_header(($TABLE != "" ? lang('Alter table') : lang('Create table')), $error, array("table" => $TABLE), h($TABLE));
if (!$_POST) { if (!$_POST) {
$types = driver()->types();
$row = array( $row = array(
"Engine" => $_COOKIE["adminer_engine"], "Engine" => $_COOKIE["adminer_engine"],
"fields" => array(array("field" => "", "type" => (isset($types["int"]) ? "int" : (isset($types["integer"]) ? "integer" : "")), "on_update" => "")), "fields" => array(array("field" => "", "type" => (isset($types["int"]) ? "int" : (isset($types["integer"]) ? "integer" : "")), "on_update" => "")),
@@ -155,23 +136,24 @@ if (!$_POST) {
$row["Auto_increment"] = ""; $row["Auto_increment"] = "";
} }
foreach ($orig_fields as $field) { foreach ($orig_fields as $field) {
$field["generated"] = $field["generated"] ?: (isset($field["default"]) ? "DEFAULT" : ""); $field["has_default"] = isset($field["default"]);
$row["fields"][] = $field; $row["fields"][] = $field;
} }
if (support("partitioning")) { if (support("partitioning")) {
$row += get_partitions_info($TABLE); $from = "FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = " . q(DB) . " AND TABLE_NAME = " . q($TABLE);
$row["partition_names"][] = ""; $result = $connection->query("SELECT PARTITION_METHOD, PARTITION_ORDINAL_POSITION, PARTITION_EXPRESSION $from ORDER BY PARTITION_ORDINAL_POSITION DESC LIMIT 1");
$row["partition_values"][] = ""; list($row["partition_by"], $row["partitions"], $row["partition"]) = $result->fetch_row();
$partitions = get_key_vals("SELECT PARTITION_NAME, PARTITION_DESCRIPTION $from AND PARTITION_NAME != '' ORDER BY PARTITION_ORDINAL_POSITION");
$partitions[""] = "";
$row["partition_names"] = array_keys($partitions);
$row["partition_values"] = array_values($partitions);
} }
} }
} }
$collations = collations(); $collations = collations();
if (is_array(reset($collations))) { $engines = engines();
$collations = call_user_func_array('array_merge', array_values($collations));
}
$engines = driver()->engines();
// case of engine may differ // case of engine may differ
foreach ($engines as $engine) { foreach ($engines as $engine) {
if (!strcasecmp($engine, $row["Engine"])) { if (!strcasecmp($engine, $row["Engine"])) {
@@ -183,60 +165,65 @@ foreach ($engines as $engine) {
<form action="" method="post" id="form"> <form action="" method="post" id="form">
<p> <p>
<?php <?php if (support("columns") || $TABLE == "") { ?>
if (support("columns") || $TABLE == "") { <?php echo lang('Table name'); ?>: <input name="name" data-maxlength="64" value="<?php echo h($row["name"]); ?>" autocapitalize="off">
echo lang('Table name') . ": <input name='name'" . ($TABLE == "" && !$_POST ? " autofocus" : "") . " data-maxlength='64' value='" . h($row["name"]) . "' autocapitalize='off'>\n"; <?php if ($TABLE == "" && !$_POST) { echo script("focus(qs('#form')['name']);"); } ?>
echo ($engines ? html_select("Engine", array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . on_help("event.target.value", 1) . script("qsl('select').onchange = helpClose;") . "\n" : ""); <?php echo ($engines ? "<select name='Engine'>" . optionlist(array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . "</select>" . on_help("getTarget(event).value", 1) . script("qsl('select').onchange = helpClose;") : ""); ?>
if ($collations) { <?php echo ($collations && !preg_match("~sqlite|mssql~", $jush) ? html_select("Collation", array("" => "(" . lang('collation') . ")") + $collations, $row["Collation"]) : ""); ?>
echo "<datalist id='collations'>" . optionlist($collations) . "</datalist>\n"; <input type="submit" value="<?php echo lang('Save'); ?>">
echo (preg_match("~sqlite|mssql~", JUSH) ? "" : "<input list='collations' name='Collation' value='" . h($row["Collation"]) . "' placeholder='(" . lang('collation') . ")'>"); <?php } ?>
}
echo "<input type='submit' value='" . lang('Save') . "'>\n";
}
if (support("columns")) { <?php if (support("columns")) { ?>
echo "<div class='scrollable'>\n"; <div class="scrollable">
echo "<table id='edit-fields' class='nowrap'>\n"; <table cellspacing="0" id="edit-fields" class="nowrap">
edit_fields($row["fields"], $collations, "TABLE", $foreign_keys); <?php
echo "</table>\n"; edit_fields($row["fields"], $collations, "TABLE", $foreign_keys);
echo script("editFields();"); ?>
echo "</div>\n<p>\n"; </table>
echo lang('Auto Increment') . ": <input type='number' name='Auto_increment' class='size' value='" . h($row["Auto_increment"]) . "'>\n"; <?php echo script("editFields();"); ?>
echo checkbox("defaults", 1, ($_POST ? $_POST["defaults"] : get_setting("defaults")), lang('Default values'), "columnShow(this.checked, 5)", "jsonly"); </div>
$comments = ($_POST ? $_POST["comments"] : get_setting("comments")); <p>
echo (support("comment") <?php echo lang('Auto Increment'); ?>: <input type="number" name="Auto_increment" size="6" 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 (support("comment")
? checkbox("comments", 1, $comments, lang('Comment'), "editingCommentsClick(this, true);", "jsonly") ? checkbox("comments", 1, $comments, lang('Comment'), "editingCommentsClick(this, true);", "jsonly")
. ' ' . (preg_match('~\n~', $row["Comment"]) . ' ' . (preg_match('~\n~', $row["Comment"])
? "<textarea name='Comment' rows='2' cols='20'" . ($comments ? "" : " class='hidden'") . ">" . h($row["Comment"]) . "</textarea>" ? "<textarea name='Comment' rows='2' cols='20'" . ($comments ? "" : " class='hidden'") . ">" . h($row["Comment"]) . "</textarea>"
: '<input name="Comment" value="' . h($row["Comment"]) . '" data-maxlength="' . (min_version(5.5) ? 2048 : 60) . '"' . ($comments ? "" : " class='hidden'") . '>' : '<input name="Comment" value="' . h($row["Comment"]) . '" data-maxlength="' . (min_version(5.5) ? 2048 : 60) . '"' . ($comments ? "" : " class='hidden'") . '>'
) )
: '') : '')
; ;
?> ?>
<p> <p>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php } ?> <?php } ?>
<?php if ($TABLE != "") { ?> <?php if ($TABLE != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $TABLE)); ?><?php } ?>
<input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $TABLE)); ?>
<?php } ?>
<?php <?php
if (support("partitioning")) { if (support("partitioning")) {
$partition_table = preg_match('~RANGE|LIST~', $row["partition_by"]); $partition_table = preg_match('~RANGE|LIST~', $row["partition_by"]);
print_fieldset("partition", lang('Partition by'), $row["partition_by"]); print_fieldset("partition", lang('Partition by'), $row["partition_by"]);
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"; <p>
echo lang('Partitions') . ": <input type='number' name='partitions' class='size" . ($partition_table || !$row["partition_by"] ? " hidden" : "") . "' value='" . h($row["partitions"]) . "'>\n"; <?php echo "<select name='partition_by'>" . optionlist(array("" => "") + $partition_by, $row["partition_by"]) . "</select>" . on_help("getTarget(event).value.replace(/./, 'PARTITION BY \$&')", 1) . script("qsl('select').onchange = partitionByChange;"); ?>
echo "<table id='partition-table'" . ($partition_table ? "" : " class='hidden'") . ">\n"; (<input name="partition" value="<?php echo h($row["partition"]); ?>">)
echo "<thead><tr><th>" . lang('Partition name') . "<th>" . lang('Values') . "</thead>\n"; <?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"]); ?>">
foreach ($row["partition_names"] as $key => $val) { <table cellspacing="0" id="partition-table"<?php echo ($partition_table ? "" : " class='hidden'"); ?>>
<thead><tr><th><?php echo lang('Partition name'); ?><th><?php echo lang('Values'); ?></thead>
<?php
foreach ($row["partition_names"] as $key => $val) {
echo '<tr>'; echo '<tr>';
echo '<td><input name="partition_names[]" value="' . h($val) . '" autocapitalize="off">'; echo '<td><input name="partition_names[]" value="' . h($val) . '" autocapitalize="off">';
echo ($key == count($row["partition_names"]) - 1 ? script("qsl('input').oninput = partitionNameChange;") : ''); echo ($key == count($row["partition_names"]) - 1 ? script("qsl('input').oninput = partitionNameChange;") : '');
echo '<td><input name="partition_values[]" value="' . h(idx($row["partition_values"], $key)) . '">'; echo '<td><input name="partition_values[]" value="' . h($row["partition_values"][$key]) . '">';
}
echo "</table>\n</div></fieldset>\n";
} }
echo input_token();
?> ?>
</table>
</div></fieldset>
<?php
}
?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form> </form>

View File

@@ -1,9 +1,7 @@
<?php <?php
namespace Adminer;
$row = $_POST; $row = $_POST;
if ($_POST && !$error && !$_POST["add"]) { if ($_POST && !$error && !isset($_POST["add_x"])) { // add is an image and PHP changes add.x to add_x
$name = trim($row["name"]); $name = trim($row["name"]);
if ($_POST["drop"]) { if ($_POST["drop"]) {
$_GET["db"] = ""; // to save in global history $_GET["db"] = ""; // to save in global history
@@ -46,7 +44,7 @@ if ($_POST) {
$name = $row["name"]; $name = $row["name"];
} elseif (DB != "") { } elseif (DB != "") {
$row["collation"] = db_collation(DB, $collations); $row["collation"] = db_collation(DB, $collations);
} elseif (JUSH == "sql") { } elseif ($jush == "sql") {
// propose database name with limited privileges // propose database name with limited privileges
foreach (get_vals("SHOW GRANTS") as $grant) { foreach (get_vals("SHOW GRANTS") as $grant) {
if (preg_match('~ ON (`(([^\\\\`]|``|\\\\.)*)%`\.\*)?~', $grant, $match) && $match[1]) { if (preg_match('~ ON (`(([^\\\\`]|``|\\\\.)*)%`\.\*)?~', $grant, $match) && $match[1]) {
@@ -60,22 +58,23 @@ if ($_POST) {
<form action="" method="post"> <form action="" method="post">
<p> <p>
<?php <?php
echo ($_POST["add"] || strpos($name, "\n") echo ($_POST["add_x"] || strpos($name, "\n")
? '<textarea autofocus name="name" rows="10" cols="40">' . h($name) . '</textarea><br>' ? '<textarea id="name" name="name" rows="10" cols="40">' . h($name) . '</textarea><br>'
: '<input name="name" autofocus value="' . h($name) . '" data-maxlength="64" autocapitalize="off">' : '<input name="name" id="name" value="' . h($name) . '" data-maxlength="64" autocapitalize="off">'
) . "\n" . ($collations ? html_select("collation", array("" => "(" . lang('collation') . ")") + $collations, $row["collation"]) . doc_link(array( ) . "\n" . ($collations ? html_select("collation", array("" => "(" . lang('collation') . ")") + $collations, $row["collation"]) . doc_link(array(
'sql' => "charset-charsets.html", 'sql' => "charset-charsets.html",
'mariadb' => "supported-character-sets-and-collations/", 'mariadb' => "supported-character-sets-and-collations/",
'mssql' => "relational-databases/system-functions/sys-fn-helpcollations-transact-sql", 'mssql' => "ms187963.aspx",
)) : ""); )) : "");
echo script("focus(qs('#name'));");
?> ?>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php <?php
if (DB != "") { if (DB != "") {
echo "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm(lang('Drop %s?', DB)) . "\n"; echo "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm(lang('Drop %s?', DB)) . "\n";
} elseif (!$_POST["add"] && $_GET["db"] == "") { } elseif (!$_POST["add_x"] && $_GET["db"] == "") {
echo icon("plus", "add[0]", "+", lang('Add next')) . "\n"; 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> </form>

View File

@@ -1,12 +1,10 @@
<?php <?php
namespace Adminer;
$tables_views = array_merge((array) $_POST["tables"], (array) $_POST["views"]); $tables_views = array_merge((array) $_POST["tables"], (array) $_POST["views"]);
if ($tables_views && !$error && !$_POST["search"]) { if ($tables_views && !$error && !$_POST["search"]) {
$result = true; $result = true;
$message = ""; $message = "";
if (JUSH == "sql" && $_POST["tables"] && count($_POST["tables"]) > 1 && ($_POST["drop"] || $_POST["truncate"] || $_POST["copy"])) { if ($jush == "sql" && $_POST["tables"] && count($_POST["tables"]) > 1 && ($_POST["drop"] || $_POST["truncate"] || $_POST["copy"])) {
queries("SET foreign_key_checks = 0"); // allows to truncate or drop several tables at once queries("SET foreign_key_checks = 0"); // allows to truncate or drop several tables at once
} }
@@ -29,21 +27,15 @@ if ($tables_views && !$error && !$_POST["search"]) {
$result = drop_tables($_POST["tables"]); $result = drop_tables($_POST["tables"]);
} }
$message = lang('Tables have been dropped.'); $message = lang('Tables have been dropped.');
} elseif (JUSH == "sqlite" && $_POST["check"]) { } elseif ($jush != "sql") {
foreach ((array) $_POST["tables"] as $table) { $result = ($jush == "sqlite"
foreach (get_rows("PRAGMA integrity_check(" . q($table) . ")") as $row) {
$message .= "<b>" . h($table) . "</b>: " . h($row["integrity_check"]) . "<br>";
}
}
} elseif (JUSH != "sql") {
$result = (JUSH == "sqlite"
? queries("VACUUM") ? queries("VACUUM")
: apply_queries("VACUUM" . ($_POST["optimize"] ? "" : " ANALYZE"), $_POST["tables"]) : apply_queries("VACUUM" . ($_POST["optimize"] ? "" : " ANALYZE"), $_POST["tables"])
); );
$message = lang('Tables have been optimized.'); $message = lang('Tables have been optimized.');
} elseif (!$_POST["tables"]) { } elseif (!$_POST["tables"]) {
$message = lang('No tables.'); $message = lang('No tables.');
} elseif ($result = queries(($_POST["optimize"] ? "OPTIMIZE" : ($_POST["check"] ? "CHECK" : ($_POST["repair"] ? "REPAIR" : "ANALYZE"))) . " TABLE " . implode(", ", array_map('Adminer\idf_escape', $_POST["tables"])))) { } elseif ($result = queries(($_POST["optimize"] ? "OPTIMIZE" : ($_POST["check"] ? "CHECK" : ($_POST["repair"] ? "REPAIR" : "ANALYZE"))) . " TABLE " . implode(", ", array_map('idf_escape', $_POST["tables"])))) {
while ($row = $result->fetch_assoc()) { while ($row = $result->fetch_assoc()) {
$message .= "<b>" . h($row["Table"]) . "</b>: " . h($row["Msg_text"]) . "<br>"; $message .= "<b>" . h($row["Table"]) . "</b>: " . h($row["Msg_text"]) . "<br>";
} }
@@ -54,7 +46,7 @@ if ($tables_views && !$error && !$_POST["search"]) {
page_header(($_GET["ns"] == "" ? lang('Database') . ": " . h(DB) : lang('Schema') . ": " . h($_GET["ns"])), $error, true); page_header(($_GET["ns"] == "" ? lang('Database') . ": " . h(DB) : lang('Schema') . ": " . h($_GET["ns"])), $error, true);
if (adminer()->homepage()) { if ($adminer->homepage()) {
if ($_GET["ns"] !== "") { if ($_GET["ns"] !== "") {
echo "<h3 id='tables-views'>" . lang('Tables and views') . "</h3>\n"; echo "<h3 id='tables-views'>" . lang('Tables and views') . "</h3>\n";
$tables_list = tables_list(); $tables_list = tables_list();
@@ -69,12 +61,12 @@ if (adminer()->homepage()) {
echo " <input type='submit' name='search' value='" . lang('Search') . "'>\n"; echo " <input type='submit' name='search' value='" . lang('Search') . "'>\n";
echo "</div></fieldset>\n"; echo "</div></fieldset>\n";
if ($_POST["search"] && $_POST["query"] != "") { if ($_POST["search"] && $_POST["query"] != "") {
$_GET["where"][0]["op"] = driver()->convertOperator("LIKE %%"); $_GET["where"][0]["op"] = $driver->convertOperator("LIKE %%");
search_tables(); search_tables();
} }
} }
echo "<div class='scrollable'>\n"; echo "<div class='scrollable'>\n";
echo "<table class='nowrap checkable odds'>\n"; echo "<table cellspacing='0' class='nowrap checkable'>\n";
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});"); echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
echo '<thead><tr class="wrap">'; echo '<thead><tr class="wrap">';
echo '<td><input id="check-all" type="checkbox" class="jsonly">' . script("qs('#check-all').onclick = partial(formCheck, /^(tables|views)\[/);", ""); echo '<td><input id="check-all" type="checkbox" class="jsonly">' . script("qs('#check-all').onclick = partial(formCheck, /^(tables|views)\[/);", "");
@@ -93,14 +85,13 @@ if (adminer()->homepage()) {
foreach ($tables_list as $name => $type) { foreach ($tables_list as $name => $type) {
$view = ($type !== null && !preg_match('~table|sequence~i', $type)); $view = ($type !== null && !preg_match('~table|sequence~i', $type));
$id = h("Table-" . $name); $id = h("Table-" . $name);
echo '<tr><td>' . checkbox(($view ? "views[]" : "tables[]"), $name, in_array("$name", $tables_views, true), "", "", "", $id); // "$name" to check numeric table names echo '<tr' . odd() . '><td>' . checkbox(($view ? "views[]" : "tables[]"), $name, in_array($name, $tables_views, true), "", "", "", $id);
echo '<th>' . (support("table") || support("indexes") ? "<a href='" . h(ME) . "table=" . urlencode($name) . "' title='" . lang('Show structure') . "' id='$id'>" . h($name) . '</a>' : h($name)); echo '<th>' . (support("table") || support("indexes") ? "<a href='" . h(ME) . "table=" . urlencode($name) . "' title='" . lang('Show structure') . "' id='$id'>" . h($name) . '</a>' : h($name));
if ($view) { if ($view) {
echo '<td colspan="6"><a href="' . h(ME) . "view=" . urlencode($name) . '" title="' . lang('Alter view') . '">' . (preg_match('~materialized~i', $type) ? lang('Materialized view') : lang('View')) . '</a>'; echo '<td colspan="6"><a href="' . h(ME) . "view=" . urlencode($name) . '" title="' . lang('Alter view') . '">' . (preg_match('~materialized~i', $type) ? lang('Materialized view') : lang('View')) . '</a>';
echo '<td align="right"><a href="' . h(ME) . "select=" . urlencode($name) . '" title="' . lang('Select data') . '">?</a>'; echo '<td align="right"><a href="' . h(ME) . "select=" . urlencode($name) . '" title="' . lang('Select data') . '">?</a>';
} else { } else {
foreach ( foreach (array(
array(
"Engine" => array(), "Engine" => array(),
"Collation" => array(), "Collation" => array(),
"Data_length" => array("create", lang('Alter table')), "Data_length" => array("create", lang('Alter table')),
@@ -108,8 +99,7 @@ if (adminer()->homepage()) {
"Data_free" => array("edit", lang('New item')), "Data_free" => array("edit", lang('New item')),
"Auto_increment" => array("auto_increment=1&create", lang('Alter table')), "Auto_increment" => array("auto_increment=1&create", lang('Alter table')),
"Rows" => array("select", lang('Select data')), "Rows" => array("select", lang('Select data')),
) as $key => $link ) as $key => $link) {
) {
$id = " id='$key-" . h($name) . "'"; $id = " id='$key-" . h($name) . "'";
echo ($link ? "<td align='right'>" . (support("table") || $key == "Rows" || (support("indexes") && $key != "Data_length") echo ($link ? "<td align='right'>" . (support("table") || $key == "Rows" || (support("indexes") && $key != "Data_length")
? "<a href='" . h(ME . "$link[0]=") . urlencode($name) . "'$id title='$link[1]'>?</a>" ? "<a href='" . h(ME . "$link[0]=") . urlencode($name) . "'$id title='$link[1]'>?</a>"
@@ -119,35 +109,32 @@ if (adminer()->homepage()) {
$tables++; $tables++;
} }
echo (support("comment") ? "<td id='Comment-" . h($name) . "'>" : ""); echo (support("comment") ? "<td id='Comment-" . h($name) . "'>" : "");
echo "\n";
} }
echo "<tr><td><th>" . lang('%d in total', count($tables_list)); echo "<tr><td><th>" . lang('%d in total', count($tables_list));
echo "<td>" . h(JUSH == "sql" ? get_val("SELECT @@default_storage_engine") : ""); echo "<td>" . h($jush == "sql" ? $connection->result("SELECT @@default_storage_engine") : "");
echo "<td>" . h(db_collation(DB, collations())); echo "<td>" . h(db_collation(DB, collations()));
foreach (array("Data_length", "Index_length", "Data_free") as $key) { foreach (array("Data_length", "Index_length", "Data_free") as $key) {
echo "<td align='right' id='sum-$key'>"; echo "<td align='right' id='sum-$key'>";
} }
echo "\n";
echo "</table>\n"; echo "</table>\n";
echo "</div>\n"; echo "</div>\n";
if (!information_schema(DB)) { if (!information_schema(DB)) {
echo "<div class='footer'><div>\n"; echo "<div class='footer'><div>\n";
$vacuum = "<input type='submit' value='" . lang('Vacuum') . "'> " . on_help("'VACUUM'"); $vacuum = "<input type='submit' value='" . lang('Vacuum') . "'> " . on_help("'VACUUM'");
$optimize = "<input type='submit' name='optimize' value='" . lang('Optimize') . "'> " . on_help(JUSH == "sql" ? "'OPTIMIZE TABLE'" : "'VACUUM OPTIMIZE'"); $optimize = "<input type='submit' name='optimize' value='" . lang('Optimize') . "'> " . on_help($jush == "sql" ? "'OPTIMIZE TABLE'" : "'VACUUM OPTIMIZE'");
echo "<fieldset><legend>" . lang('Selected') . " <span id='selected'></span></legend><div>" echo "<fieldset><legend>" . lang('Selected') . " <span id='selected'></span></legend><div>"
. (JUSH == "sqlite" ? $vacuum . "<input type='submit' name='check' value='" . lang('Check') . "'> " . on_help("'PRAGMA integrity_check'") . ($jush == "sqlite" ? $vacuum
: (JUSH == "pgsql" ? $vacuum . $optimize : ($jush == "pgsql" ? $vacuum . $optimize
: (JUSH == "sql" ? "<input type='submit' value='" . lang('Analyze') . "'> " . on_help("'ANALYZE TABLE'") : ($jush == "sql" ? "<input type='submit' value='" . lang('Analyze') . "'> " . on_help("'ANALYZE TABLE'") . $optimize
. $optimize
. "<input type='submit' name='check' value='" . lang('Check') . "'> " . on_help("'CHECK TABLE'") . "<input type='submit' name='check' value='" . lang('Check') . "'> " . on_help("'CHECK TABLE'")
. "<input type='submit' name='repair' value='" . lang('Repair') . "'> " . on_help("'REPAIR TABLE'") . "<input type='submit' name='repair' value='" . lang('Repair') . "'> " . on_help("'REPAIR TABLE'")
: ""))) : "")))
. "<input type='submit' name='truncate' value='" . lang('Truncate') . "'> " . on_help(JUSH == "sqlite" ? "'DELETE'" : "'TRUNCATE" . (JUSH == "pgsql" ? "'" : " TABLE'")) . confirm() . "<input type='submit' name='truncate' value='" . lang('Truncate') . "'> " . on_help($jush == "sqlite" ? "'DELETE'" : "'TRUNCATE" . ($jush == "pgsql" ? "'" : " TABLE'")) . confirm()
. "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . on_help("'DROP TABLE'") . confirm() . "\n"; . "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . on_help("'DROP TABLE'") . confirm() . "\n";
$databases = (support("scheme") ? adminer()->schemas() : adminer()->databases()); $databases = (support("scheme") ? $adminer->schemas() : $adminer->databases());
if (count($databases) != 1 && JUSH != "sqlite") { if (count($databases) != 1 && $jush != "sqlite") {
$db = (isset($_POST["target"]) ? $_POST["target"] : (support("scheme") ? $_GET["ns"] : DB)); $db = (isset($_POST["target"]) ? $_POST["target"] : (support("scheme") ? $_GET["ns"] : DB));
echo "<p>" . lang('Move to other database') . ": "; echo "<p>" . lang('Move to other database') . ": ";
echo ($databases ? html_select("target", $databases, $db) : '<input name="target" value="' . h($db) . '" autocapitalize="off">'); echo ($databases ? html_select("target", $databases, $db) : '<input name="target" value="' . h($db) . '" autocapitalize="off">');
@@ -157,7 +144,7 @@ if (adminer()->homepage()) {
} }
echo "<input type='hidden' name='all' value=''>"; // used by trCheck() 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 script("qsl('input').onclick = function () { selectCount('selected', formChecked(this, /^(tables|views)\[/));" . (support("table") ? " selectCount('selected2', formChecked(this, /^tables\[/) || $tables);" : "") . " }");
echo input_token(); echo "<input type='hidden' name='token' value='$token'>\n";
echo "</div></fieldset>\n"; echo "</div></fieldset>\n";
echo "</div></div>\n"; echo "</div></div>\n";
} }
@@ -165,18 +152,19 @@ if (adminer()->homepage()) {
echo script("tableCheck();"); echo script("tableCheck();");
} }
echo "<p class='links'><a href='" . h(ME) . "create='>" . lang('Create table') . "</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" : ""); echo (support("view") ? '<a href="' . h(ME) . 'view=">' . lang('Create view') . "</a>\n" : "");
if (support("routine")) { if (support("routine")) {
echo "<h3 id='routines'>" . lang('Routines') . "</h3>\n"; echo "<h3 id='routines'>" . lang('Routines') . "</h3>\n";
$routines = routines(); $routines = routines();
if ($routines) { if ($routines) {
echo "<table class='odds'>\n"; echo "<table cellspacing='0'>\n";
echo '<thead><tr><th>' . lang('Name') . '<td>' . lang('Type') . '<td>' . lang('Return type') . "<td></thead>\n"; echo '<thead><tr><th>' . lang('Name') . '<td>' . lang('Type') . '<td>' . lang('Return type') . "<td></thead>\n";
odd('');
foreach ($routines as $row) { foreach ($routines as $row) {
$name = ($row["SPECIFIC_NAME"] == $row["ROUTINE_NAME"] ? "" : "&name=" . urlencode($row["ROUTINE_NAME"])); // not computed on the pages to be able to print the header first $name = ($row["SPECIFIC_NAME"] == $row["ROUTINE_NAME"] ? "" : "&name=" . urlencode($row["ROUTINE_NAME"])); // not computed on the pages to be able to print the header first
echo '<tr>'; echo '<tr' . odd() . '>';
echo '<th><a href="' . h(ME . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'callf=' : 'call=') . urlencode($row["SPECIFIC_NAME"]) . $name) . '">' . h($row["ROUTINE_NAME"]) . '</a>'; echo '<th><a href="' . h(ME . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'callf=' : 'call=') . urlencode($row["SPECIFIC_NAME"]) . $name) . '">' . h($row["ROUTINE_NAME"]) . '</a>';
echo '<td>' . h($row["ROUTINE_TYPE"]); echo '<td>' . h($row["ROUTINE_TYPE"]);
echo '<td>' . h($row["DTD_IDENTIFIER"]); echo '<td>' . h($row["DTD_IDENTIFIER"]);
@@ -194,10 +182,11 @@ if (adminer()->homepage()) {
echo "<h3 id='sequences'>" . lang('Sequences') . "</h3>\n"; echo "<h3 id='sequences'>" . lang('Sequences') . "</h3>\n";
$sequences = get_vals("SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = current_schema() ORDER BY sequence_name"); $sequences = get_vals("SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = current_schema() ORDER BY sequence_name");
if ($sequences) { if ($sequences) {
echo "<table class='odds'>\n"; echo "<table cellspacing='0'>\n";
echo "<thead><tr><th>" . lang('Name') . "</thead>\n"; echo "<thead><tr><th>" . lang('Name') . "</thead>\n";
odd('');
foreach ($sequences as $val) { foreach ($sequences as $val) {
echo "<tr><th><a href='" . h(ME) . "sequence=" . urlencode($val) . "'>" . h($val) . "</a>\n"; echo "<tr" . odd() . "><th><a href='" . h(ME) . "sequence=" . urlencode($val) . "'>" . h($val) . "</a>\n";
} }
echo "</table>\n"; echo "</table>\n";
} }
@@ -208,10 +197,11 @@ if (adminer()->homepage()) {
echo "<h3 id='user-types'>" . lang('User types') . "</h3>\n"; echo "<h3 id='user-types'>" . lang('User types') . "</h3>\n";
$user_types = types(); $user_types = types();
if ($user_types) { if ($user_types) {
echo "<table class='odds'>\n"; echo "<table cellspacing='0'>\n";
echo "<thead><tr><th>" . lang('Name') . "</thead>\n"; echo "<thead><tr><th>" . lang('Name') . "</thead>\n";
odd('');
foreach ($user_types as $val) { foreach ($user_types as $val) {
echo "<tr><th><a href='" . h(ME) . "type=" . urlencode($val) . "'>" . h($val) . "</a>\n"; echo "<tr" . odd() . "><th><a href='" . h(ME) . "type=" . urlencode($val) . "'>" . h($val) . "</a>\n";
} }
echo "</table>\n"; echo "</table>\n";
} }
@@ -222,7 +212,7 @@ if (adminer()->homepage()) {
echo "<h3 id='events'>" . lang('Events') . "</h3>\n"; echo "<h3 id='events'>" . lang('Events') . "</h3>\n";
$rows = get_rows("SHOW EVENTS"); $rows = get_rows("SHOW EVENTS");
if ($rows) { if ($rows) {
echo "<table>\n"; echo "<table cellspacing='0'>\n";
echo "<thead><tr><th>" . lang('Name') . "<td>" . lang('Schedule') . "<td>" . lang('Start') . "<td>" . lang('End') . "<td></thead>\n"; echo "<thead><tr><th>" . lang('Name') . "<td>" . lang('Schedule') . "<td>" . lang('Start') . "<td>" . lang('End') . "<td></thead>\n";
foreach ($rows as $row) { foreach ($rows as $row) {
echo "<tr>"; echo "<tr>";
@@ -232,7 +222,7 @@ if (adminer()->homepage()) {
echo '<td><a href="' . h(ME) . 'event=' . urlencode($row["Name"]) . '">' . lang('Alter') . '</a>'; echo '<td><a href="' . h(ME) . 'event=' . urlencode($row["Name"]) . '">' . lang('Alter') . '</a>';
} }
echo "</table>\n"; echo "</table>\n";
$event_scheduler = get_val("SELECT @@event_scheduler"); $event_scheduler = $connection->result("SELECT @@event_scheduler");
if ($event_scheduler && $event_scheduler != "ON") { if ($event_scheduler && $event_scheduler != "ON") {
echo "<p class='error'><code class='jush-sqlset'>event_scheduler</code>: " . h($event_scheduler) . "\n"; echo "<p class='error'><code class='jush-sqlset'>event_scheduler</code>: " . h($event_scheduler) . "\n";
} }

View File

@@ -1,11 +1,12 @@
<?php <?php
function adminer_object() { function adminer_object() {
include_once "../plugins/plugin.php";
include_once "../plugins/designs.php"; include_once "../plugins/designs.php";
$designs = array(); $designs = array();
foreach (glob("../designs/*/*.css") as $filename) { foreach (glob("../designs/*", GLOB_ONLYDIR) as $filename) {
$designs[$filename] = basename(dirname($filename)); $designs["$filename/adminer.css"] = basename($filename);
} }
return new Adminer\Plugins(array( return new AdminerPlugin(array(
new AdminerDesigns($designs), new AdminerDesigns($designs),
)); ));
} }

View File

@@ -1,12 +1,10 @@
<?php <?php
namespace Adminer;
$TABLE = $_GET["download"]; $TABLE = $_GET["download"];
$fields = fields($TABLE); $fields = fields($TABLE);
header("Content-Type: application/octet-stream"); header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=" . friendly_url("$TABLE-" . implode("_", $_GET["where"])) . "." . friendly_url($_GET["field"])); header("Content-Disposition: attachment; filename=" . friendly_url("$TABLE-" . implode("_", $_GET["where"])) . "." . friendly_url($_GET["field"]));
$select = array(idf_escape($_GET["field"])); $select = array(idf_escape($_GET["field"]));
$result = driver()->select($TABLE, $select, array(where($_GET, $fields)), $select); $result = $driver->select($TABLE, $select, array(where($_GET, $fields)), $select);
$row = ($result ? $result->fetch_row() : array()); $row = ($result ? $result->fetch_row() : array());
echo driver()->value($row[0], $fields[$_GET["field"]]); echo $driver->value($row[0], $fields[$_GET["field"]]);
exit; // don't output footer exit; // don't output footer

View File

@@ -0,0 +1,747 @@
<?php
$drivers["mongo"] = "MongoDB (alpha)";
if (isset($_GET["mongo"])) {
define("DRIVER", "mongo");
if (class_exists('MongoDB')) {
class Min_DB {
var $extension = "Mongo", $server_info = MongoClient::VERSION, $error, $last_id, $_link, $_db;
function connect($uri, $options) {
try {
$this->_link = new MongoClient($uri, $options);
if ($options["password"] != "") {
$options["password"] = "";
try {
new MongoClient($uri, $options);
$this->error = lang('Database does not support password.');
} catch (Exception $e) {
// this is what we want
}
}
} catch (Exception $e) {
$this->error = $e->getMessage();
}
}
function query($query) {
return false;
}
function select_db($database) {
try {
$this->_db = $this->_link->selectDB($database);
return true;
} catch (Exception $ex) {
$this->error = $ex->getMessage();
return false;
}
}
function quote($string) {
return $string;
}
}
class Min_Result {
var $num_rows, $_rows = array(), $_offset = 0, $_charset = array();
function __construct($result) {
foreach ($result as $item) {
$row = array();
foreach ($item as $key => $val) {
if (is_a($val, 'MongoBinData')) {
$this->_charset[$key] = 63;
}
$row[$key] =
(is_a($val, 'MongoId') ? "ObjectId(\"$val\")" :
(is_a($val, 'MongoDate') ? gmdate("Y-m-d H:i:s", $val->sec) . " GMT" :
(is_a($val, 'MongoBinData') ? $val->bin : //! allow downloading
(is_a($val, 'MongoRegex') ? "$val" :
(is_object($val) ? get_class($val) : // MongoMinKey, MongoMaxKey
$val
)))));
}
$this->_rows[] = $row;
foreach ($row as $key => $val) {
if (!isset($this->_rows[0][$key])) {
$this->_rows[0][$key] = null;
}
}
}
$this->num_rows = count($this->_rows);
}
function fetch_assoc() {
$row = current($this->_rows);
if (!$row) {
return $row;
}
$return = array();
foreach ($this->_rows[0] as $key => $val) {
$return[$key] = $row[$key];
}
next($this->_rows);
return $return;
}
function fetch_row() {
$return = $this->fetch_assoc();
if (!$return) {
return $return;
}
return array_values($return);
}
function fetch_field() {
$keys = array_keys($this->_rows[0]);
$name = $keys[$this->_offset++];
return (object) array(
'name' => $name,
'charsetnr' => $this->_charset[$name],
);
}
}
class Min_Driver extends Min_SQL {
public $primary = "_id";
function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
$select = ($select == array("*")
? array()
: array_fill_keys($select, true)
);
$sort = array();
foreach ($order as $val) {
$val = preg_replace('~ DESC$~', '', $val, 1, $count);
$sort[$val] = ($count ? -1 : 1);
}
return new Min_Result($this->_conn->_db->selectCollection($table)
->find(array(), $select)
->sort($sort)
->limit($limit != "" ? +$limit : 0)
->skip($page * $limit)
);
}
function insert($table, $set) {
try {
$return = $this->_conn->_db->selectCollection($table)->insert($set);
$this->_conn->errno = $return['code'];
$this->_conn->error = $return['err'];
$this->_conn->last_id = $set['_id'];
return !$return['err'];
} catch (Exception $ex) {
$this->_conn->error = $ex->getMessage();
return false;
}
}
}
function get_databases($flush) {
global $connection;
$return = array();
$dbs = $connection->_link->listDBs();
foreach ($dbs['databases'] as $db) {
$return[] = $db['name'];
}
return $return;
}
function count_tables($databases) {
global $connection;
$return = array();
foreach ($databases as $db) {
$return[$db] = count($connection->_link->selectDB($db)->getCollectionNames(true));
}
return $return;
}
function tables_list() {
global $connection;
return array_fill_keys($connection->_db->getCollectionNames(true), 'table');
}
function drop_databases($databases) {
global $connection;
foreach ($databases as $db) {
$response = $connection->_link->selectDB($db)->drop();
if (!$response['ok']) {
return false;
}
}
return true;
}
function indexes($table, $connection2 = null) {
global $connection;
$return = array();
foreach ($connection->_db->selectCollection($table)->getIndexInfo() as $index) {
$descs = array();
foreach ($index["key"] as $column => $type) {
$descs[] = ($type == -1 ? '1' : null);
}
$return[$index["name"]] = array(
"type" => ($index["name"] == "_id_" ? "PRIMARY" : ($index["unique"] ? "UNIQUE" : "INDEX")),
"columns" => array_keys($index["key"]),
"lengths" => array(),
"descs" => $descs,
);
}
return $return;
}
function fields($table) {
return fields_from_edit();
}
function found_rows($table_status, $where) {
global $connection;
//! don't call count_rows()
return $connection->_db->selectCollection($_GET["select"])->count($where);
}
$operators = array("=");
} elseif (class_exists('MongoDB\Driver\Manager')) {
class Min_DB {
var $extension = "MongoDB", $server_info = MONGODB_VERSION, $affected_rows, $error, $last_id;
/** @var MongoDB\Driver\Manager */
var $_link;
var $_db, $_db_name;
function connect($uri, $options) {
$class = 'MongoDB\Driver\Manager';
$this->_link = new $class($uri, $options);
$this->executeCommand('admin', array('ping' => 1));
}
function executeCommand($db, $command) {
$class = 'MongoDB\Driver\Command';
try {
return $this->_link->executeCommand($db, new $class($command));
} catch (Exception $e) {
$this->error = $e->getMessage();
return array();
}
}
function executeBulkWrite($namespace, $bulk, $counter) {
try {
$results = $this->_link->executeBulkWrite($namespace, $bulk);
$this->affected_rows = $results->$counter();
return true;
} catch (Exception $e) {
$this->error = $e->getMessage();
return false;
}
}
function query($query) {
return false;
}
function select_db($database) {
$this->_db_name = $database;
return true;
}
function quote($string) {
return $string;
}
}
class Min_Result {
var $num_rows, $_rows = array(), $_offset = 0, $_charset = array();
function __construct($result) {
foreach ($result as $item) {
$row = array();
foreach ($item as $key => $val) {
if (is_a($val, 'MongoDB\BSON\Binary')) {
$this->_charset[$key] = 63;
}
$row[$key] =
(is_a($val, 'MongoDB\BSON\ObjectID') ? 'MongoDB\BSON\ObjectID("' . "$val\")" :
(is_a($val, 'MongoDB\BSON\UTCDatetime') ? $val->toDateTime()->format('Y-m-d H:i:s') :
(is_a($val, 'MongoDB\BSON\Binary') ? $val->getData() : //! allow downloading
(is_a($val, 'MongoDB\BSON\Regex') ? "$val" :
(is_object($val) || is_array($val) ? json_encode($val, 256) : // 256 = JSON_UNESCAPED_UNICODE
$val // MongoMinKey, MongoMaxKey
)))));
}
$this->_rows[] = $row;
foreach ($row as $key => $val) {
if (!isset($this->_rows[0][$key])) {
$this->_rows[0][$key] = null;
}
}
}
$this->num_rows = count($this->_rows);
}
function fetch_assoc() {
$row = current($this->_rows);
if (!$row) {
return $row;
}
$return = array();
foreach ($this->_rows[0] as $key => $val) {
$return[$key] = $row[$key];
}
next($this->_rows);
return $return;
}
function fetch_row() {
$return = $this->fetch_assoc();
if (!$return) {
return $return;
}
return array_values($return);
}
function fetch_field() {
$keys = array_keys($this->_rows[0]);
$name = $keys[$this->_offset++];
return (object) array(
'name' => $name,
'charsetnr' => $this->_charset[$name],
);
}
}
class Min_Driver extends Min_SQL {
public $primary = "_id";
function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
global $connection;
$select = ($select == array("*")
? array()
: array_fill_keys($select, 1)
);
if (count($select) && !isset($select['_id'])) {
$select['_id'] = 0;
}
$where = where_to_query($where);
$sort = array();
foreach ($order as $val) {
$val = preg_replace('~ DESC$~', '', $val, 1, $count);
$sort[$val] = ($count ? -1 : 1);
}
if (isset($_GET['limit']) && is_numeric($_GET['limit']) && $_GET['limit'] > 0) {
$limit = $_GET['limit'];
}
$limit = min(200, max(1, (int) $limit));
$skip = $page * $limit;
$class = 'MongoDB\Driver\Query';
try {
return new Min_Result($connection->_link->executeQuery("$connection->_db_name.$table", new $class($where, array('projection' => $select, 'limit' => $limit, 'skip' => $skip, 'sort' => $sort))));
} catch (Exception $e) {
$connection->error = $e->getMessage();
return false;
}
}
function update($table, $set, $queryWhere, $limit = 0, $separator = "\n") {
global $connection;
$db = $connection->_db_name;
$where = sql_query_where_parser($queryWhere);
$class = 'MongoDB\Driver\BulkWrite';
$bulk = new $class(array());
if (isset($set['_id'])) {
unset($set['_id']);
}
$removeFields = array();
foreach ($set as $key => $value) {
if ($value == 'NULL') {
$removeFields[$key] = 1;
unset($set[$key]);
}
}
$update = array('$set' => $set);
if (count($removeFields)) {
$update['$unset'] = $removeFields;
}
$bulk->update($where, $update, array('upsert' => false));
return $connection->executeBulkWrite("$db.$table", $bulk, 'getModifiedCount');
}
function delete($table, $queryWhere, $limit = 0) {
global $connection;
$db = $connection->_db_name;
$where = sql_query_where_parser($queryWhere);
$class = 'MongoDB\Driver\BulkWrite';
$bulk = new $class(array());
$bulk->delete($where, array('limit' => $limit));
return $connection->executeBulkWrite("$db.$table", $bulk, 'getDeletedCount');
}
function insert($table, $set) {
global $connection;
$db = $connection->_db_name;
$class = 'MongoDB\Driver\BulkWrite';
$bulk = new $class(array());
if ($set['_id'] == '') {
unset($set['_id']);
}
$bulk->insert($set);
return $connection->executeBulkWrite("$db.$table", $bulk, 'getInsertedCount');
}
}
function get_databases($flush) {
global $connection;
$return = array();
foreach ($connection->executeCommand('admin', array('listDatabases' => 1)) as $dbs) {
foreach ($dbs->databases as $db) {
$return[] = $db->name;
}
}
return $return;
}
function count_tables($databases) {
$return = array();
return $return;
}
function tables_list() {
global $connection;
$collections = array();
foreach ($connection->executeCommand($connection->_db_name, array('listCollections' => 1)) as $result) {
$collections[$result->name] = 'table';
}
return $collections;
}
function drop_databases($databases) {
return false;
}
function indexes($table, $connection2 = null) {
global $connection;
$return = array();
foreach ($connection->executeCommand($connection->_db_name, array('listIndexes' => $table)) as $index) {
$descs = array();
$columns = array();
foreach (get_object_vars($index->key) as $column => $type) {
$descs[] = ($type == -1 ? '1' : null);
$columns[] = $column;
}
$return[$index->name] = array(
"type" => ($index->name == "_id_" ? "PRIMARY" : (isset($index->unique) ? "UNIQUE" : "INDEX")),
"columns" => $columns,
"lengths" => array(),
"descs" => $descs,
);
}
return $return;
}
function fields($table) {
global $driver;
$fields = fields_from_edit();
if (!$fields) {
$result = $driver->select($table, array("*"), null, null, array(), 10);
if ($result) {
while ($row = $result->fetch_assoc()) {
foreach ($row as $key => $val) {
$row[$key] = null;
$fields[$key] = array(
"field" => $key,
"type" => "string",
"null" => ($key != $driver->primary),
"auto_increment" => ($key == $driver->primary),
"privileges" => array(
"insert" => 1,
"select" => 1,
"update" => 1,
"where" => 1,
"order" => 1,
),
);
}
}
}
}
return $fields;
}
function found_rows($table_status, $where) {
global $connection;
$where = where_to_query($where);
$toArray = $connection->executeCommand($connection->_db_name, array('count' => $table_status['Name'], 'query' => $where))->toArray();
return $toArray[0]->n;
}
function sql_query_where_parser($queryWhere) {
$queryWhere = preg_replace('~^\sWHERE \(?\(?(.+?)\)?\)?$~', '\1', $queryWhere);
$wheres = explode(' AND ', $queryWhere);
$wheresOr = explode(') OR (', $queryWhere);
$where = array();
foreach ($wheres as $whereStr) {
$where[] = trim($whereStr);
}
if (count($wheresOr) == 1) {
$wheresOr = array();
} elseif (count($wheresOr) > 1) {
$where = array();
}
return where_to_query($where, $wheresOr);
}
function where_to_query($whereAnd = array(), $whereOr = array()) {
global $adminer;
$data = array();
foreach (array('and' => $whereAnd, 'or' => $whereOr) as $type => $where) {
if (is_array($where)) {
foreach ($where as $expression) {
list($col, $op, $val) = explode(" ", $expression, 3);
if ($col == "_id" && preg_match('~^(MongoDB\\\\BSON\\\\ObjectID)\("(.+)"\)$~', $val, $match)) {
list(, $class, $val) = $match;
$val = new $class($val);
}
if (!in_array($op, $adminer->operators)) {
continue;
}
if (preg_match('~^\(f\)(.+)~', $op, $match)) {
$val = (float) $val;
$op = $match[1];
} elseif (preg_match('~^\(date\)(.+)~', $op, $match)) {
$dateTime = new DateTime($val);
$class = 'MongoDB\BSON\UTCDatetime';
$val = new $class($dateTime->getTimestamp() * 1000);
$op = $match[1];
}
switch ($op) {
case '=':
$op = '$eq';
break;
case '!=':
$op = '$ne';
break;
case '>':
$op = '$gt';
break;
case '<':
$op = '$lt';
break;
case '>=':
$op = '$gte';
break;
case '<=':
$op = '$lte';
break;
case 'regex':
$op = '$regex';
break;
default:
continue 2;
}
if ($type == 'and') {
$data['$and'][] = array($col => array($op => $val));
} elseif ($type == 'or') {
$data['$or'][] = array($col => array($op => $val));
}
}
}
}
return $data;
}
$operators = array(
"=",
"!=",
">",
"<",
">=",
"<=",
"regex",
"(f)=",
"(f)!=",
"(f)>",
"(f)<",
"(f)>=",
"(f)<=",
"(date)=",
"(date)!=",
"(date)>",
"(date)<",
"(date)>=",
"(date)<=",
);
}
function table($idf) {
return $idf;
}
function idf_escape($idf) {
return $idf;
}
function table_status($name = "", $fast = false) {
$return = array();
foreach (tables_list() as $table => $type) {
$return[$table] = array("Name" => $table);
if ($name == $table) {
return $return[$table];
}
}
return $return;
}
function create_database($db, $collation) {
return true;
}
function last_id() {
global $connection;
return $connection->last_id;
}
function error() {
global $connection;
return h($connection->error);
}
function collations() {
return array();
}
function logged_user() {
global $adminer;
$credentials = $adminer->credentials();
return $credentials[1];
}
function connect() {
global $adminer;
$connection = new Min_DB;
list($server, $username, $password) = $adminer->credentials();
$options = array();
if ($username . $password != "") {
$options["username"] = $username;
$options["password"] = $password;
}
$db = $adminer->database();
if ($db != "") {
$options["db"] = $db;
}
if (($auth_source = getenv("MONGO_AUTH_SOURCE"))) {
$options["authSource"] = $auth_source;
}
$connection->connect("mongodb://$server", $options);
if ($connection->error) {
return $connection->error;
}
return $connection;
}
function alter_indexes($table, $alter) {
global $connection;
foreach ($alter as $val) {
list($type, $name, $set) = $val;
if ($set == "DROP") {
$return = $connection->_db->command(array("deleteIndexes" => $table, "index" => $name));
} else {
$columns = array();
foreach ($set as $column) {
$column = preg_replace('~ DESC$~', '', $column, 1, $count);
$columns[$column] = ($count ? -1 : 1);
}
$return = $connection->_db->selectCollection($table)->ensureIndex($columns, array(
"unique" => ($type == "UNIQUE"),
"name" => $name,
//! "sparse"
));
}
if ($return['errmsg']) {
$connection->error = $return['errmsg'];
return false;
}
}
return true;
}
function support($feature) {
return preg_match("~database|indexes|descidx~", $feature);
}
function db_collation($db, $collations) {
}
function information_schema() {
}
function is_view($table_status) {
}
function convert_field($field) {
}
function unconvert_field($field, $return) {
return $return;
}
function foreign_keys($table) {
return array();
}
function fk_support($table_status) {
}
function engines() {
return array();
}
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
global $connection;
if ($table == "") {
$connection->_db->createCollection($name);
return true;
}
}
function drop_tables($tables) {
global $connection;
foreach ($tables as $table) {
$response = $connection->_db->selectCollection($table)->drop();
if (!$response['ok']) {
return false;
}
}
return true;
}
function truncate_tables($tables) {
global $connection;
foreach ($tables as $table) {
$response = $connection->_db->selectCollection($table)->remove();
if (!$response['ok']) {
return false;
}
}
return true;
}
function driver_config() {
global $operators;
return array(
'possible_drivers' => array("mongo", "mongodb"),
'jush' => "mongo",
'operators' => $operators,
'functions' => array(),
'grouping' => array(),
'edit_functions' => array(array("json")),
);
}
}

View File

@@ -5,18 +5,15 @@
* @author Jakub Vrana * @author Jakub Vrana
*/ */
namespace Adminer; $drivers["mssql"] = "MS SQL (beta)";
add_driver("mssql", "MS SQL");
if (isset($_GET["mssql"])) { if (isset($_GET["mssql"])) {
define('Adminer\DRIVER', "mssql"); define("DRIVER", "mssql");
if (extension_loaded("sqlsrv") && $_GET["ext"] != "pdo") { if (extension_loaded("sqlsrv")) {
class Db extends SqlDb { class Min_DB {
public string $extension = "sqlsrv"; var $extension = "sqlsrv", $_link, $_result, $server_info, $affected_rows, $errno, $error;
private $link, $result;
private function get_error() { function _get_error() {
$this->error = ""; $this->error = "";
foreach (sqlsrv_errors() as $error) { foreach (sqlsrv_errors() as $error) {
$this->errno = $error["code"]; $this->errno = $error["code"];
@@ -25,53 +22,46 @@ if (isset($_GET["mssql"])) {
$this->error = rtrim($this->error); $this->error = rtrim($this->error);
} }
function attach(?string $server, string $username, string $password): string { function connect($server, $username, $password) {
global $adminer;
$db = $adminer->database();
$connection_info = array("UID" => $username, "PWD" => $password, "CharacterSet" => "UTF-8"); $connection_info = array("UID" => $username, "PWD" => $password, "CharacterSet" => "UTF-8");
$ssl = adminer()->connectSsl();
if (isset($ssl["Encrypt"])) {
$connection_info["Encrypt"] = $ssl["Encrypt"];
}
if (isset($ssl["TrustServerCertificate"])) {
$connection_info["TrustServerCertificate"] = $ssl["TrustServerCertificate"];
}
$db = adminer()->database();
if ($db != "") { if ($db != "") {
$connection_info["Database"] = $db; $connection_info["Database"] = $db;
} }
$this->link = @sqlsrv_connect(preg_replace('~:~', ',', $server), $connection_info); $this->_link = @sqlsrv_connect(preg_replace('~:~', ',', $server), $connection_info);
if ($this->link) { if ($this->_link) {
$info = sqlsrv_server_info($this->link); $info = sqlsrv_server_info($this->_link);
$this->server_info = $info['SQLServerVersion']; $this->server_info = $info['SQLServerVersion'];
} else { } else {
$this->get_error(); $this->_get_error();
} }
return ($this->link ? '' : $this->error); return (bool) $this->_link;
} }
function quote(string $string): string { function quote($string) {
$unicode = strlen($string) != strlen(utf8_decode($string)); return "'" . str_replace("'", "''", $string) . "'";
return ($unicode ? "N" : "") . "'" . str_replace("'", "''", $string) . "'";
} }
function select_db(string $database) { function select_db($database) {
return $this->query(use_sql($database)); return $this->query("USE " . idf_escape($database));
} }
function query(string $query, bool $unbuffered = false) { 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 = ""; $this->error = "";
if (!$result) { if (!$result) {
$this->get_error(); $this->_get_error();
return false; return false;
} }
return $this->store_result($result); return $this->store_result($result);
} }
function multi_query(string $query) { function multi_query($query) {
$this->result = sqlsrv_query($this->link, $query); $this->_result = sqlsrv_query($this->_link, $query);
$this->error = ""; $this->error = "";
if (!$this->result) { if (!$this->_result) {
$this->get_error(); $this->_get_error();
return false; return false;
} }
return true; return true;
@@ -79,33 +69,41 @@ if (isset($_GET["mssql"])) {
function store_result($result = null) { function store_result($result = null) {
if (!$result) { if (!$result) {
$result = $this->result; $result = $this->_result;
} }
if (!$result) { if (!$result) {
return false; return false;
} }
if (sqlsrv_field_metadata($result)) { if (sqlsrv_field_metadata($result)) {
return new Result($result); return new Min_Result($result);
} }
$this->affected_rows = sqlsrv_rows_affected($result); $this->affected_rows = sqlsrv_rows_affected($result);
return true; return true;
} }
function next_result(): bool { function next_result() {
return $this->result ? !!sqlsrv_next_result($this->result) : false; return $this->_result ? sqlsrv_next_result($this->_result) : null;
}
function result($query, $field = 0) {
$result = $this->query($query);
if (!is_object($result)) {
return false;
}
$row = $result->fetch_row();
return $row[$field];
} }
} }
class Result { class Min_Result {
public $num_rows; var $_result, $_offset = 0, $_fields, $num_rows;
private $result, $offset = 0, $fields;
function __construct($result) { function __construct($result) {
$this->result = $result; $this->_result = $result;
// $this->num_rows = sqlsrv_num_rows($result); // available only in scrollable results // $this->num_rows = sqlsrv_num_rows($result); // available only in scrollable results
} }
private function convert($row) { function _convert($row) {
foreach ((array) $row as $key => $val) { foreach ((array) $row as $key => $val) {
if (is_a($val, 'DateTime')) { if (is_a($val, 'DateTime')) {
$row[$key] = $val->format("Y-m-d H:i:s"); $row[$key] = $val->format("Y-m-d H:i:s");
@@ -116,174 +114,177 @@ if (isset($_GET["mssql"])) {
} }
function fetch_assoc() { 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() { 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(): \stdClass { function fetch_field() {
if (!$this->fields) { if (!$this->_fields) {
$this->fields = sqlsrv_field_metadata($this->result); $this->_fields = sqlsrv_field_metadata($this->_result);
} }
$field = $this->fields[$this->offset++]; $field = $this->_fields[$this->_offset++];
$return = new \stdClass; $return = new stdClass;
$return->name = $field["Name"]; $return->name = $field["Name"];
$return->type = ($field["Type"] == 1 ? 254 : 15); $return->orgname = $field["Name"];
$return->charsetnr = 0; $return->type = ($field["Type"] == 1 ? 254 : 0);
return $return; return $return;
} }
function seek($offset) { function seek($offset) {
for ($i=0; $i < $offset; $i++) { 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() { function __destruct() {
sqlsrv_free_stmt($this->result); sqlsrv_free_stmt($this->_result);
} }
} }
function last_id($result) { } elseif (extension_loaded("mssql")) {
return get_val("SELECT SCOPE_IDENTITY()"); // @@IDENTITY can return trigger INSERT class Min_DB {
var $extension = "MSSQL", $_link, $_result, $server_info, $affected_rows, $error;
function connect($server, $username, $password) {
$this->_link = @mssql_connect($server, $username, $password);
if ($this->_link) {
$result = $this->query("SELECT SERVERPROPERTY('ProductLevel'), SERVERPROPERTY('Edition')");
if ($result) {
$row = $result->fetch_row();
$this->server_info = $this->result("sp_server_info 2", 2) . " [$row[0]] $row[1]";
}
} else {
$this->error = mssql_get_last_message();
}
return (bool) $this->_link;
} }
function explain($connection, $query) { function quote($string) {
$connection->query("SET SHOWPLAN_ALL ON"); return "'" . str_replace("'", "''", $string) . "'";
$return = $connection->query($query); }
$connection->query("SET SHOWPLAN_ALL OFF"); // connection is used also for indexes
function select_db($database) {
return mssql_select_db($database);
}
function query($query, $unbuffered = false) {
$result = @mssql_query($query, $this->_link); //! $unbuffered
$this->error = "";
if (!$result) {
$this->error = mssql_get_last_message();
return false;
}
if ($result === true) {
$this->affected_rows = mssql_rows_affected($this->_link);
return true;
}
return new Min_Result($result);
}
function multi_query($query) {
return $this->_result = $this->query($query);
}
function store_result() {
return $this->_result;
}
function next_result() {
return mssql_next_result($this->_result->_result);
}
function result($query, $field = 0) {
$result = $this->query($query);
if (!is_object($result)) {
return false;
}
return mssql_result($result->_result, 0, $field);
}
}
class Min_Result {
var $_result, $_offset = 0, $_fields, $num_rows;
function __construct($result) {
$this->_result = $result;
$this->num_rows = mssql_num_rows($result);
}
function fetch_assoc() {
return mssql_fetch_assoc($this->_result);
}
function fetch_row() {
return mssql_fetch_row($this->_result);
}
function num_rows() {
return mssql_num_rows($this->_result);
}
function fetch_field() {
$return = mssql_fetch_field($this->_result);
$return->orgtable = $return->table;
$return->orgname = $return->name;
return $return; return $return;
} }
} else { function seek($offset) {
abstract class MssqlDb extends PdoDb { mssql_data_seek($this->_result, $offset);
function select_db(string $database) {
// database selection is separated from the connection so dbname in DSN can't be used
return $this->query(use_sql($database));
} }
function lastInsertId() { function __destruct() {
return $this->pdo->lastInsertId(); mssql_free_result($this->_result);
}
}
function last_id($result) {
return connection()->lastInsertId();
}
function explain($connection, $query) {
}
if (extension_loaded("pdo_sqlsrv")) {
class Db extends MssqlDb {
public string $extension = "PDO_SQLSRV";
function attach(?string $server, string $username, string $password): string {
return $this->dsn("sqlsrv:Server=" . str_replace(":", ",", $server), $username, $password);
} }
} }
} elseif (extension_loaded("pdo_dblib")) { } elseif (extension_loaded("pdo_dblib")) {
class Db extends MssqlDb { class Min_DB extends Min_PDO {
public string $extension = "PDO_DBLIB"; var $extension = "PDO_DBLIB";
function attach(?string $server, string $username, string $password): string { function connect($server, $username, $password) {
return $this->dsn("dblib:charset=utf8;host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\d)~', ';port=\1', $server)), $username, $password); $this->dsn("dblib:charset=utf8;host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\d)~', ';port=\1', $server)), $username, $password);
} return true;
}
function select_db($database) {
// database selection is separated from the connection so dbname in DSN can't be used
return $this->query("USE " . idf_escape($database));
} }
} }
} }
class Driver extends SqlDriver { class Min_Driver extends Min_SQL {
static array $extensions = array("SQLSRV", "PDO_SQLSRV", "PDO_DBLIB");
static string $jush = "mssql";
public array $insertFunctions = array("date|time" => "getdate"); function insertUpdate($table, $rows, $primary) {
public array $editFunctions = array( foreach ($rows as $set) {
"int|decimal|real|float|money|datetime" => "+/-",
"char|text" => "+",
);
public array $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL");
public array $functions = array("len", "lower", "round", "upper");
public array $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
public array $generated = array("PERSISTED", "VIRTUAL");
public string $onActions = "NO ACTION|CASCADE|SET NULL|SET DEFAULT";
static function connect(?string $server, string $username, string $password) {
if ($server == "") {
$server = "localhost:1433";
}
return parent::connect($server, $username, $password);
}
function __construct(Db $connection) {
parent::__construct($connection);
$this->types = array( //! use sys.types
lang('Numbers') => array("tinyint" => 3, "smallint" => 5, "int" => 10, "bigint" => 20, "bit" => 1, "decimal" => 0, "real" => 12, "float" => 53, "smallmoney" => 10, "money" => 20),
lang('Date and time') => array("date" => 10, "smalldatetime" => 19, "datetime" => 19, "datetime2" => 19, "time" => 8, "datetimeoffset" => 10),
lang('Strings') => array("char" => 8000, "varchar" => 8000, "text" => 2147483647, "nchar" => 4000, "nvarchar" => 4000, "ntext" => 1073741823),
lang('Binary') => array("binary" => 8000, "varbinary" => 8000, "image" => 2147483647),
);
}
function insertUpdate(string $table, array $rows, array $primary) {
$fields = fields($table);
$update = array(); $update = array();
$where = array(); $where = array();
$set = reset($rows);
$columns = "c" . implode(", c", range(1, count($set)));
$c = 0;
$insert = array();
foreach ($set as $key => $val) { foreach ($set as $key => $val) {
$c++; $update[] = "$key = $val";
$name = idf_unescape($key); if (isset($primary[idf_unescape($key)])) {
if (!$fields[$name]["auto_increment"]) { $where[] = "$key = $val";
$insert[$key] = "c$c";
}
if (isset($primary[$name])) {
$where[] = "$key = c$c";
} else {
$update[] = "$key = c$c";
} }
} }
$values = array(); //! can use only one query for all rows
foreach ($rows as $set) { if (!queries("MERGE " . table($table) . " USING (VALUES(" . implode(", ", $set) . ")) AS source (c" . implode(", c", range(1, count($set))) . ") ON " . implode(" AND ", $where) //! source, c1 - possible conflict
$values[] = "(" . implode(", ", $set) . ")"; . " WHEN MATCHED THEN UPDATE SET " . implode(", ", $update)
. " WHEN NOT MATCHED THEN INSERT (" . implode(", ", array_keys($set)) . ") VALUES (" . implode(", ", $set) . ");" // ; is mandatory
)) {
return false;
} }
if ($where) {
$identity = queries("SET IDENTITY_INSERT " . table($table) . " ON");
$return = queries(
"MERGE " . table($table) . " USING (VALUES\n\t" . implode(",\n\t", $values) . "\n) AS source ($columns) ON " . implode(" AND ", $where) //! source, c1 - possible conflict
. ($update ? "\nWHEN MATCHED THEN UPDATE SET " . implode(", ", $update) : "")
. "\nWHEN NOT MATCHED THEN INSERT (" . implode(", ", array_keys($identity ? $set : $insert)) . ") VALUES (" . ($identity ? $columns : implode(", ", $insert)) . ");" // ; is mandatory
);
if ($identity) {
queries("SET IDENTITY_INSERT " . table($table) . " OFF");
} }
} else { return true;
$return = queries("INSERT INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ") VALUES\n" . implode(",\n", $values));
}
return $return;
} }
function begin() { function begin() {
return queries("BEGIN TRANSACTION"); return queries("BEGIN TRANSACTION");
} }
function tableHelp(string $name, bool $is_view = false) {
$links = array(
"sys" => "catalog-views/sys-",
"INFORMATION_SCHEMA" => "information-schema-views/",
);
$link = $links[get_schema()];
if ($link) {
return "relational-databases/system-$link" . preg_replace('~_~', '-', strtolower($name)) . "-transact-sql";
}
}
} }
@@ -296,12 +297,22 @@ if (isset($_GET["mssql"])) {
return ($_GET["ns"] != "" ? idf_escape($_GET["ns"]) . "." : "") . idf_escape($idf); return ($_GET["ns"] != "" ? idf_escape($_GET["ns"]) . "." : "") . idf_escape($idf);
} }
function get_databases($flush) { function connect() {
global $adminer;
$connection = new Min_DB;
$credentials = $adminer->credentials();
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
return $connection;
}
return $connection->error;
}
function get_databases() {
return get_vals("SELECT name FROM sys.databases WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb')"); return get_vals("SELECT name FROM sys.databases WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb')");
} }
function limit($query, $where, $limit, $offset = 0, $separator = " ") { function limit($query, $where, $limit, $offset = 0, $separator = " ") {
return ($limit ? " TOP (" . ($limit + $offset) . ")" : "") . " $query$where"; // seek later return ($limit !== null ? " TOP (" . ($limit + $offset) . ")" : "") . " $query$where"; // seek later
} }
function limit1($table, $query, $where, $separator = "\n") { function limit1($table, $query, $where, $separator = "\n") {
@@ -309,11 +320,17 @@ if (isset($_GET["mssql"])) {
} }
function db_collation($db, $collations) { function db_collation($db, $collations) {
return get_val("SELECT collation_name FROM sys.databases WHERE name = " . q($db)); global $connection;
return $connection->result("SELECT collation_name FROM sys.databases WHERE name = " . q($db));
}
function engines() {
return array();
} }
function logged_user() { function logged_user() {
return get_val("SELECT SUSER_NAME()"); global $connection;
return $connection->result("SELECT SUSER_NAME()");
} }
function tables_list() { function tables_list() {
@@ -321,21 +338,21 @@ if (isset($_GET["mssql"])) {
} }
function count_tables($databases) { function count_tables($databases) {
global $connection;
$return = array(); $return = array();
foreach ($databases as $db) { foreach ($databases as $db) {
connection()->select_db($db); $connection->select_db($db);
$return[$db] = get_val("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES"); $return[$db] = $connection->result("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES");
} }
return $return; return $return;
} }
function table_status($name = "") { function table_status($name = "") {
$return = array(); $return = array();
foreach ( foreach (get_rows("SELECT ao.name AS Name, ao.type_desc AS Engine, (SELECT value FROM fn_listextendedproperty(default, 'SCHEMA', schema_name(schema_id), 'TABLE', ao.name, null, null)) AS Comment FROM sys.all_objects AS ao WHERE schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND type IN ('S', 'U', 'V') " . ($name != "" ? "AND name = " . q($name) : "ORDER BY name")) as $row) {
get_rows("SELECT ao.name AS Name, ao.type_desc AS Engine, (SELECT value FROM fn_listextendedproperty(default, 'SCHEMA', schema_name(schema_id), 'TABLE', ao.name, null, null)) AS Comment if ($name != "") {
FROM sys.all_objects AS ao return $row;
WHERE schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND type IN ('S', 'U', 'V') " . ($name != "" ? "AND name = " . q($name) : "ORDER BY name")) as $row }
) {
$return[$row["Name"]] = $row; $return[$row["Name"]] = $row;
} }
return $return; return $return;
@@ -352,53 +369,41 @@ WHERE schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND type IN ('S', 'U', 'V')
function fields($table) { function fields($table) {
$comments = get_key_vals("SELECT objname, cast(value as varchar(max)) FROM fn_listextendedproperty('MS_DESCRIPTION', 'schema', " . q(get_schema()) . ", 'table', " . q($table) . ", 'column', NULL)"); $comments = get_key_vals("SELECT objname, cast(value as varchar(max)) FROM fn_listextendedproperty('MS_DESCRIPTION', 'schema', " . q(get_schema()) . ", 'table', " . q($table) . ", 'column', NULL)");
$return = array(); $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]
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, d.definition [default], d.name default_constraint, i.is_primary_key
FROM sys.all_columns c FROM sys.all_columns c
JOIN sys.all_objects o ON c.object_id = o.object_id
JOIN sys.types t ON c.user_type_id = t.user_type_id 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 LEFT JOIN sys.default_constraints d ON c.default_object_id = d.parent_column_id
LEFT JOIN sys.index_columns ic ON c.object_id = ic.object_id AND c.column_id = ic.column_id WHERE o.schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND o.type IN ('S', 'U', 'V') AND o.name = " . q($table)
LEFT JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id ) as $row) {
WHERE c.object_id = " . q($table_id)) as $row
) {
$type = $row["type"]; $type = $row["type"];
$length = (preg_match("~char|binary~", $type) $length = (preg_match("~char|binary~", $type) ? $row["max_length"] : ($type == "decimal" ? "$row[precision],$row[scale]" : ""));
? intval($row["max_length"]) / ($type[0] == 'n' ? 2 : 1)
: ($type == "decimal" ? "$row[precision],$row[scale]" : "")
);
$return[$row["name"]] = array( $return[$row["name"]] = array(
"field" => $row["name"], "field" => $row["name"],
"full_type" => $type . ($length ? "($length)" : ""), "full_type" => $type . ($length ? "($length)" : ""),
"type" => $type, "type" => $type,
"length" => $length, "length" => $length,
"default" => (preg_match("~^\('(.*)'\)$~", $row["default"], $match) ? str_replace("''", "'", $match[1]) : $row["default"]), "default" => $row["default"],
"default_constraint" => $row["default_constraint"],
"null" => $row["is_nullable"], "null" => $row["is_nullable"],
"auto_increment" => $row["is_identity"], "auto_increment" => $row["is_identity"],
"collation" => $row["collation_name"], "collation" => $row["collation_name"],
"privileges" => array("insert" => 1, "select" => 1, "update" => 1, "where" => 1, "order" => 1), "privileges" => array("insert" => 1, "select" => 1, "update" => 1, "where" => 1, "order" => 1),
"primary" => $row["is_primary_key"], "primary" => $row["is_identity"], //! or indexes.is_primary_key
"comment" => $comments[$row["name"]], "comment" => $comments[$row["name"]],
); );
} }
foreach (get_rows("SELECT * FROM sys.computed_columns WHERE object_id = " . q($table_id)) as $row) {
$return[$row["name"]]["generated"] = ($row["is_persisted"] ? "PERSISTED" : "VIRTUAL");
$return[$row["name"]]["default"] = $row["definition"];
}
return $return; return $return;
} }
function indexes($table, $connection2 = null) { function indexes($table, $connection2 = null) {
$return = array(); $return = array();
// sp_statistics doesn't return information about primary key // sp_statistics doesn't return information about primary key
foreach ( foreach (get_rows("SELECT i.name, key_ordinal, is_unique, is_primary_key, c.name AS column_name, is_descending_key
get_rows("SELECT i.name, key_ordinal, is_unique, is_primary_key, c.name AS column_name, is_descending_key
FROM sys.indexes i FROM sys.indexes i
INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row WHERE OBJECT_NAME(i.object_id) = " . q($table)
) { , $connection2) as $row) {
$name = $row["name"]; $name = $row["name"];
$return[$name]["type"] = ($row["is_primary_key"] ? "PRIMARY" : ($row["is_unique"] ? "UNIQUE" : "INDEX")); $return[$name]["type"] = ($row["is_primary_key"] ? "PRIMARY" : ($row["is_unique"] ? "UNIQUE" : "INDEX"));
$return[$name]["lengths"] = array(); $return[$name]["lengths"] = array();
@@ -409,7 +414,8 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
} }
function view($name) { function view($name) {
return array("select" => preg_replace('~^(?:[^[]|\[[^]]*])*\s+AS\s+~isU', '', get_val("SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = SCHEMA_NAME() AND TABLE_NAME = " . q($name)))); global $connection;
return array("select" => preg_replace('~^(?:[^[]|\[[^]]*])*\s+AS\s+~isU', '', $connection->result("SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = SCHEMA_NAME() AND TABLE_NAME = " . q($name))));
} }
function collations() { function collations() {
@@ -421,11 +427,12 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
} }
function information_schema($db) { function information_schema($db) {
return get_schema() == "INFORMATION_SCHEMA"; return false;
} }
function error() { function error() {
return nl_br(h(preg_replace('~^(\[[^]]*])+~m', '', connection()->error))); global $connection;
return nl_br(h(preg_replace('~^(\[[^]]*])+~m', '', $connection->error)));
} }
function create_database($db, $collation) { function create_database($db, $collation) {
@@ -433,7 +440,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
} }
function drop_databases($databases) { function drop_databases($databases) {
return queries("DROP DATABASE " . implode(", ", array_map('Adminer\idf_escape', $databases))); return queries("DROP DATABASE " . implode(", ", array_map('idf_escape', $databases)));
} }
function rename_database($name, $collation) { function rename_database($name, $collation) {
@@ -451,7 +458,6 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) { function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
$alter = array(); $alter = array();
$comments = array(); $comments = array();
$orig_fields = fields($table);
foreach ($fields as $field) { foreach ($fields as $field) {
$column = idf_escape($field[0]); $column = idf_escape($field[0]);
$val = $field[1]; $val = $field[1];
@@ -461,28 +467,14 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
$val[1] = preg_replace("~( COLLATE )'(\\w+)'~", '\1\2', $val[1]); $val[1] = preg_replace("~( COLLATE )'(\\w+)'~", '\1\2', $val[1]);
$comments[$field[0]] = $val[5]; $comments[$field[0]] = $val[5];
unset($val[5]); unset($val[5]);
if (preg_match('~ AS ~', $val[3])) {
unset($val[1], $val[2]);
}
if ($field[0] == "") { if ($field[0] == "") {
$alter["ADD"][] = "\n " . implode("", $val) . ($table == "" ? substr($foreign[$val[0]], 16 + strlen($val[0])) : ""); // 16 - strlen(" FOREIGN KEY ()") $alter["ADD"][] = "\n " . implode("", $val) . ($table == "" ? substr($foreign[$val[0]], 16 + strlen($val[0])) : ""); // 16 - strlen(" FOREIGN KEY ()")
} else { } else {
$default = $val[3];
unset($val[3]); // default values are set separately
unset($val[6]); //! identity can't be removed unset($val[6]); //! identity can't be removed
if ($column != $val[0]) { if ($column != $val[0]) {
queries("EXEC sp_rename " . q(table($table) . ".$column") . ", " . q(idf_unescape($val[0])) . ", 'COLUMN'"); queries("EXEC sp_rename " . q(table($table) . ".$column") . ", " . q(idf_unescape($val[0])) . ", 'COLUMN'");
} }
$alter["ALTER COLUMN " . implode("", $val)][] = ""; $alter["ALTER COLUMN " . implode("", $val)][] = "";
$orig_field = $orig_fields[$field[0]];
if (default_value($orig_field) != $default) {
if ($orig_field["default"] !== null) {
$alter["DROP"][] = " " . idf_escape($orig_field["default_constraint"]);
}
if ($default) {
$alter["ADD"][] = "\n $default FOR $column";
}
}
} }
} }
} }
@@ -496,23 +488,14 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
$alter[""] = $foreign; $alter[""] = $foreign;
} }
foreach ($alter as $key => $val) { foreach ($alter as $key => $val) {
if (!queries("ALTER TABLE " . table($name) . " $key" . implode(",", $val))) { if (!queries("ALTER TABLE " . idf_escape($name) . " $key" . implode(",", $val))) {
return false; return false;
} }
} }
foreach ($comments as $key => $val) { foreach ($comments as $key => $val) {
$comment = substr($val, 9); // 9 - strlen(" COMMENT ") $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_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 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));
@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; return true;
} }
@@ -527,12 +510,10 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
} else { } else {
$index[] = idf_escape($val[1]) . " ON " . table($table); $index[] = idf_escape($val[1]) . " ON " . table($table);
} }
} elseif ( } elseif (!queries(($val[0] != "PRIMARY"
!queries(($val[0] != "PRIMARY"
? "CREATE $val[0] " . ($val[0] != "INDEX" ? "INDEX " : "") . idf_escape($val[1] != "" ? $val[1] : uniqid($table . "_")) . " ON " . table($table) ? "CREATE $val[0] " . ($val[0] != "INDEX" ? "INDEX " : "") . idf_escape($val[1] != "" ? $val[1] : uniqid($table . "_")) . " ON " . table($table)
: "ALTER TABLE " . table($table) . " ADD PRIMARY KEY" : "ALTER TABLE " . table($table) . " ADD PRIMARY KEY"
) . " (" . implode(", ", $val[2]) . ")") ) . " (" . implode(", ", $val[2]) . ")")) {
) {
return false; return false;
} }
} }
@@ -541,19 +522,27 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
; ;
} }
function last_id() {
global $connection;
return $connection->result("SELECT SCOPE_IDENTITY()"); // @@IDENTITY can return trigger INSERT
}
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) { function found_rows($table_status, $where) {
} }
function foreign_keys($table) { function foreign_keys($table) {
$return = array(); $return = array();
$on_actions = array("CASCADE", "NO ACTION", "SET NULL", "SET DEFAULT"); foreach (get_rows("EXEC sp_fkeys @fktable_name = " . q($table)) as $row) {
foreach (get_rows("EXEC sp_fkeys @fktable_name = " . q($table) . ", @fktable_owner = " . q(get_schema())) as $row) {
$foreign_key = &$return[$row["FK_NAME"]]; $foreign_key = &$return[$row["FK_NAME"]];
$foreign_key["db"] = $row["PKTABLE_QUALIFIER"]; $foreign_key["db"] = $row["PKTABLE_QUALIFIER"];
$foreign_key["ns"] = $row["PKTABLE_OWNER"];
$foreign_key["table"] = $row["PKTABLE_NAME"]; $foreign_key["table"] = $row["PKTABLE_NAME"];
$foreign_key["on_update"] = $on_actions[$row["UPDATE_RULE"]];
$foreign_key["on_delete"] = $on_actions[$row["DELETE_RULE"]];
$foreign_key["source"][] = $row["FKCOLUMN_NAME"]; $foreign_key["source"][] = $row["FKCOLUMN_NAME"];
$foreign_key["target"][] = $row["PKCOLUMN_NAME"]; $foreign_key["target"][] = $row["PKCOLUMN_NAME"];
} }
@@ -565,23 +554,22 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
} }
function drop_views($views) { function drop_views($views) {
return queries("DROP VIEW " . implode(", ", array_map('Adminer\table', $views))); return queries("DROP VIEW " . implode(", ", array_map('table', $views)));
} }
function drop_tables($tables) { function drop_tables($tables) {
return queries("DROP TABLE " . implode(", ", array_map('Adminer\table', $tables))); return queries("DROP TABLE " . implode(", ", array_map('table', $tables)));
} }
function move_tables($tables, $views, $target) { function move_tables($tables, $views, $target) {
return apply_queries("ALTER SCHEMA " . idf_escape($target) . " TRANSFER", array_merge($tables, $views)); return apply_queries("ALTER SCHEMA " . idf_escape($target) . " TRANSFER", array_merge($tables, $views));
} }
function trigger($name, $table) { function trigger($name) {
if ($name == "") { if ($name == "") {
return array(); return array();
} }
$rows = get_rows( $rows = get_rows("SELECT s.name [Trigger],
"SELECT s.name [Trigger],
CASE WHEN OBJECTPROPERTY(s.id, 'ExecIsInsertTrigger') = 1 THEN 'INSERT' WHEN OBJECTPROPERTY(s.id, 'ExecIsUpdateTrigger') = 1 THEN 'UPDATE' WHEN OBJECTPROPERTY(s.id, 'ExecIsDeleteTrigger') = 1 THEN 'DELETE' END [Event], CASE WHEN OBJECTPROPERTY(s.id, 'ExecIsInsertTrigger') = 1 THEN 'INSERT' WHEN OBJECTPROPERTY(s.id, 'ExecIsUpdateTrigger') = 1 THEN 'UPDATE' WHEN OBJECTPROPERTY(s.id, 'ExecIsDeleteTrigger') = 1 THEN 'DELETE' END [Event],
CASE WHEN OBJECTPROPERTY(s.id, 'ExecIsInsteadOfTrigger') = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END [Timing], CASE WHEN OBJECTPROPERTY(s.id, 'ExecIsInsteadOfTrigger') = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END [Timing],
c.text c.text
@@ -598,14 +586,13 @@ WHERE s.xtype = 'TR' AND s.name = " . q($name)
function triggers($table) { function triggers($table) {
$return = array(); $return = array();
foreach ( foreach (get_rows("SELECT sys1.name,
get_rows("SELECT sys1.name,
CASE WHEN OBJECTPROPERTY(sys1.id, 'ExecIsInsertTrigger') = 1 THEN 'INSERT' WHEN OBJECTPROPERTY(sys1.id, 'ExecIsUpdateTrigger') = 1 THEN 'UPDATE' WHEN OBJECTPROPERTY(sys1.id, 'ExecIsDeleteTrigger') = 1 THEN 'DELETE' END [Event], CASE WHEN OBJECTPROPERTY(sys1.id, 'ExecIsInsertTrigger') = 1 THEN 'INSERT' WHEN OBJECTPROPERTY(sys1.id, 'ExecIsUpdateTrigger') = 1 THEN 'UPDATE' WHEN OBJECTPROPERTY(sys1.id, 'ExecIsDeleteTrigger') = 1 THEN 'DELETE' END [Event],
CASE WHEN OBJECTPROPERTY(sys1.id, 'ExecIsInsteadOfTrigger') = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END [Timing] CASE WHEN OBJECTPROPERTY(sys1.id, 'ExecIsInsteadOfTrigger') = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END [Timing]
FROM sysobjects sys1 FROM sysobjects sys1
JOIN sysobjects sys2 ON sys1.parent_obj = sys2.id JOIN sysobjects sys2 ON sys1.parent_obj = sys2.id
WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)) as $row WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)
) { // triggers are not schema-scoped ) as $row) { // triggers are not schema-scoped
$return[$row["name"]] = array($row["Timing"], $row["Event"]); $return[$row["name"]] = array($row["Timing"], $row["Event"]);
} }
return $return; return $return;
@@ -624,69 +611,27 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)) as $row
} }
function get_schema() { function get_schema() {
global $connection;
if ($_GET["ns"] != "") { if ($_GET["ns"] != "") {
return $_GET["ns"]; return $_GET["ns"];
} }
return get_val("SELECT SCHEMA_NAME()"); return $connection->result("SELECT SCHEMA_NAME()");
} }
function set_schema($schema) { function set_schema($schema) {
$_GET["ns"] = $schema;
return true; // ALTER USER is permanent return true; // ALTER USER is permanent
} }
function create_sql($table, $auto_increment, $style) {
if (is_view(table_status1($table))) {
$view = view($table);
return "CREATE VIEW " . table($table) . " AS $view[select]";
}
$fields = array();
$primary = false;
foreach (fields($table) as $name => $field) {
$val = process_field($field, $field);
if ($val[6]) {
$primary = true;
}
$fields[] = implode("", $val);
}
foreach (indexes($table) as $name => $index) {
if (!$primary || $index["type"] != "PRIMARY") {
$columns = array();
foreach ($index["columns"] as $key => $val) {
$columns[] = idf_escape($val) . ($index["descs"][$key] ? " DESC" : "");
}
$name = idf_escape($name);
$fields[] = ($index["type"] == "INDEX" ? "INDEX $name" : "CONSTRAINT $name " . ($index["type"] == "UNIQUE" ? "UNIQUE" : "PRIMARY KEY")) . " (" . implode(", ", $columns) . ")";
}
}
foreach (driver()->checkConstraints($table) as $name => $check) {
$fields[] = "CONSTRAINT " . idf_escape($name) . " CHECK ($check)";
}
return "CREATE TABLE " . table($table) . " (\n\t" . implode(",\n\t", $fields) . "\n)";
}
function foreign_keys_sql($table) {
$fields = array();
foreach (foreign_keys($table) as $foreign) {
$fields[] = ltrim(format_foreign_key($foreign));
}
return ($fields ? "ALTER TABLE " . table($table) . " ADD\n\t" . implode(",\n\t", $fields) . ";\n\n" : "");
}
function truncate_sql($table) {
return "TRUNCATE TABLE " . table($table);
}
function use_sql($database) { function use_sql($database) {
return "USE " . idf_escape($database); return "USE " . idf_escape($database);
} }
function trigger_sql($table) { function show_variables() {
$return = ""; return array();
foreach (triggers($table) as $name => $trigger) {
$return .= create_trigger(" ON " . table($table), trigger($name, $table)) . ";";
} }
return $return;
function show_status() {
return array();
} }
function convert_field($field) { function convert_field($field) {
@@ -697,6 +642,38 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)) as $row
} }
function support($feature) { function support($feature) {
return preg_match('~^(check|comment|columns|database|drop_col|dump|indexes|descidx|scheme|sql|table|trigger|view|view_trigger)$~', $feature); //! routine| return preg_match('~^(comment|columns|database|drop_col|indexes|descidx|scheme|sql|table|trigger|view|view_trigger)$~', $feature); //! routine|
}
function driver_config() {
$types = array();
$structured_types = array();
foreach (array( //! use sys.types
lang('Numbers') => array("tinyint" => 3, "smallint" => 5, "int" => 10, "bigint" => 20, "bit" => 1, "decimal" => 0, "real" => 12, "float" => 53, "smallmoney" => 10, "money" => 20),
lang('Date and time') => array("date" => 10, "smalldatetime" => 19, "datetime" => 19, "datetime2" => 19, "time" => 8, "datetimeoffset" => 10),
lang('Strings') => array("char" => 8000, "varchar" => 8000, "text" => 2147483647, "nchar" => 4000, "nvarchar" => 4000, "ntext" => 1073741823),
lang('Binary') => array("binary" => 8000, "varbinary" => 8000, "image" => 2147483647),
) as $key => $val) {
$types += $val;
$structured_types[$key] = array_keys($val);
}
return array(
'possible_drivers' => array("SQLSRV", "MSSQL", "PDO_DBLIB"),
'jush' => "mssql",
'types' => $types,
'structured_types' => $structured_types,
'unsigned' => array(),
'operators' => array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"),
'functions' => array("len", "lower", "round", "upper"),
'grouping' => array("avg", "count", "count distinct", "max", "min", "sum"),
'edit_functions' => array(
array(
"date|time" => "getdate",
), array(
"int|decimal|real|float|money|datetime" => "+/-",
"char|text" => "+",
)
),
);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,12 @@
<?php <?php
namespace Adminer; $drivers["oracle"] = "Oracle (beta)";
add_driver("oracle", "Oracle (beta)");
if (isset($_GET["oracle"])) { if (isset($_GET["oracle"])) {
define('Adminer\DRIVER', "oracle"); define("DRIVER", "oracle");
if (extension_loaded("oci8") && $_GET["ext"] != "pdo") { if (extension_loaded("oci8")) {
class Db extends SqlDb { class Min_DB {
public string $extension = "oci8"; var $extension = "oci8", $_link, $_result, $server_info, $affected_rows, $errno, $error;
public $_current_db; var $_current_db;
private $link;
function _error($errno, $error) { function _error($errno, $error) {
if (ini_bool("html_errors")) { if (ini_bool("html_errors")) {
@@ -19,30 +16,31 @@ if (isset($_GET["oracle"])) {
$this->error = $error; $this->error = $error;
} }
function attach(?string $server, string $username, string $password): string { function connect($server, $username, $password) {
$this->link = @oci_new_connect($username, $password, $server, "AL32UTF8"); $this->_link = @oci_new_connect($username, $password, $server, "AL32UTF8");
if ($this->link) { if ($this->_link) {
$this->server_info = oci_server_version($this->link); $this->server_info = oci_server_version($this->_link);
return ''; return true;
} }
$error = oci_error(); $error = oci_error();
return $error["message"]; $this->error = $error["message"];
return false;
} }
function quote(string $string): string { function quote($string) {
return "'" . str_replace("'", "''", $string) . "'"; return "'" . str_replace("'", "''", $string) . "'";
} }
function select_db(string $database) { function select_db($database) {
$this->_current_db = $database; $this->_current_db = $database;
return true; return true;
} }
function query(string $query, bool $unbuffered = false) { function query($query, $unbuffered = false) {
$result = oci_parse($this->link, $query); $result = oci_parse($this->_link, $query);
$this->error = ""; $this->error = "";
if (!$result) { if (!$result) {
$error = oci_error($this->link); $error = oci_error($this->_link);
$this->errno = $error["code"]; $this->errno = $error["code"];
$this->error = $error["message"]; $this->error = $error["message"];
return false; return false;
@@ -52,26 +50,45 @@ if (isset($_GET["oracle"])) {
restore_error_handler(); restore_error_handler();
if ($return) { if ($return) {
if (oci_num_fields($result)) { if (oci_num_fields($result)) {
return new Result($result); return new Min_Result($result);
} }
$this->affected_rows = oci_num_rows($result); $this->affected_rows = oci_num_rows($result);
oci_free_statement($result); oci_free_statement($result);
} }
return $return; return $return;
} }
function multi_query($query) {
return $this->_result = $this->query($query);
} }
class Result { function store_result() {
public $num_rows; return $this->_result;
private $result, $offset = 1; }
function next_result() {
return false;
}
function result($query, $field = 1) {
$result = $this->query($query);
if (!is_object($result) || !oci_fetch($result->_result)) {
return false;
}
return oci_result($result->_result, $field);
}
}
class Min_Result {
var $_result, $_offset = 1, $num_rows;
function __construct($result) { function __construct($result) {
$this->result = $result; $this->_result = $result;
} }
private function convert($row) { function _convert($row) {
foreach ((array) $row as $key => $val) { foreach ((array) $row as $key => $val) {
if (is_a($val, 'OCILob') || is_a($val, 'OCI-Lob')) { if (is_a($val, 'OCI-Lob')) {
$row[$key] = $val->load(); $row[$key] = $val->load();
} }
} }
@@ -79,37 +96,39 @@ if (isset($_GET["oracle"])) {
} }
function fetch_assoc() { function fetch_assoc() {
return $this->convert(oci_fetch_assoc($this->result)); return $this->_convert(oci_fetch_assoc($this->_result));
} }
function fetch_row() { function fetch_row() {
return $this->convert(oci_fetch_row($this->result)); return $this->_convert(oci_fetch_row($this->_result));
} }
function fetch_field(): \stdClass { function fetch_field() {
$column = $this->offset++; $column = $this->_offset++;
$return = new \stdClass; $return = new stdClass;
$return->name = oci_field_name($this->result, $column); $return->name = oci_field_name($this->_result, $column);
$return->type = oci_field_type($this->result, $column); //! map to MySQL numbers $return->orgname = $return->name;
$return->type = oci_field_type($this->_result, $column);
$return->charsetnr = (preg_match("~raw|blob|bfile~", $return->type) ? 63 : 0); // 63 - binary $return->charsetnr = (preg_match("~raw|blob|bfile~", $return->type) ? 63 : 0); // 63 - binary
return $return; return $return;
} }
function __destruct() { function __destruct() {
oci_free_statement($this->result); oci_free_statement($this->_result);
} }
} }
} elseif (extension_loaded("pdo_oci")) { } elseif (extension_loaded("pdo_oci")) {
class Db extends PdoDb { class Min_DB extends Min_PDO {
public string $extension = "PDO_OCI"; var $extension = "PDO_OCI";
public $_current_db; var $_current_db;
function attach(?string $server, string $username, string $password): string { function connect($server, $username, $password) {
return $this->dsn("oci:dbname=//$server;charset=AL32UTF8", $username, $password); $this->dsn("oci:dbname=//$server;charset=AL32UTF8", $username, $password);
return true;
} }
function select_db(string $database) { function select_db($database) {
$this->_current_db = $database; $this->_current_db = $database;
return true; return true;
} }
@@ -119,33 +138,7 @@ if (isset($_GET["oracle"])) {
class Driver extends SqlDriver { class Min_Driver extends Min_SQL {
static array $extensions = array("OCI8", "PDO_OCI");
static string $jush = "oracle";
public array $insertFunctions = array( //! no parentheses
"date" => "current_date",
"timestamp" => "current_timestamp",
);
public array $editFunctions = array(
"number|float|double" => "+/-",
"date|timestamp" => "+ interval/- interval",
"char|clob" => "||",
);
public array $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL");
public array $functions = array("length", "lower", "round", "upper");
public array $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
function __construct(Db $connection) {
parent::__construct($connection);
$this->types = array(
lang('Numbers') => array("number" => 38, "binary_float" => 12, "binary_double" => 21),
lang('Date and time') => array("date" => 10, "timestamp" => 29, "interval year" => 12, "interval day" => 28), //! year(), day() to second()
lang('Strings') => array("char" => 2000, "varchar2" => 4000, "nchar" => 2000, "nvarchar2" => 4000, "clob" => 4294967295, "nclob" => 4294967295),
lang('Binary') => array("raw" => 2000, "long raw" => 2147483648, "blob" => 4294967295, "bfile" => 4294967296),
);
}
//! support empty $set in insert() //! support empty $set in insert()
@@ -153,7 +146,8 @@ if (isset($_GET["oracle"])) {
return true; // automatic start return true; // automatic start
} }
function insertUpdate(string $table, array $rows, array $primary) { function insertUpdate($table, $rows, $primary) {
global $connection;
foreach ($rows as $set) { foreach ($rows as $set) {
$update = array(); $update = array();
$where = array(); $where = array();
@@ -163,22 +157,24 @@ if (isset($_GET["oracle"])) {
$where[] = "$key = $val"; $where[] = "$key = $val";
} }
} }
if ( if (!(($where && queries("UPDATE " . table($table) . " SET " . implode(", ", $update) . " WHERE " . implode(" AND ", $where)) && $connection->affected_rows)
!(($where && queries("UPDATE " . table($table) . " SET " . implode(", ", $update) . " WHERE " . implode(" AND ", $where)) && connection()->affected_rows) || queries("INSERT INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ") VALUES (" . implode(", ", $set) . ")")
|| queries("INSERT INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ") VALUES (" . implode(", ", $set) . ")")) )) {
) {
return false; return false;
} }
} }
return true; return true;
} }
function hasCStyleEscapes(): bool {
return true;
}
} }
/**
* @param string $hostPath
* @return bool
*/
function is_server_host_valid($hostPath) {
// EasyConnect host+path format: host[/[service_name][:server_type][/instance_name]]
return (bool)preg_match('~^[^/]+(/([^/:]+)?(:[^/:]+)?(/[^/:]+)?)?$~', $hostPath);
}
function idf_escape($idf) { function idf_escape($idf) {
return '"' . str_replace('"', '""', $idf) . '"'; return '"' . str_replace('"', '""', $idf) . '"';
@@ -188,19 +184,23 @@ if (isset($_GET["oracle"])) {
return idf_escape($idf); return idf_escape($idf);
} }
function get_databases($flush) { function connect() {
return get_vals( global $adminer;
"SELECT DISTINCT tablespace_name FROM ( $connection = new Min_DB;
SELECT tablespace_name FROM user_tablespaces $credentials = $adminer->credentials();
UNION SELECT tablespace_name FROM all_tables WHERE tablespace_name IS NOT NULL if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
) return $connection;
ORDER BY 1" }
); return $connection->error;
}
function get_databases() {
return get_vals("SELECT tablespace_name FROM user_tablespaces ORDER BY 1");
} }
function limit($query, $where, $limit, $offset = 0, $separator = " ") { function limit($query, $where, $limit, $offset = 0, $separator = " ") {
return ($offset ? " * FROM (SELECT t.*, rownum AS rnum FROM (SELECT $query$where) t WHERE rownum <= " . ($limit + $offset) . ") WHERE rnum > $offset" return ($offset ? " * FROM (SELECT t.*, rownum AS rnum FROM (SELECT $query$where) t WHERE rownum <= " . ($limit + $offset) . ") WHERE rnum > $offset"
: ($limit ? " * FROM (SELECT $query$where) WHERE rownum <= " . ($limit + $offset) : ($limit !== null ? " * FROM (SELECT $query$where) WHERE rownum <= " . ($limit + $offset)
: " $query$where" : " $query$where"
)); ));
} }
@@ -210,16 +210,23 @@ ORDER BY 1"
} }
function db_collation($db, $collations) { function db_collation($db, $collations) {
return get_val("SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET'"); //! respect $db global $connection;
return $connection->result("SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET'"); //! respect $db
}
function engines() {
return array();
} }
function logged_user() { function logged_user() {
return get_val("SELECT USER FROM DUAL"); global $connection;
return $connection->result("SELECT USER FROM DUAL");
} }
function get_current_db() { function get_current_db() {
$db = connection()->_current_db ?: DB; global $connection;
unset(connection()->_current_db); $db = $connection->_current_db ? $connection->_current_db : DB;
unset($connection->_current_db);
return $db; return $db;
} }
@@ -232,23 +239,23 @@ ORDER BY 1"
function views_table($columns) { function views_table($columns) {
$owner = where_owner(''); $owner = where_owner('');
return "(SELECT $columns FROM all_views WHERE " . ($owner ?: "rownum < 0") . ")"; return "(SELECT $columns FROM all_views WHERE " . ($owner ? $owner : "rownum < 0") . ")";
} }
function tables_list() { function tables_list() {
$view = views_table("view_name"); $view = views_table("view_name");
$owner = where_owner(" AND "); $owner = where_owner(" AND ");
return get_key_vals( return get_key_vals("SELECT table_name, 'table' FROM all_tables WHERE tablespace_name = " . q(DB) . "$owner
"SELECT table_name, 'table' FROM all_tables WHERE tablespace_name = " . q(DB) . "$owner
UNION SELECT view_name, 'view' FROM $view UNION SELECT view_name, 'view' FROM $view
ORDER BY 1" ORDER BY 1"
); //! views don't have schema ); //! views don't have schema
} }
function count_tables($databases) { function count_tables($databases) {
global $connection;
$return = array(); $return = array();
foreach ($databases as $db) { foreach ($databases as $db) {
$return[$db] = get_val("SELECT COUNT(*) FROM all_tables WHERE tablespace_name = " . q($db)); $return[$db] = $connection->result("SELECT COUNT(*) FROM all_tables WHERE tablespace_name = " . q($db));
} }
return $return; return $return;
} }
@@ -259,11 +266,13 @@ ORDER BY 1"
$db = get_current_db(); $db = get_current_db();
$view = views_table("view_name"); $view = views_table("view_name");
$owner = where_owner(" AND "); $owner = where_owner(" AND ");
foreach ( foreach (get_rows('SELECT table_name "Name", \'table\' "Engine", avg_row_len * num_rows "Data_length", num_rows "Rows" FROM all_tables WHERE tablespace_name = ' . q($db) . $owner . ($name != "" ? " AND table_name = $search" : "") . "
get_rows('SELECT table_name "Name", \'table\' "Engine", avg_row_len * num_rows "Data_length", num_rows "Rows" FROM all_tables WHERE tablespace_name = ' . q($db) . $owner . ($name != "" ? " AND table_name = $search" : "") . "
UNION SELECT view_name, 'view', 0, 0 FROM $view" . ($name != "" ? " WHERE view_name = $search" : "") . " UNION SELECT view_name, 'view', 0, 0 FROM $view" . ($name != "" ? " WHERE view_name = $search" : "") . "
ORDER BY 1") as $row ORDER BY 1"
) { ) as $row) {
if ($name != "") {
return $row;
}
$return[$row["Name"]] = $row; $return[$row["Name"]] = $row;
} }
return $return; return $return;
@@ -306,14 +315,12 @@ ORDER BY 1") as $row
function indexes($table, $connection2 = null) { function indexes($table, $connection2 = null) {
$return = array(); $return = array();
$owner = where_owner(" AND ", "aic.table_owner"); $owner = where_owner(" AND ", "aic.table_owner");
foreach ( foreach (get_rows("SELECT aic.*, ac.constraint_type, atc.data_default
get_rows("SELECT aic.*, ac.constraint_type, atc.data_default
FROM all_ind_columns aic FROM all_ind_columns aic
LEFT JOIN all_constraints ac ON aic.index_name = ac.constraint_name AND aic.table_name = ac.table_name AND aic.index_owner = ac.owner LEFT JOIN all_constraints ac ON aic.index_name = ac.constraint_name AND aic.table_name = ac.table_name AND aic.index_owner = ac.owner
LEFT JOIN all_tab_cols atc ON aic.column_name = atc.column_name AND aic.table_name = atc.table_name AND aic.index_owner = atc.owner LEFT JOIN all_tab_cols atc ON aic.column_name = atc.column_name AND aic.table_name = atc.table_name AND aic.index_owner = atc.owner
WHERE aic.table_name = " . q($table) . "$owner WHERE aic.table_name = " . q($table) . "$owner
ORDER BY ac.constraint_type, aic.column_position", $connection2) as $row ORDER BY ac.constraint_type, aic.column_position", $connection2) as $row) {
) {
$index_name = $row["INDEX_NAME"]; $index_name = $row["INDEX_NAME"];
$column_name = $row["DATA_DEFAULT"]; $column_name = $row["DATA_DEFAULT"];
$column_name = ($column_name ? trim($column_name, '"') : $row["COLUMN_NAME"]); // trim - possibly wrapped in quotes but never contains quotes inside $column_name = ($column_name ? trim($column_name, '"') : $row["COLUMN_NAME"]); // trim - possibly wrapped in quotes but never contains quotes inside
@@ -336,11 +343,12 @@ ORDER BY ac.constraint_type, aic.column_position", $connection2) as $row
} }
function information_schema($db) { function information_schema($db) {
return get_schema() == "INFORMATION_SCHEMA"; return false;
} }
function error() { function error() {
return h(connection()->error); //! highlight sqltext from offset global $connection;
return h($connection->error); //! highlight sqltext from offset
} }
function explain($connection, $query) { function explain($connection, $query) {
@@ -452,50 +460,34 @@ AND c_src.TABLE_NAME = " . q($table);
return apply_queries("DROP TABLE", $tables); return apply_queries("DROP TABLE", $tables);
} }
function last_id($result) { function last_id() {
return 0; //! return 0; //!
} }
function schemas() { function schemas() {
$return = get_vals("SELECT DISTINCT owner FROM dba_segments WHERE owner IN (SELECT username FROM dba_users WHERE default_tablespace NOT IN ('SYSTEM','SYSAUX')) ORDER BY 1"); $return = get_vals("SELECT DISTINCT owner FROM dba_segments WHERE owner IN (SELECT username FROM dba_users WHERE default_tablespace NOT IN ('SYSTEM','SYSAUX')) ORDER BY 1");
return ($return ?: get_vals("SELECT DISTINCT owner FROM all_tables WHERE tablespace_name = " . q(DB) . " ORDER BY 1")); return ($return ? $return : get_vals("SELECT DISTINCT owner FROM all_tables WHERE tablespace_name = " . q(DB) . " ORDER BY 1"));
} }
function get_schema() { function get_schema() {
return get_val("SELECT sys_context('USERENV', 'SESSION_USER') FROM dual"); global $connection;
return $connection->result("SELECT sys_context('USERENV', 'SESSION_USER') FROM dual");
} }
function set_schema($scheme, $connection2 = null) { function set_schema($scheme, $connection2 = null) {
global $connection;
if (!$connection2) { if (!$connection2) {
$connection2 = connection(); $connection2 = $connection;
} }
return $connection2->query("ALTER SESSION SET CURRENT_SCHEMA = " . idf_escape($scheme)); return $connection2->query("ALTER SESSION SET CURRENT_SCHEMA = " . idf_escape($scheme));
} }
function show_variables() { function show_variables() {
return get_rows('SELECT name, display_value FROM v$parameter'); return get_key_vals('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() { function process_list() {
return get_rows('SELECT 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"
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 FROM v$session sess LEFT OUTER JOIN v$sql sql
ON sql.sql_id = sess.sql_id ON sql.sql_id = sess.sql_id
WHERE sess.type = \'USER\' WHERE sess.type = \'USER\'
@@ -503,6 +495,11 @@ ORDER BY PROCESS
'); ');
} }
function show_status() {
$rows = get_rows('SELECT * FROM v$instance');
return reset($rows);
}
function convert_field($field) { function convert_field($field) {
} }
@@ -513,4 +510,38 @@ ORDER BY PROCESS
function support($feature) { function support($feature) {
return preg_match('~^(columns|database|drop_col|indexes|descidx|processlist|scheme|sql|status|table|variables|view)$~', $feature); //! return preg_match('~^(columns|database|drop_col|indexes|descidx|processlist|scheme|sql|status|table|variables|view)$~', $feature); //!
} }
function driver_config() {
$types = array();
$structured_types = array();
foreach (array(
lang('Numbers') => array("number" => 38, "binary_float" => 12, "binary_double" => 21),
lang('Date and time') => array("date" => 10, "timestamp" => 29, "interval year" => 12, "interval day" => 28), //! year(), day() to second()
lang('Strings') => array("char" => 2000, "varchar2" => 4000, "nchar" => 2000, "nvarchar2" => 4000, "clob" => 4294967295, "nclob" => 4294967295),
lang('Binary') => array("raw" => 2000, "long raw" => 2147483648, "blob" => 4294967295, "bfile" => 4294967296),
) as $key => $val) {
$types += $val;
$structured_types[$key] = array_keys($val);
}
return array(
'possible_drivers' => array("OCI8", "PDO_OCI"),
'jush' => "oracle",
'types' => $types,
'structured_types' => $structured_types,
'unsigned' => array(),
'operators' => array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL"),
'functions' => array("length", "lower", "round", "upper"),
'grouping' => array("avg", "count", "count distinct", "max", "min", "sum"),
'edit_functions' => array(
array( //! no parentheses
"date" => "current_date",
"timestamp" => "current_timestamp",
), array(
"number|float|double" => "+/-",
"date|timestamp" => "+ interval/- interval",
"char|clob" => "||",
)
),
);
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,103 +1,206 @@
<?php <?php
namespace Adminer; $drivers["sqlite"] = "SQLite 3";
$drivers["sqlite2"] = "SQLite 2";
add_driver("sqlite", "SQLite"); if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
define("DRIVER", (isset($_GET["sqlite"]) ? "sqlite" : "sqlite2"));
if (class_exists(isset($_GET["sqlite"]) ? "SQLite3" : "SQLiteDatabase")) {
if (isset($_GET["sqlite"])) {
if (isset($_GET["sqlite"])) { class Min_SQLite {
define('Adminer\DRIVER', "sqlite"); var $extension = "SQLite3", $server_info, $affected_rows, $errno, $error, $_link;
if (class_exists("SQLite3") && $_GET["ext"] != "pdo") {
abstract class SqliteDb extends SqlDb { function __construct($filename) {
public string $extension = "SQLite3"; $this->_link = new SQLite3($filename);
private $link; $version = $this->_link->version();
function attach(?string $filename, string $username, string $password): string {
$this->link = new \SQLite3($filename);
$version = $this->link->version();
$this->server_info = $version["versionString"]; $this->server_info = $version["versionString"];
return '';
} }
function query(string $query, bool $unbuffered = false) { function query($query) {
$result = @$this->link->query($query); $result = @$this->_link->query($query);
$this->error = ""; $this->error = "";
if (!$result) { if (!$result) {
$this->errno = $this->link->lastErrorCode(); $this->errno = $this->_link->lastErrorCode();
$this->error = $this->link->lastErrorMsg(); $this->error = $this->_link->lastErrorMsg();
return false; return false;
} elseif ($result->numColumns()) { } elseif ($result->numColumns()) {
return new Result($result); return new Min_Result($result);
} }
$this->affected_rows = $this->link->changes(); $this->affected_rows = $this->_link->changes();
return true; return true;
} }
function quote(string $string): string { function quote($string) {
return (is_utf8($string) return (is_utf8($string)
? "'" . $this->link->escapeString($string) . "'" ? "'" . $this->_link->escapeString($string) . "'"
: "x'" . first(unpack('H*', $string)) . "'" : "x'" . reset(unpack('H*', $string)) . "'"
); );
} }
function store_result() {
return $this->_result;
} }
class Result { function result($query, $field = 0) {
public $num_rows; $result = $this->query($query);
private $result, $offset = 0; if (!is_object($result)) {
return false;
}
$row = $result->_result->fetchArray();
return $row[$field];
}
}
class Min_Result {
var $_result, $_offset = 0, $num_rows;
function __construct($result) { function __construct($result) {
$this->result = $result; $this->_result = $result;
} }
function fetch_assoc() { function fetch_assoc() {
return $this->result->fetchArray(SQLITE3_ASSOC); return $this->_result->fetchArray(SQLITE3_ASSOC);
} }
function fetch_row() { function fetch_row() {
return $this->result->fetchArray(SQLITE3_NUM); return $this->_result->fetchArray(SQLITE3_NUM);
} }
function fetch_field(): \stdClass { function fetch_field() {
$column = $this->offset++; $column = $this->_offset++;
$type = $this->result->columnType($column); $type = $this->_result->columnType($column);
return (object) array( return (object) array(
"name" => $this->result->columnName($column), "name" => $this->_result->columnName($column),
"type" => ($type == SQLITE3_TEXT ? 15 : 0), "type" => $type,
"charsetnr" => ($type == SQLITE3_BLOB ? 63 : 0), // 63 - binary "charsetnr" => ($type == SQLITE3_BLOB ? 63 : 0), // 63 - binary
); );
} }
function __destruct() { function __desctruct() {
$this->result->finalize(); return $this->_result->finalize();
} }
} }
} else {
class Min_SQLite {
var $extension = "SQLite", $server_info, $affected_rows, $error, $_link;
function __construct($filename) {
$this->server_info = sqlite_libversion();
$this->_link = new SQLiteDatabase($filename);
}
function query($query, $unbuffered = false) {
$method = ($unbuffered ? "unbufferedQuery" : "query");
$result = @$this->_link->$method($query, SQLITE_BOTH, $error);
$this->error = "";
if (!$result) {
$this->error = $error;
return false;
} elseif ($result === true) {
$this->affected_rows = $this->changes();
return true;
}
return new Min_Result($result);
}
function quote($string) {
return "'" . sqlite_escape_string($string) . "'";
}
function store_result() {
return $this->_result;
}
function result($query, $field = 0) {
$result = $this->query($query);
if (!is_object($result)) {
return false;
}
$row = $result->_result->fetch();
return $row[$field];
}
}
class Min_Result {
var $_result, $_offset = 0, $num_rows;
function __construct($result) {
$this->_result = $result;
if (method_exists($result, 'numRows')) { // not available in unbuffered query
$this->num_rows = $result->numRows();
}
}
function fetch_assoc() {
$row = $this->_result->fetch(SQLITE_ASSOC);
if (!$row) {
return false;
}
$return = array();
foreach ($row as $key => $val) {
$return[idf_unescape($key)] = $val;
}
return $return;
}
function fetch_row() {
return $this->_result->fetch(SQLITE_NUM);
}
function fetch_field() {
$name = $this->_result->fieldName($this->_offset++);
$pattern = '(\[.*]|"(?:[^"]|"")*"|(.+))';
if (preg_match("~^($pattern\\.)?$pattern\$~", $name, $match)) {
$table = ($match[3] != "" ? $match[3] : idf_unescape($match[2]));
$name = ($match[5] != "" ? $match[5] : idf_unescape($match[4]));
}
return (object) array(
"name" => $name,
"orgname" => $name,
"orgtable" => $table,
);
}
}
}
} elseif (extension_loaded("pdo_sqlite")) { } elseif (extension_loaded("pdo_sqlite")) {
abstract class SqliteDb extends PdoDb { class Min_SQLite extends Min_PDO {
public string $extension = "PDO_SQLite"; var $extension = "PDO_SQLite";
function attach(?string $filename, string $username, string $password): string { function __construct($filename) {
$this->dsn(DRIVER . ":$filename", "", ""); $this->dsn(DRIVER . ":$filename", "", "");
}
}
}
if (class_exists("Min_SQLite")) {
class Min_DB extends Min_SQLite {
function __construct() {
parent::__construct(":memory:");
$this->query("PRAGMA foreign_keys = 1");
}
function select_db($filename) {
if (is_readable($filename) && $this->query("ATTACH " . $this->quote(preg_match("~(^[/\\\\]|:)~", $filename) ? $filename : dirname($_SERVER["SCRIPT_FILENAME"]) . "/$filename") . " AS a")) { // is_readable - SQLite 3
parent::__construct($filename);
$this->query("PRAGMA foreign_keys = 1"); $this->query("PRAGMA foreign_keys = 1");
$this->query("PRAGMA busy_timeout = 500"); $this->query("PRAGMA busy_timeout = 500");
return ''; return true;
} }
return false;
} }
function multi_query($query) {
return $this->_result = $this->query($query);
} }
if (class_exists('Adminer\SqliteDb')) { function next_result() {
class Db extends SqliteDb {
function attach(?string $filename, string $username, string $password): string {
parent::attach($filename, $username, $password);
$this->query("PRAGMA foreign_keys = 1");
$this->query("PRAGMA busy_timeout = 500");
return '';
}
function select_db(string $filename): bool {
if (is_readable($filename) && $this->query("ATTACH " . $this->quote(preg_match("~(^[/\\\\]|:)~", $filename) ? $filename : dirname($_SERVER["SCRIPT_FILENAME"]) . "/$filename") . " AS a")) {
return !self::attach($filename, '', '');
}
return false; return false;
} }
} }
@@ -105,42 +208,9 @@ if (isset($_GET["sqlite"])) {
class Driver extends SqlDriver { class Min_Driver extends Min_SQL {
static array $extensions = array("SQLite3", "PDO_SQLite");
static string $jush = "sqlite";
protected array $types = array(array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0)); function insertUpdate($table, $rows, $primary) {
public array $insertFunctions = array(); // "text" => "date('now')/time('now')/datetime('now')",
public array $editFunctions = array(
"integer|real|numeric" => "+/-",
// "text" => "date/time/datetime",
"text" => "||",
);
public array $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"); // REGEXP can be user defined function
public array $functions = array("hex", "length", "lower", "round", "unixepoch", "upper");
public array $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
static function connect(?string $server, string $username, string $password) {
if ($password != "") {
return lang('Database does not support password.');
}
return parent::connect(":memory:", "", "");
}
function __construct(Db $connection) {
parent::__construct($connection);
if (min_version(3.31, 0, $connection)) {
$this->generated = array("STORED", "VIRTUAL");
}
}
function structuredTypes(): array {
return array_keys($this->types[0]);
}
function insertUpdate(string $table, array $rows, array $primary) {
$values = array(); $values = array();
foreach ($rows as $set) { foreach ($rows as $set) {
$values[] = "(" . implode(", ", $set) . ")"; $values[] = "(" . implode(", ", $set) . ")";
@@ -148,7 +218,7 @@ if (isset($_GET["sqlite"])) {
return queries("REPLACE INTO " . table($table) . " (" . implode(", ", array_keys(reset($rows))) . ") VALUES\n" . implode(",\n", $values)); return queries("REPLACE INTO " . table($table) . " (" . implode(", ", array_keys(reset($rows))) . ") VALUES\n" . implode(",\n", $values));
} }
function tableHelp(string $name, bool $is_view = false) { function tableHelp($name) {
if ($name == "sqlite_sequence") { if ($name == "sqlite_sequence") {
return "fileformat2.html#seqtab"; return "fileformat2.html#seqtab";
} }
@@ -157,20 +227,6 @@ if (isset($_GET["sqlite"])) {
} }
} }
function checkConstraints(string $table): array {
preg_match_all('~ CHECK *(\( *(((?>[^()]*[^() ])|(?1))*) *\))~', get_val("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table), 0, $this->conn), $matches); //! could be inside a comment
return array_combine($matches[2], $matches[2]);
}
function allFields(): array {
$return = array();
foreach (tables_list() as $table => $type) {
foreach (fields($table) as $field) {
$return[$table][] = $field;
}
}
return $return;
}
} }
@@ -183,23 +239,38 @@ if (isset($_GET["sqlite"])) {
return idf_escape($idf); return idf_escape($idf);
} }
function get_databases($flush) { function connect() {
global $adminer;
list(, , $password) = $adminer->credentials();
if ($password != "") {
return lang('Database does not support password.');
}
return new Min_DB;
}
function get_databases() {
return array(); return array();
} }
function limit($query, $where, $limit, $offset = 0, $separator = " ") { function limit($query, $where, $limit, $offset = 0, $separator = " ") {
return " $query$where" . ($limit ? $separator . "LIMIT $limit" . ($offset ? " OFFSET $offset" : "") : ""); return " $query$where" . ($limit !== null ? $separator . "LIMIT $limit" . ($offset ? " OFFSET $offset" : "") : "");
} }
function limit1($table, $query, $where, $separator = "\n") { function limit1($table, $query, $where, $separator = "\n") {
return (preg_match('~^INTO~', $query) || get_val("SELECT sqlite_compileoption_used('ENABLE_UPDATE_DELETE_LIMIT')") global $connection;
return (preg_match('~^INTO~', $query) || $connection->result("SELECT sqlite_compileoption_used('ENABLE_UPDATE_DELETE_LIMIT')")
? limit($query, $where, 1, 0, $separator) ? limit($query, $where, 1, 0, $separator)
: " $query WHERE rowid = (SELECT rowid FROM " . table($table) . $where . $separator . "LIMIT 1)" //! use primary key in tables with WITHOUT rowid : " $query WHERE rowid = (SELECT rowid FROM " . table($table) . $where . $separator . "LIMIT 1)" //! use primary key in tables with WITHOUT rowid
); );
} }
function db_collation($db, $collations) { function db_collation($db, $collations) {
return get_val("PRAGMA encoding"); // there is no database list so $db == DB global $connection;
return $connection->result("PRAGMA encoding"); // there is no database list so $db == DB
}
function engines() {
return array();
} }
function logged_user() { function logged_user() {
@@ -215,15 +286,16 @@ if (isset($_GET["sqlite"])) {
} }
function table_status($name = "") { function table_status($name = "") {
global $connection;
$return = array(); $return = array();
foreach (get_rows("SELECT name AS Name, type AS Engine, 'rowid' AS Oid, '' AS Auto_increment FROM sqlite_master WHERE type IN ('table', 'view') " . ($name != "" ? "AND name = " . q($name) : "ORDER BY name")) as $row) { foreach (get_rows("SELECT name AS Name, type AS Engine, 'rowid' AS Oid, '' AS Auto_increment FROM sqlite_master WHERE type IN ('table', 'view') " . ($name != "" ? "AND name = " . q($name) : "ORDER BY name")) as $row) {
$row["Rows"] = get_val("SELECT COUNT(*) FROM " . idf_escape($row["Name"])); $row["Rows"] = $connection->result("SELECT COUNT(*) FROM " . idf_escape($row["Name"]));
$return[$row["Name"]] = $row; $return[$row["Name"]] = $row;
} }
foreach (get_rows("SELECT * FROM sqlite_sequence" . ($name != "" ? " WHERE name = " . q($name) : ""), null, "") as $row) { foreach (get_rows("SELECT * FROM sqlite_sequence", null, "") as $row) {
$return[$row["name"]]["Auto_increment"] = $row["seq"]; $return[$row["name"]]["Auto_increment"] = $row["seq"];
} }
return $return; return ($name != "" ? $return[$name] : $return);
} }
function is_view($table_status) { function is_view($table_status) {
@@ -231,13 +303,15 @@ if (isset($_GET["sqlite"])) {
} }
function fk_support($table_status) { function fk_support($table_status) {
return !get_val("SELECT sqlite_compileoption_used('OMIT_FOREIGN_KEY')"); global $connection;
return !$connection->result("SELECT sqlite_compileoption_used('OMIT_FOREIGN_KEY')");
} }
function fields($table) { function fields($table) {
global $connection;
$return = array(); $return = array();
$primary = ""; $primary = "";
foreach (get_rows("PRAGMA table_" . (min_version(3.31) ? "x" : "") . "info(" . table($table) . ")") as $row) { foreach (get_rows("PRAGMA table_info(" . table($table) . ")") as $row) {
$name = $row["name"]; $name = $row["name"];
$type = strtolower($row["type"]); $type = strtolower($row["type"]);
$default = $row["dflt_value"]; $default = $row["dflt_value"];
@@ -245,7 +319,7 @@ if (isset($_GET["sqlite"])) {
"field" => $name, "field" => $name,
"type" => (preg_match('~int~i', $type) ? "integer" : (preg_match('~char|clob|text~i', $type) ? "text" : (preg_match('~blob~i', $type) ? "blob" : (preg_match('~real|floa|doub~i', $type) ? "real" : "numeric")))), "type" => (preg_match('~int~i', $type) ? "integer" : (preg_match('~char|clob|text~i', $type) ? "text" : (preg_match('~blob~i', $type) ? "blob" : (preg_match('~real|floa|doub~i', $type) ? "real" : "numeric")))),
"full_type" => $type, "full_type" => $type,
"default" => (preg_match("~^'(.*)'$~", $default, $match) ? str_replace("''", "'", $match[1]) : ($default == "NULL" ? null : $default)), "default" => (preg_match("~'(.*)'~", $default, $match) ? str_replace("''", "'", $match[1]) : ($default == "NULL" ? null : $default)),
"null" => !$row["notnull"], "null" => !$row["notnull"],
"privileges" => array("select" => 1, "insert" => 1, "update" => 1, "where" => 1, "order" => 1), "privileges" => array("select" => 1, "insert" => 1, "update" => 1, "where" => 1, "order" => 1),
"primary" => $row["pk"], "primary" => $row["pk"],
@@ -259,28 +333,24 @@ if (isset($_GET["sqlite"])) {
$primary = $name; $primary = $name;
} }
} }
$sql = get_val("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table)); $sql = $connection->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table));
$idf = '(("[^"]*+")+|[a-z0-9_]+)'; preg_match_all('~(("[^"]*+")+|[a-z0-9_]+)\s+text\s+COLLATE\s+(\'[^\']+\'|\S+)~i', $sql, $matches, PREG_SET_ORDER);
preg_match_all('~' . $idf . '\s+text\s+COLLATE\s+(\'[^\']+\'|\S+)~i', $sql, $matches, PREG_SET_ORDER);
foreach ($matches as $match) { foreach ($matches as $match) {
$name = str_replace('""', '"', preg_replace('~^"|"$~', '', $match[1])); $name = str_replace('""', '"', preg_replace('~^"|"$~', '', $match[1]));
if ($return[$name]) { if ($return[$name]) {
$return[$name]["collation"] = trim($match[3], "'"); $return[$name]["collation"] = trim($match[3], "'");
} }
} }
preg_match_all('~' . $idf . '\s.*GENERATED ALWAYS AS \((.+)\) (STORED|VIRTUAL)~i', $sql, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$name = str_replace('""', '"', preg_replace('~^"|"$~', '', $match[1]));
$return[$name]["default"] = $match[3];
$return[$name]["generated"] = strtoupper($match[4]);
}
return $return; return $return;
} }
function indexes($table, $connection2 = null) { function indexes($table, $connection2 = null) {
$connection2 = connection($connection2); global $connection;
if (!is_object($connection2)) {
$connection2 = $connection;
}
$return = array(); $return = array();
$sql = get_val("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table), 0, $connection2); $sql = $connection2->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table));
if (preg_match('~\bPRIMARY\s+KEY\s*\((([^)"]+|"[^"]*"|`[^`]*`)++)~i', $sql, $match)) { if (preg_match('~\bPRIMARY\s+KEY\s*\((([^)"]+|"[^"]*"|`[^`]*`)++)~i', $sql, $match)) {
$return[""] = array("type" => "PRIMARY", "columns" => array(), "lengths" => array(), "descs" => array()); $return[""] = array("type" => "PRIMARY", "columns" => array(), "lengths" => array(), "descs" => array());
preg_match_all('~((("[^"]*+")+|(?:`[^`]*+`)+)|(\S+))(\s+(ASC|DESC))?(,\s*|$)~i', $match[1], $matches, PREG_SET_ORDER); preg_match_all('~((("[^"]*+")+|(?:`[^`]*+`)+)|(\S+))(\s+(ASC|DESC))?(,\s*|$)~i', $match[1], $matches, PREG_SET_ORDER);
@@ -325,6 +395,7 @@ if (isset($_GET["sqlite"])) {
$return = array(); $return = array();
foreach (get_rows("PRAGMA foreign_key_list(" . table($table) . ")") as $row) { foreach (get_rows("PRAGMA foreign_key_list(" . table($table) . ")") as $row) {
$foreign_key = &$return[$row["id"]]; $foreign_key = &$return[$row["id"]];
//! idf_unescape in SQLite2
if (!$foreign_key) { if (!$foreign_key) {
$foreign_key = $row; $foreign_key = $row;
} }
@@ -335,7 +406,8 @@ if (isset($_GET["sqlite"])) {
} }
function view($name) { function view($name) {
return array("select" => preg_replace('~^(?:[^`"[]+|`[^`]*`|"[^"]*")* AS\s+~iU', '', get_val("SELECT sql FROM sqlite_master WHERE type = 'view' AND name = " . q($name)))); //! identifiers may be inside [] global $connection;
return array("select" => preg_replace('~^(?:[^`"[]+|`[^`]*`|"[^"]*")* AS\s+~iU', '', $connection->result("SELECT sql FROM sqlite_master WHERE name = " . q($name)))); //! identifiers may be inside []
} }
function collations() { function collations() {
@@ -347,32 +419,34 @@ if (isset($_GET["sqlite"])) {
} }
function error() { function error() {
return h(connection()->error); global $connection;
return h($connection->error);
} }
function check_sqlite_name($name) { function check_sqlite_name($name) {
// avoid creating PHP files on unsecured servers // avoid creating PHP files on unsecured servers
global $connection;
$extensions = "db|sdb|sqlite"; $extensions = "db|sdb|sqlite";
if (!preg_match("~^[^\\0]*\\.($extensions)\$~", $name)) { if (!preg_match("~^[^\\0]*\\.($extensions)\$~", $name)) {
connection()->error = lang('Please use one of the extensions %s.', str_replace("|", ", ", $extensions)); $connection->error = lang('Please use one of the extensions %s.', str_replace("|", ", ", $extensions));
return false; return false;
} }
return true; return true;
} }
function create_database($db, $collation) { function create_database($db, $collation) {
global $connection;
if (file_exists($db)) { if (file_exists($db)) {
connection()->error = lang('File exists.'); $connection->error = lang('File exists.');
return false; return false;
} }
if (!check_sqlite_name($db)) { if (!check_sqlite_name($db)) {
return false; return false;
} }
try { try {
$link = new Db(); $link = new Min_SQLite($db);
$link->attach($db, '', ''); } catch (Exception $ex) {
} catch (\Exception $ex) { $connection->error = $ex->getMessage();
connection()->error = $ex->getMessage();
return false; return false;
} }
$link->query('PRAGMA encoding = "UTF-8"'); $link->query('PRAGMA encoding = "UTF-8"');
@@ -382,10 +456,11 @@ if (isset($_GET["sqlite"])) {
} }
function drop_databases($databases) { function drop_databases($databases) {
connection()->attach(":memory:", '', ''); // to unlock file, doesn't work in PDO on Windows global $connection;
$connection->__construct(":memory:"); // to unlock file, doesn't work in PDO on Windows
foreach ($databases as $db) { foreach ($databases as $db) {
if (!@unlink($db)) { if (!@unlink($db)) {
connection()->error = lang('File exists.'); $connection->error = lang('File exists.');
return false; return false;
} }
} }
@@ -393,19 +468,21 @@ if (isset($_GET["sqlite"])) {
} }
function rename_database($name, $collation) { function rename_database($name, $collation) {
global $connection;
if (!check_sqlite_name($name)) { if (!check_sqlite_name($name)) {
return false; return false;
} }
connection()->attach(":memory:", '', ''); $connection->__construct(":memory:");
connection()->error = lang('File exists.'); $connection->error = lang('File exists.');
return @rename(DB, $name); return @rename(DB, $name);
} }
function auto_increment() { function auto_increment() {
return " PRIMARY KEY AUTOINCREMENT"; return " PRIMARY KEY" . (DRIVER == "sqlite" ? " AUTOINCREMENT" : "");
} }
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) { function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
global $connection;
$use_all_fields = ($table == "" || $foreign); $use_all_fields = ($table == "" || $foreign);
foreach ($fields as $field) { foreach ($fields as $field) {
if ($field[0] != "" || !$field[1] || $field[2]) { if ($field[0] != "" || !$field[1] || $field[2]) {
@@ -438,7 +515,7 @@ if (isset($_GET["sqlite"])) {
if ($auto_increment) { if ($auto_increment) {
queries("BEGIN"); queries("BEGIN");
queries("UPDATE sqlite_sequence SET seq = $auto_increment WHERE name = " . q($name)); // ignores error queries("UPDATE sqlite_sequence SET seq = $auto_increment WHERE name = " . q($name)); // ignores error
if (!connection()->affected_rows) { if (!$connection->affected_rows) {
queries("INSERT INTO sqlite_sequence (name, seq) VALUES (" . q($name) . ", $auto_increment)"); queries("INSERT INTO sqlite_sequence (name, seq) VALUES (" . q($name) . ", $auto_increment)");
} }
queries("COMMIT"); queries("COMMIT");
@@ -446,18 +523,8 @@ if (isset($_GET["sqlite"])) {
return true; return true;
} }
/** Recreate table function recreate_table($table, $name, $fields, $originals, $foreign, $auto_increment, $indexes = array()) {
* @param string $table original name global $connection;
* @param string $name new name
* @param list<list<string>> $fields [process_field()], empty to preserve
* @param string[] $originals [$original => idf_escape($new_column)], empty to preserve
* @param string[] $foreign [format_foreign_key()], empty to preserve
* @param numeric-string $auto_increment set auto_increment to this value, "" to preserve
* @param list<array{string, string, list<string>|'DROP'}> $indexes [[$type, $name, $columns]], empty to preserve
* @param string $drop_check CHECK constraint to drop
* @param string $add_check CHECK constraint to add
*/
function recreate_table(string $table, string $name, array $fields, array $originals, array $foreign, string $auto_increment = "", $indexes = array(), string $drop_check = "", string $add_check = ""): bool {
if ($table != "") { if ($table != "") {
if (!$fields) { if (!$fields) {
foreach (fields($table) as $key => $field) { foreach (fields($table) as $key => $field) {
@@ -514,39 +581,26 @@ if (isset($_GET["sqlite"])) {
} }
queries("BEGIN"); queries("BEGIN");
} }
$changes = array(); foreach ($fields as $key => $field) {
foreach ($fields as $field) { $fields[$key] = " " . implode($field);
if (preg_match('~GENERATED~', $field[3])) {
unset($originals[array_search($field[0], $originals)]);
}
$changes[] = " " . implode($field);
}
$changes = array_merge($changes, array_filter($foreign));
foreach (driver()->checkConstraints($table) as $check) {
if ($check != $drop_check) {
$changes[] = " CHECK ($check)";
}
}
if ($add_check) {
$changes[] = " CHECK ($add_check)";
} }
$fields = array_merge($fields, array_filter($foreign));
$temp_name = ($table == $name ? "adminer_$name" : $name); $temp_name = ($table == $name ? "adminer_$name" : $name);
if (!queries("CREATE TABLE " . table($temp_name) . " (\n" . implode(",\n", $changes) . "\n)")) { if (!queries("CREATE TABLE " . table($temp_name) . " (\n" . implode(",\n", $fields) . "\n)")) {
// implicit ROLLBACK to not overwrite connection()->error // implicit ROLLBACK to not overwrite $connection->error
return false; return false;
} }
if ($table != "") { if ($table != "") {
if ($originals && !queries("INSERT INTO " . table($temp_name) . " (" . implode(", ", $originals) . ") SELECT " . implode(", ", array_map('Adminer\idf_escape', array_keys($originals))) . " FROM " . table($table))) { if ($originals && !queries("INSERT INTO " . table($temp_name) . " (" . implode(", ", $originals) . ") SELECT " . implode(", ", array_map('idf_escape', array_keys($originals))) . " FROM " . table($table))) {
return false; return false;
} }
$triggers = array(); $triggers = array();
foreach (triggers($table) as $trigger_name => $timing_event) { foreach (triggers($table) as $trigger_name => $timing_event) {
$trigger = trigger($trigger_name, $table); $trigger = trigger($trigger_name);
$triggers[] = "CREATE TRIGGER " . idf_escape($trigger_name) . " " . implode(" ", $timing_event) . " ON " . table($name) . "\n$trigger[Statement]"; $triggers[] = "CREATE TRIGGER " . idf_escape($trigger_name) . " " . implode(" ", $timing_event) . " ON " . table($name) . "\n$trigger[Statement]";
} }
$auto_increment = $auto_increment ? "" : get_val("SELECT seq FROM sqlite_sequence WHERE name = " . q($table)); // if $auto_increment is set then it will be updated later $auto_increment = $auto_increment ? 0 : $connection->result("SELECT seq FROM sqlite_sequence WHERE name = " . q($table)); // if $auto_increment is set then it will be updated later
if ( if (!queries("DROP TABLE " . table($table)) // drop before creating indexes and triggers to allow using old names
!queries("DROP TABLE " . table($table)) // drop before creating indexes and triggers to allow using old names
|| ($table == $name && !queries("ALTER TABLE " . table($temp_name) . " RENAME TO " . table($name))) || ($table == $name && !queries("ALTER TABLE " . table($temp_name) . " RENAME TO " . table($name)))
|| !alter_indexes($name, $indexes) || !alter_indexes($name, $indexes)
) { ) {
@@ -576,15 +630,14 @@ if (isset($_GET["sqlite"])) {
function alter_indexes($table, $alter) { function alter_indexes($table, $alter) {
foreach ($alter as $primary) { foreach ($alter as $primary) {
if ($primary[0] == "PRIMARY") { if ($primary[0] == "PRIMARY") {
return recreate_table($table, $table, array(), array(), array(), "", $alter); return recreate_table($table, $table, array(), array(), array(), 0, $alter);
} }
} }
foreach (array_reverse($alter) as $val) { foreach (array_reverse($alter) as $val) {
if ( if (!queries($val[2] == "DROP"
!queries($val[2] == "DROP"
? "DROP INDEX " . idf_escape($val[1]) ? "DROP INDEX " . idf_escape($val[1])
: index_sql($table, $val[0], $val[1], "(" . implode(", ", $val[2]) . ")")) : index_sql($table, $val[0], $val[1], "(" . implode(", ", $val[2]) . ")")
) { )) {
return false; return false;
} }
} }
@@ -607,7 +660,8 @@ if (isset($_GET["sqlite"])) {
return false; return false;
} }
function trigger($name, $table) { function trigger($name) {
global $connection;
if ($name == "") { if ($name == "") {
return array("Statement" => "BEGIN\n\t;\nEND"); return array("Statement" => "BEGIN\n\t;\nEND");
} }
@@ -615,7 +669,7 @@ if (isset($_GET["sqlite"])) {
$trigger_options = trigger_options(); $trigger_options = trigger_options();
preg_match( preg_match(
"~^CREATE\\s+TRIGGER\\s*$idf\\s*(" . implode("|", $trigger_options["Timing"]) . ")\\s+([a-z]+)(?:\\s+OF\\s+($idf))?\\s+ON\\s*$idf\\s*(?:FOR\\s+EACH\\s+ROW\\s)?(.*)~is", "~^CREATE\\s+TRIGGER\\s*$idf\\s*(" . implode("|", $trigger_options["Timing"]) . ")\\s+([a-z]+)(?:\\s+OF\\s+($idf))?\\s+ON\\s*$idf\\s*(?:FOR\\s+EACH\\s+ROW\\s)?(.*)~is",
get_val("SELECT sql FROM sqlite_master WHERE type = 'trigger' AND name = " . q($name)), $connection->result("SELECT sql FROM sqlite_master WHERE type = 'trigger' AND name = " . q($name)),
$match $match
); );
$of = $match[3]; $of = $match[3];
@@ -650,8 +704,9 @@ if (isset($_GET["sqlite"])) {
return queries("BEGIN"); return queries("BEGIN");
} }
function last_id($result) { function last_id() {
return get_val("SELECT LAST_INSERT_ROWID()"); global $connection;
return $connection->result("SELECT LAST_INSERT_ROWID()");
} }
function explain($connection, $query) { function explain($connection, $query) {
@@ -661,17 +716,30 @@ if (isset($_GET["sqlite"])) {
function found_rows($table_status, $where) { function found_rows($table_status, $where) {
} }
function types(): array { function types() {
return array(); return array();
} }
function schemas() {
return array();
}
function get_schema() {
return "";
}
function set_schema($scheme) {
return true;
}
function create_sql($table, $auto_increment, $style) { function create_sql($table, $auto_increment, $style) {
$return = get_val("SELECT sql FROM sqlite_master WHERE type IN ('table', 'view') AND name = " . q($table)); global $connection;
$return = $connection->result("SELECT sql FROM sqlite_master WHERE type IN ('table', 'view') AND name = " . q($table));
foreach (indexes($table) as $name => $index) { foreach (indexes($table) as $name => $index) {
if ($name == '') { if ($name == '') {
continue; continue;
} }
$return .= ";\n\n" . index_sql($table, $index['type'], $name, "(" . implode(", ", array_map('Adminer\idf_escape', $index['columns'])) . ")"); $return .= ";\n\n" . index_sql($table, $index['type'], $name, "(" . implode(", ", array_map('idf_escape', $index['columns'])) . ")");
} }
return $return; return $return;
} }
@@ -688,15 +756,10 @@ if (isset($_GET["sqlite"])) {
} }
function show_variables() { function show_variables() {
global $connection;
$return = array(); $return = array();
foreach (get_rows("PRAGMA pragma_list") as $row) { foreach (array("auto_vacuum", "cache_size", "count_changes", "default_cache_size", "empty_result_callbacks", "encoding", "foreign_keys", "full_column_names", "fullfsync", "journal_mode", "journal_size_limit", "legacy_file_format", "locking_mode", "page_size", "max_page_count", "read_uncommitted", "recursive_triggers", "reverse_unordered_selects", "secure_delete", "short_column_names", "synchronous", "temp_store", "temp_store_directory", "schema_version", "integrity_check", "quick_check") as $key) {
$name = $row["name"]; $return[$key] = $connection->result("PRAGMA $key");
if ($name != "pragma_list" && $name != "compile_options") {
$return[$name] = array($name, '');
foreach (get_rows("PRAGMA $name") as $row) {
$return[$name][1] .= implode(", ", $row) . "\n";
}
}
} }
return $return; return $return;
} }
@@ -704,7 +767,8 @@ if (isset($_GET["sqlite"])) {
function show_status() { function show_status() {
$return = array(); $return = array();
foreach (get_vals("PRAGMA compile_options") as $option) { foreach (get_vals("PRAGMA compile_options") as $option) {
$return[] = explode("=", $option, 2); list($key, $val) = explode("=", $option, 2);
$return[$key] = $val;
} }
return $return; return $return;
} }
@@ -717,6 +781,29 @@ if (isset($_GET["sqlite"])) {
} }
function support($feature) { function support($feature) {
return preg_match('~^(check|columns|database|drop_col|dump|indexes|descidx|move_col|sql|status|table|trigger|variables|view|view_trigger)$~', $feature); return preg_match('~^(columns|database|drop_col|dump|indexes|descidx|move_col|sql|status|table|trigger|variables|view|view_trigger)$~', $feature);
}
function driver_config() {
$types = array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0);
return array(
'possible_drivers' => array((isset($_GET["sqlite"]) ? "SQLite3" : "SQLite"), "PDO_SQLite"),
'jush' => "sqlite",
'types' => $types,
'structured_types' => array_keys($types),
'unsigned' => array(),
'operators' => array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"), // REGEXP can be user defined function
'functions' => array("hex", "length", "lower", "round", "unixepoch", "upper"),
'grouping' => array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"),
'edit_functions' => array(
array(
// "text" => "date('now')/time('now')/datetime('now')",
), array(
"integer|real|numeric" => "+/-",
// "text" => "date/time/datetime",
"text" => "||",
)
),
);
} }
} }

View File

@@ -1,31 +1,29 @@
<?php <?php
namespace Adminer;
$TABLE = $_GET["dump"]; $TABLE = $_GET["dump"];
if ($_POST && !$error) { if ($_POST && !$error) {
save_settings( $cookie = "";
array_intersect_key($_POST, array_flip(array("output", "format", "db_style", "types", "routines", "events", "table_style", "auto_increment", "triggers", "data_style"))), foreach (array("output", "format", "db_style", "routines", "events", "table_style", "auto_increment", "triggers", "data_style") as $key) {
"adminer_export" $cookie .= "&$key=" . urlencode($_POST[$key]);
); }
cookie("adminer_export", substr($cookie, 1));
$tables = array_flip((array) $_POST["tables"]) + array_flip((array) $_POST["data"]); $tables = array_flip((array) $_POST["tables"]) + array_flip((array) $_POST["data"]);
$ext = dump_headers( $ext = dump_headers(
(count($tables) == 1 ? key($tables) : DB), (count($tables) == 1 ? key($tables) : DB),
(DB == "" || count($tables) > 1) (DB == "" || count($tables) > 1));
);
$is_sql = preg_match('~sql~', $_POST["format"]); $is_sql = preg_match('~sql~', $_POST["format"]);
if ($is_sql) { if ($is_sql) {
echo "-- Adminer " . VERSION . " " . get_driver(DRIVER) . " " . str_replace("\n", " ", connection()->server_info) . " dump\n\n"; echo "-- Adminer $VERSION " . $drivers[DRIVER] . " " . str_replace("\n", " ", $connection->server_info) . " dump\n\n";
if (JUSH == "sql") { if ($jush == "sql") {
echo "SET NAMES utf8; echo "SET NAMES utf8;
SET time_zone = '+00:00'; SET time_zone = '+00:00';
SET foreign_key_checks = 0; SET foreign_key_checks = 0;
" . ($_POST["data_style"] ? "SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'; " . ($_POST["data_style"] ? "SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
" : "") . " " : "") . "
"; ";
connection()->query("SET time_zone = '+00:00'"); $connection->query("SET time_zone = '+00:00'");
connection()->query("SET sql_mode = ''"); $connection->query("SET sql_mode = ''");
} }
} }
@@ -39,9 +37,9 @@ SET foreign_key_checks = 0;
} }
foreach ((array) $databases as $db) { foreach ((array) $databases as $db) {
adminer()->dumpDatabase($db); $adminer->dumpDatabase($db);
if (connection()->select_db($db)) { if ($connection->select_db($db)) {
if ($is_sql && preg_match('~CREATE~', $style) && ($create = get_val("SHOW CREATE DATABASE " . idf_escape($db), 1))) { if ($is_sql && preg_match('~CREATE~', $style) && ($create = $connection->result("SHOW CREATE DATABASE " . idf_escape($db), 1))) {
set_utf8mb4($create); set_utf8mb4($create);
if ($style == "DROP+CREATE") { if ($style == "DROP+CREATE") {
echo "DROP DATABASE IF EXISTS " . idf_escape($db) . ";\n"; echo "DROP DATABASE IF EXISTS " . idf_escape($db) . ";\n";
@@ -54,37 +52,27 @@ SET foreign_key_checks = 0;
} }
$out = ""; $out = "";
if ($_POST["types"]) {
foreach (types() as $id => $type) {
$enums = type_values($id);
if ($enums) {
$out .= ($style != 'DROP+CREATE' ? "DROP TYPE IF EXISTS " . idf_escape($type) . ";;\n" : "") . "CREATE TYPE " . idf_escape($type) . " AS ENUM ($enums);\n\n";
} else {
//! https://github.com/postgres/postgres/blob/REL_17_4/src/bin/pg_dump/pg_dump.c#L10846
$out .= "-- Could not export type $type\n\n";
}
}
}
if ($_POST["routines"]) { if ($_POST["routines"]) {
foreach (routines() as $row) { foreach (array("FUNCTION", "PROCEDURE") as $routine) {
$name = $row["ROUTINE_NAME"]; foreach (get_rows("SHOW $routine STATUS WHERE Db = " . q($db), null, "-- ") as $row) {
$routine = $row["ROUTINE_TYPE"]; $create = remove_definer($connection->result("SHOW CREATE $routine " . idf_escape($row["Name"]), 2));
$create = create_routine($routine, array("name" => $name) + routine($row["SPECIFIC_NAME"], $routine));
set_utf8mb4($create); set_utf8mb4($create);
$out .= ($style != 'DROP+CREATE' ? "DROP $routine IF EXISTS " . idf_escape($name) . ";;\n" : "") . "$create;\n\n"; $out .= ($style != 'DROP+CREATE' ? "DROP $routine IF EXISTS " . idf_escape($row["Name"]) . ";;\n" : "") . "$create;;\n\n";
}
} }
} }
if ($_POST["events"]) { if ($_POST["events"]) {
foreach (get_rows("SHOW EVENTS", null, "-- ") as $row) { foreach (get_rows("SHOW EVENTS", null, "-- ") as $row) {
$create = remove_definer(get_val("SHOW CREATE EVENT " . idf_escape($row["Name"]), 3)); $create = remove_definer($connection->result("SHOW CREATE EVENT " . idf_escape($row["Name"]), 3));
set_utf8mb4($create); set_utf8mb4($create);
$out .= ($style != 'DROP+CREATE' ? "DROP EVENT IF EXISTS " . idf_escape($row["Name"]) . ";;\n" : "") . "$create;;\n\n"; $out .= ($style != 'DROP+CREATE' ? "DROP EVENT IF EXISTS " . idf_escape($row["Name"]) . ";;\n" : "") . "$create;;\n\n";
} }
} }
echo ($out && JUSH == 'sql' ? "DELIMITER ;;\n\n$out" . "DELIMITER ;\n\n" : $out); if ($out) {
echo "DELIMITER ;;\n\n$out" . "DELIMITER ;\n\n";
}
} }
if ($_POST["table_style"] || $_POST["data_style"]) { if ($_POST["table_style"] || $_POST["data_style"]) {
@@ -93,18 +81,17 @@ SET foreign_key_checks = 0;
$table = (DB == "" || in_array($name, (array) $_POST["tables"])); $table = (DB == "" || in_array($name, (array) $_POST["tables"]));
$data = (DB == "" || in_array($name, (array) $_POST["data"])); $data = (DB == "" || in_array($name, (array) $_POST["data"]));
if ($table || $data) { if ($table || $data) {
$tmp_file = null;
if ($ext == "tar") { if ($ext == "tar") {
$tmp_file = new TmpFile; $tmp_file = new TmpFile;
ob_start(array($tmp_file, 'write'), 1e5); ob_start(array($tmp_file, 'write'), 1e5);
} }
adminer()->dumpTable($name, ($table ? $_POST["table_style"] : ""), (is_view($table_status) ? 2 : 0)); $adminer->dumpTable($name, ($table ? $_POST["table_style"] : ""), (is_view($table_status) ? 2 : 0));
if (is_view($table_status)) { if (is_view($table_status)) {
$views[] = $name; $views[] = $name;
} elseif ($data) { } elseif ($data) {
$fields = fields($name); $fields = fields($name);
adminer()->dumpData($name, $_POST["data_style"], "SELECT *" . convert_fields($fields, $fields) . " FROM " . table($name)); $adminer->dumpData($name, $_POST["data_style"], "SELECT *" . convert_fields($fields, $fields) . " FROM " . table($name));
} }
if ($is_sql && $_POST["triggers"] && $table && ($triggers = trigger_sql($name))) { if ($is_sql && $_POST["triggers"] && $table && ($triggers = trigger_sql($name))) {
echo "\nDELIMITER ;;\n$triggers\nDELIMITER ;\n"; echo "\nDELIMITER ;;\n$triggers\nDELIMITER ;\n";
@@ -120,7 +107,7 @@ SET foreign_key_checks = 0;
} }
// add FKs after creating tables (except in MySQL which uses SET FOREIGN_KEY_CHECKS=0) // add FKs after creating tables (except in MySQL which uses SET FOREIGN_KEY_CHECKS=0)
if (function_exists('Adminer\foreign_keys_sql')) { if (function_exists('foreign_keys_sql')) {
foreach (table_status('', true) as $name => $table_status) { foreach (table_status('', true) as $name => $table_status) {
$table = (DB == "" || in_array($name, (array) $_POST["tables"])); $table = (DB == "" || in_array($name, (array) $_POST["tables"]));
if ($table && !is_view($table_status)) { if ($table && !is_view($table_status)) {
@@ -130,7 +117,7 @@ SET foreign_key_checks = 0;
} }
foreach ($views as $view) { foreach ($views as $view) {
adminer()->dumpTable($view, $_POST["table_style"], 1); $adminer->dumpTable($view, $_POST["table_style"], 1);
} }
if ($ext == "tar") { if ($ext == "tar") {
@@ -140,7 +127,9 @@ SET foreign_key_checks = 0;
} }
} }
adminer()->dumpFooter(); if ($is_sql) {
echo "-- " . $connection->result("SELECT NOW()") . "\n";
}
exit; exit;
} }
@@ -148,29 +137,26 @@ page_header(lang('Export'), $error, ($_GET["export"] != "" ? array("table" => $_
?> ?>
<form action="" method="post"> <form action="" method="post">
<table class="layout"> <table cellspacing="0" class="layout">
<?php <?php
$db_style = array('', 'USE', 'DROP+CREATE', 'CREATE'); $db_style = array('', 'USE', 'DROP+CREATE', 'CREATE');
$table_style = array('', 'DROP+CREATE', 'CREATE'); $table_style = array('', 'DROP+CREATE', 'CREATE');
$data_style = array('', 'TRUNCATE+INSERT', 'INSERT'); $data_style = array('', 'TRUNCATE+INSERT', 'INSERT');
if (JUSH == "sql") { //! use insertUpdate() in all drivers if ($jush == "sql") { //! use insertUpdate() in all drivers
$data_style[] = 'INSERT+UPDATE'; $data_style[] = 'INSERT+UPDATE';
} }
$row = get_settings("adminer_export"); parse_str($_COOKIE["adminer_export"], $row);
if (!$row) { if (!$row) {
$row = array("output" => "text", "format" => "sql", "db_style" => (DB != "" ? "" : "CREATE"), "table_style" => "DROP+CREATE", "data_style" => "INSERT"); $row = array("output" => "file", "format" => "sql", "db_style" => (DB != "" ? "" : "CREATE"), "table_style" => "DROP+CREATE", "data_style" => "INSERT");
} }
if (!isset($row["events"])) { // backwards compatibility if (!isset($row["events"])) { // backwards compatibility
$row["routines"] = $row["events"] = ($_GET["dump"] == ""); $row["routines"] = $row["events"] = ($_GET["dump"] == "");
$row["triggers"] = $row["table_style"]; $row["triggers"] = $row["table_style"];
} }
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"], false) . "\n"; // false = 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"])
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')) : "")
. (support("routine") ? checkbox("routines", 1, $row["routines"], lang('Routines')) : "") . (support("routine") ? checkbox("routines", 1, $row["routines"], lang('Routines')) : "")
. (support("event") ? checkbox("events", 1, $row["events"], lang('Events')) : "") . (support("event") ? checkbox("events", 1, $row["events"], lang('Events')) : "")
); );
@@ -181,12 +167,15 @@ echo "<tr><th>" . lang('Tables') . "<td>" . html_select('table_style', $table_st
; ;
echo "<tr><th>" . lang('Data') . "<td>" . html_select('data_style', $data_style, $row["data_style"]); echo "<tr><th>" . lang('Data') . "<td>" . html_select('data_style', $data_style, $row["data_style"]);
echo "<tr><th>" . lang('Output') . "<td>" . html_select("output", $adminer->dumpOutput(), $row["output"], false) . "\n"; // false = radio
?> ?>
</table> </table>
<p><input type="submit" value="<?php echo lang('Export'); ?>"> <p><input type="submit" value="<?php echo lang('Export'); ?>">
<?php echo input_token(); ?> <input type="hidden" name="token" value="<?php echo $token; ?>">
<table> <table cellspacing="0">
<?php <?php
echo script("qsl('table').onclick = dumpClick;"); echo script("qsl('table').onclick = dumpClick;");
$prefixes = array(); $prefixes = array();
@@ -221,7 +210,7 @@ if (DB != "") {
echo "<label class='block'><input type='checkbox' id='check-databases'" . ($TABLE == "" ? " checked" : "") . ">" . lang('Database') . "</label>"; echo "<label class='block'><input type='checkbox' id='check-databases'" . ($TABLE == "" ? " checked" : "") . ">" . lang('Database') . "</label>";
echo script("qs('#check-databases').onclick = partial(formCheck, /^databases\\[/);", ""); echo script("qs('#check-databases').onclick = partial(formCheck, /^databases\\[/);", "");
echo "</thead>\n"; echo "</thead>\n";
$databases = adminer()->databases(); $databases = $adminer->databases();
if ($databases) { if ($databases) {
foreach ($databases as $db) { foreach ($databases as $db) {
if (!information_schema($db)) { if (!information_schema($db)) {

View File

@@ -1,15 +1,10 @@
<?php <?php
namespace Adminer;
$TABLE = $_GET["edit"]; $TABLE = $_GET["edit"];
$fields = fields($TABLE); $fields = fields($TABLE);
$where = (isset($_GET["select"]) $where = (isset($_GET["select"]) ? ($_POST["check"] && count($_POST["check"]) == 1 ? where_check($_POST["check"][0], $fields) : "") : where($_GET, $fields));
? ($_POST["check"] && count($_POST["check"]) == 1 ? where_check($_POST["check"][0], $fields) : "")
: where($_GET, $fields)
);
$update = (isset($_GET["select"]) ? $_POST["edit"] : $where); $update = (isset($_GET["select"]) ? $_POST["edit"] : $where);
foreach ($fields as $name => $field) { foreach ($fields as $name => $field) {
if (!isset($field["privileges"][$update ? "update" : "insert"]) || adminer()->fieldName($field) == "" || $field["generated"]) { if (!isset($field["privileges"][$update ? "update" : "insert"]) || $adminer->fieldName($field) == "" || $field["generated"]) {
unset($fields[$name]); unset($fields[$name]);
} }
} }
@@ -30,7 +25,7 @@ if ($_POST && !$error && !isset($_GET["select"])) {
queries_redirect( queries_redirect(
$location, $location,
lang('Item has been deleted.'), lang('Item has been deleted.'),
driver()->delete($TABLE, $query_where, $unique_array ? 0 : 1) $driver->delete($TABLE, $query_where, !$unique_array)
); );
} else { } else {
@@ -49,7 +44,7 @@ if ($_POST && !$error && !isset($_GET["select"])) {
queries_redirect( queries_redirect(
$location, $location,
lang('Item has been updated.'), lang('Item has been updated.'),
driver()->update($TABLE, $set, $query_where, $unique_array ? 0 : 1) $driver->update($TABLE, $set, $query_where, !$unique_array)
); );
if (is_ajax()) { if (is_ajax()) {
page_headers(); page_headers();
@@ -57,8 +52,8 @@ if ($_POST && !$error && !isset($_GET["select"])) {
exit; exit;
} }
} else { } else {
$result = driver()->insert($TABLE, $set); $result = $driver->insert($TABLE, $set);
$last_id = ($result ? last_id($result) : 0); $last_id = ($result ? last_id() : 0);
queries_redirect($location, lang('Item%s has been inserted.', ($last_id ? " $last_id" : "")), $result); //! link queries_redirect($location, lang('Item%s has been inserted.', ($last_id ? " $last_id" : "")), $result); //! link
} }
} }
@@ -71,7 +66,13 @@ if ($_POST["save"]) {
$select = array(); $select = array();
foreach ($fields as $name => $field) { foreach ($fields as $name => $field) {
if (isset($field["privileges"]["select"])) { if (isset($field["privileges"]["select"])) {
$as = ($_POST["clone"] && $field["auto_increment"] ? "''" : convert_field($field)); $as = convert_field($field);
if ($_POST["clone"] && $field["auto_increment"]) {
$as = "''";
}
if ($jush == "sql" && preg_match("~enum|set~", $field["type"])) {
$as = "1*" . idf_escape($name);
}
$select[] = ($as ? "$as AS " : "") . idf_escape($name); $select[] = ($as ? "$as AS " : "") . idf_escape($name);
} }
} }
@@ -80,7 +81,7 @@ if ($_POST["save"]) {
$select = array("*"); $select = array("*");
} }
if ($select) { if ($select) {
$result = driver()->select($TABLE, $select, array($where), $select, array(), (isset($_GET["select"]) ? 2 : 1)); $result = $driver->select($TABLE, $select, array($where), $select, array(), (isset($_GET["select"]) ? 2 : 1));
if (!$result) { if (!$result) {
$error = error(); $error = error();
} else { } else {
@@ -95,12 +96,12 @@ if ($_POST["save"]) {
} }
} }
if (!support("table") && !$fields) { // used by Mongo and SimpleDB if (!support("table") && !$fields) {
if (!$where) { // insert if (!$where) { // insert
$result = driver()->select($TABLE, array("*"), array(), array("*")); $result = $driver->select($TABLE, array("*"), $where, array("*"));
$row = ($result ? $result->fetch_assoc() : false); $row = ($result ? $result->fetch_assoc() : false);
if (!$row) { if (!$row) {
$row = array(driver()->primary => ""); $row = array($driver->primary => "");
} }
} }
if ($row) { if ($row) {
@@ -108,9 +109,9 @@ if (!support("table") && !$fields) { // used by Mongo and SimpleDB
if (!$where) { if (!$where) {
$row[$key] = null; $row[$key] = null;
} }
$fields[$key] = array("field" => $key, "null" => ($key != driver()->primary), "auto_increment" => ($key == driver()->primary)); $fields[$key] = array("field" => $key, "null" => ($key != $driver->primary), "auto_increment" => ($key == $driver->primary));
} }
} }
} }
edit_form($TABLE, $fields, $row, $update, $error); edit_form($TABLE, $fields, $row, $update);

View File

@@ -1,13 +1,13 @@
<?php <?php
// To create Adminer just for Elasticsearch, run `../compile.php elastic`.
function adminer_object() { function adminer_object() {
include_once "../plugins/plugin.php";
include_once "../plugins/login-password-less.php"; include_once "../plugins/login-password-less.php";
include_once "../plugins/drivers/elastic.php"; include_once "../plugins/drivers/elastic.php";
return new Adminer\Plugins(array( include_once "../plugins/drivers/elastic5.php";
return new AdminerPlugin([
// TODO: inline the result of password_hash() so that the password is not visible in source codes // 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)), new AdminerLoginPasswordLess(password_hash("YOUR_PASSWORD_HERE", PASSWORD_DEFAULT)),
)); ]);
} }
include "./index.php"; include "./index.php";

View File

@@ -1,6 +1,4 @@
<?php <?php
namespace Adminer;
$EVENT = $_GET["event"]; $EVENT = $_GET["event"];
$intervals = array("YEAR", "QUARTER", "MONTH", "DAY", "HOUR", "MINUTE", "WEEK", "SECOND", "YEAR_MONTH", "DAY_HOUR", "DAY_MINUTE", "DAY_SECOND", "HOUR_MINUTE", "HOUR_SECOND", "MINUTE_SECOND"); $intervals = array("YEAR", "QUARTER", "MONTH", "DAY", "HOUR", "MINUTE", "WEEK", "SECOND", "YEAR_MONTH", "DAY_HOUR", "DAY_MINUTE", "DAY_SECOND", "HOUR_MINUTE", "HOUR_SECOND", "MINUTE_SECOND");
$statuses = array("ENABLED" => "ENABLE", "DISABLED" => "DISABLE", "SLAVESIDE_DISABLED" => "DISABLE ON SLAVE"); $statuses = array("ENABLED" => "ENABLE", "DISABLED" => "DISABLE", "SLAVESIDE_DISABLED" => "DISABLE ON SLAVE");
@@ -18,17 +16,13 @@ if ($_POST && !$error) {
) . " ON COMPLETION" . ($row["ON_COMPLETION"] ? "" : " NOT") . " PRESERVE" ) . " ON COMPLETION" . ($row["ON_COMPLETION"] ? "" : " NOT") . " PRESERVE"
; ;
queries_redirect( queries_redirect(substr(ME, 0, -1), ($EVENT != "" ? lang('Event has been altered.') : lang('Event has been created.')), queries(($EVENT != ""
substr(ME, 0, -1), ? "ALTER EVENT " . idf_escape($EVENT) . $schedule
($EVENT != "" ? lang('Event has been altered.') : lang('Event has been created.')), . ($EVENT != $row["EVENT_NAME"] ? "\nRENAME TO " . idf_escape($row["EVENT_NAME"]) : "")
queries(
($EVENT != ""
? "ALTER EVENT " . idf_escape($EVENT) . $schedule . ($EVENT != $row["EVENT_NAME"] ? "\nRENAME TO " . idf_escape($row["EVENT_NAME"]) : "")
: "CREATE EVENT " . idf_escape($row["EVENT_NAME"]) . $schedule : "CREATE EVENT " . idf_escape($row["EVENT_NAME"]) . $schedule
) . "\n" . $statuses[$row["STATUS"]] . " COMMENT " . q($row["EVENT_COMMENT"]) ) . "\n" . $statuses[$row["STATUS"]] . " COMMENT " . q($row["EVENT_COMMENT"])
. rtrim(" DO\n$row[EVENT_DEFINITION]", ";") . ";" . rtrim(" DO\n$row[EVENT_DEFINITION]", ";") . ";"
) ));
);
} }
} }
@@ -41,7 +35,7 @@ if (!$row && $EVENT != "") {
?> ?>
<form action="" method="post"> <form action="" method="post">
<table class="layout"> <table cellspacing="0" class="layout">
<tr><th><?php echo lang('Name'); ?><td><input name="EVENT_NAME" value="<?php echo h($row["EVENT_NAME"]); ?>" data-maxlength="64" autocapitalize="off"> <tr><th><?php echo lang('Name'); ?><td><input name="EVENT_NAME" value="<?php echo h($row["EVENT_NAME"]); ?>" data-maxlength="64" autocapitalize="off">
<tr><th title="datetime"><?php echo lang('Start'); ?><td><input name="STARTS" value="<?php echo h("$row[EXECUTE_AT]$row[STARTS]"); ?>"> <tr><th title="datetime"><?php echo lang('Start'); ?><td><input name="STARTS" value="<?php echo h("$row[EXECUTE_AT]$row[STARTS]"); ?>">
<tr><th title="datetime"><?php echo lang('End'); ?><td><input name="ENDS" value="<?php echo h($row["ENDS"]); ?>"> <tr><th title="datetime"><?php echo lang('End'); ?><td><input name="ENDS" value="<?php echo h($row["ENDS"]); ?>">
@@ -53,8 +47,6 @@ if (!$row && $EVENT != "") {
<p><?php textarea("EVENT_DEFINITION", $row["EVENT_DEFINITION"]); ?> <p><?php textarea("EVENT_DEFINITION", $row["EVENT_DEFINITION"]); ?>
<p> <p>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php if ($EVENT != "") { ?> <?php if ($EVENT != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $EVENT)); ?><?php } ?>
<input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $EVENT)); ?> <input type="hidden" name="token" value="<?php echo $token; ?>">
<?php } ?>
<?php echo input_token(); ?>
</form> </form>

View File

@@ -1,39 +1,26 @@
<?php <?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") { if ($_GET["file"] == "favicon.ico") {
header("Content-Type: image/x-icon"); header("Content-Type: image/x-icon");
echo lzw_decompress(compile_file('../adminer/static/favicon.ico', 'lzw_compress')); echo lzw_decompress(compile_file('../adminer/static/favicon.ico', 'lzw_compress'));
} elseif ($_GET["file"] == "default.css") { } elseif ($_GET["file"] == "default.css") {
header("Content-Type: text/css; charset=utf-8"); header("Content-Type: text/css; charset=utf-8");
echo lzw_decompress(compile_file('../adminer/static/default.css;../externals/jush/jush.css', 'minify_css')); echo lzw_decompress(compile_file('../adminer/static/default.css;../vendor/vrana/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") { } elseif ($_GET["file"] == "functions.js") {
header("Content-Type: text/javascript; charset=utf-8"); header("Content-Type: text/javascript; charset=utf-8");
echo lzw_decompress(compile_file('../adminer/static/functions.js;static/editing.js', 'minify_js')); echo lzw_decompress(compile_file('../adminer/static/functions.js;static/editing.js', 'minify_js'));
} elseif ($_GET["file"] == "jush.js") { } elseif ($_GET["file"] == "jush.js") {
header("Content-Type: text/javascript; charset=utf-8"); header("Content-Type: text/javascript; charset=utf-8");
echo lzw_decompress(compile_file('../externals/jush/modules/jush.js; echo lzw_decompress(compile_file('../vendor/vrana/jush/modules/jush.js;../vendor/vrana/jush/modules/jush-textarea.js;../vendor/vrana/jush/modules/jush-txt.js;../vendor/vrana/jush/modules/jush-js.js;../vendor/vrana/jush/modules/jush-sql.js;../vendor/vrana/jush/modules/jush-pgsql.js;../vendor/vrana/jush/modules/jush-sqlite.js;../vendor/vrana/jush/modules/jush-mssql.js;../vendor/vrana/jush/modules/jush-oracle.js;../vendor/vrana/jush/modules/jush-simpledb.js', 'minify_js'));
../externals/jush/modules/jush-textarea.js; } else {
../externals/jush/modules/jush-txt.js; header("Content-Type: image/gif");
../externals/jush/modules/jush-js.js; switch ($_GET["file"]) {
../externals/jush/modules/jush-sql.js; case "plus.gif": echo compile_file('../adminer/static/plus.gif'); break;
../externals/jush/modules/jush-pgsql.js; case "cross.gif": echo compile_file('../adminer/static/cross.gif'); break;
../externals/jush/modules/jush-sqlite.js; case "up.gif": echo compile_file('../adminer/static/up.gif'); break;
../externals/jush/modules/jush-mssql.js; case "down.gif": echo compile_file('../adminer/static/down.gif'); break;
../externals/jush/modules/jush-oracle.js; case "arrow.gif": echo compile_file('../adminer/static/arrow.gif'); break;
../externals/jush/modules/jush-simpledb.js', 'minify_js')); }
} }
exit; exit;

View File

@@ -1,11 +1,12 @@
<?php <?php
namespace Adminer;
$TABLE = $_GET["foreign"]; $TABLE = $_GET["foreign"];
$name = $_GET["name"]; $name = $_GET["name"];
$row = $_POST; $row = $_POST;
if ($_POST && !$error && !$_POST["add"] && !$_POST["change"] && !$_POST["change-js"]) { if ($_POST && !$error && !$_POST["add"] && !$_POST["change"] && !$_POST["change-js"]) {
$message = ($_POST["drop"] ? lang('Foreign key has been dropped.') : ($name != "" ? lang('Foreign key has been altered.') : lang('Foreign key has been created.')));
$location = ME . "table=" . urlencode($TABLE);
if (!$_POST["drop"]) { if (!$_POST["drop"]) {
$row["source"] = array_filter($row["source"], 'strlen'); $row["source"] = array_filter($row["source"], 'strlen');
ksort($row["source"]); // enforce input order ksort($row["source"]); // enforce input order
@@ -16,23 +17,18 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["change"] && !$_POST["change-
$row["target"] = $target; $row["target"] = $target;
} }
if (JUSH == "sqlite") { if ($jush == "sqlite") {
$result = recreate_table($TABLE, $TABLE, array(), array(), array(" $name" => ($row["drop"] ? "" : " " . format_foreign_key($row)))); queries_redirect($location, $message, recreate_table($TABLE, $TABLE, array(), array(), array(" $name" => ($_POST["drop"] ? "" : " " . format_foreign_key($row)))));
} else { } else {
$alter = "ALTER TABLE " . table($TABLE); $alter = "ALTER TABLE " . table($TABLE);
$result = ($name == "" || queries("$alter DROP " . (JUSH == "sql" ? "FOREIGN KEY " : "CONSTRAINT ") . idf_escape($name))); $drop = "\nDROP " . ($jush == "sql" ? "FOREIGN KEY " : "CONSTRAINT ") . idf_escape($name);
if (!$row["drop"]) { if ($_POST["drop"]) {
$result = queries("$alter ADD" . format_foreign_key($row)); query_redirect($alter . $drop, $location, $message);
} else {
query_redirect($alter . ($name != "" ? "$drop," : "") . "\nADD" . format_foreign_key($row), $location, $message);
$error = lang('Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.') . "<br>$error"; //! no partitioning
} }
} }
queries_redirect(
ME . "table=" . urlencode($TABLE),
($row["drop"] ? lang('Foreign key has been dropped.') : ($name != "" ? lang('Foreign key has been altered.') : lang('Foreign key has been created.'))),
$result
);
if (!$row["drop"]) {
$error = "$error<br>" . lang('Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.'); //! no partitioning
}
} }
page_header(lang('Foreign key'), $error, array("table" => $TABLE), h($TABLE)); page_header(lang('Foreign key'), $error, array("table" => $TABLE), h($TABLE));
@@ -58,63 +54,54 @@ if ($_POST) {
<?php <?php
$source = array_keys(fields($TABLE)); //! no text and blob $source = array_keys(fields($TABLE)); //! no text and blob
if ($row["db"] != "") { if ($row["db"] != "") {
connection()->select_db($row["db"]); $connection->select_db($row["db"]);
} }
if ($row["ns"] != "") { if ($row["ns"] != "") {
$orig_schema = get_schema();
set_schema($row["ns"]); set_schema($row["ns"]);
} }
$referencable = array_keys(array_filter(table_status('', true), 'Adminer\fk_support')); $referencable = array_keys(array_filter(table_status('', true), 'fk_support'));
$target = array_keys(fields(in_array($row["table"], $referencable) ? $row["table"] : reset($referencable))); $target = array_keys(fields(in_array($row["table"], $referencable) ? $row["table"] : reset($referencable)));
$onchange = "this.form['change-js'].value = '1'; this.form.submit();"; $onchange = "this.form['change-js'].value = '1'; this.form.submit();";
echo "<p>" . lang('Target table') . ": " . html_select("table", $referencable, $row["table"], $onchange) . "\n"; echo "<p>" . lang('Target table') . ": " . html_select("table", $referencable, $row["table"], $onchange) . "\n";
if (support("scheme")) { if ($jush == "pgsql") {
$schemas = array_filter(adminer()->schemas(), function ($schema) { echo lang('Schema') . ": " . html_select("ns", $adminer->schemas(), $row["ns"] != "" ? $row["ns"] : $_GET["ns"], $onchange);
return !preg_match('~^information_schema$~i', $schema); } elseif ($jush != "sqlite") {
});
echo lang('Schema') . ": " . html_select("ns", $schemas, $row["ns"] != "" ? $row["ns"] : $_GET["ns"], $onchange);
if ($row["ns"] != "") {
set_schema($orig_schema);
}
} elseif (JUSH != "sqlite") {
$dbs = array(); $dbs = array();
foreach (adminer()->databases() as $db) { foreach ($adminer->databases() as $db) {
if (!information_schema($db)) { if (!information_schema($db)) {
$dbs[] = $db; $dbs[] = $db;
} }
} }
echo lang('DB') . ": " . html_select("db", $dbs, $row["db"] != "" ? $row["db"] : $_GET["db"], $onchange); 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> <noscript><p><input type="submit" name="change" value="<?php echo lang('Change'); ?>"></noscript>
<table> <table cellspacing="0">
<thead><tr><th id="label-source"><?php echo lang('Source'); ?><th id="label-target"><?php echo lang('Target'); ?></thead> <thead><tr><th id="label-source"><?php echo lang('Source'); ?><th id="label-target"><?php echo lang('Target'); ?></thead>
<?php <?php
$j = 0; $j = 0;
foreach ($row["source"] as $key => $val) { foreach ($row["source"] as $key => $val) {
echo "<tr>"; echo "<tr>";
echo "<td>" . html_select("source[" . (+$key) . "]", array(-1 => "") + $source, $val, ($j == count($row["source"]) - 1 ? "foreignAddRow.call(this);" : ""), "label-source"); 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, idx($row["target"], $key), "", "label-target"); echo "<td>" . html_select("target[" . (+$key) . "]", $target, $row["target"][$key], 1, "label-target");
$j++; $j++;
} }
?> ?>
</table> </table>
<p> <p>
<?php echo lang('ON DELETE'); ?>: <?php echo html_select("on_delete", array(-1 => "") + explode("|", driver()->onActions), $row["on_delete"]); ?> <?php echo lang('ON DELETE'); ?>: <?php echo html_select("on_delete", array(-1 => "") + explode("|", $on_actions), $row["on_delete"]); ?>
<?php echo lang('ON UPDATE'); ?>: <?php echo html_select("on_update", array(-1 => "") + explode("|", driver()->onActions), $row["on_update"]); ?> <?php echo lang('ON UPDATE'); ?>: <?php echo html_select("on_update", array(-1 => "") + explode("|", $on_actions), $row["on_update"]); ?>
<?php echo doc_link(array( <?php echo doc_link(array(
'sql' => "innodb-foreign-key-constraints.html", 'sql' => "innodb-foreign-key-constraints.html",
'mariadb' => "foreign-keys/", 'mariadb' => "foreign-keys/",
'pgsql' => "sql-createtable.html#SQL-CREATETABLE-REFERENCES", 'pgsql' => "sql-createtable.html#SQL-CREATETABLE-REFERENCES",
'mssql' => "t-sql/statements/create-table-transact-sql", 'mssql' => "ms174979.aspx",
'oracle' => "SQLRF01111", 'oracle' => "https://docs.oracle.com/cd/B19306_01/server.102/b14200/clauses002.htm#sthref2903",
)); ?> )); ?>
<p> <p>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<noscript><p><input type="submit" name="add" value="<?php echo lang('Add column'); ?>"></noscript> <noscript><p><input type="submit" name="add" value="<?php echo lang('Add column'); ?>"></noscript>
<?php if ($name != "") { ?> <?php if ($name != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $name)); ?><?php } ?>
<input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $name)); ?> <input type="hidden" name="token" value="<?php echo $token; ?>">
<?php } ?>
<?php echo input_token(); ?>
</form> </form>

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,11 @@
<?php <?php
namespace Adminer; $connection = '';
$has_token = $_SESSION["token"];
if (!$has_token) {
$_SESSION["token"] = rand(1, 1e6); // defense against cross-site request forgery
}
$token = get_token(); ///< @var string CSRF protection
$permanent = array(); $permanent = array();
if ($_COOKIE["adminer_permanent"]) { if ($_COOKIE["adminer_permanent"]) {
@@ -9,18 +15,74 @@ if ($_COOKIE["adminer_permanent"]) {
} }
} }
function add_invalid_login(): void { function validate_server_input() {
$base = get_temp_dir() . "/adminer.invalid"; if (SERVER == "") {
// adminer.invalid may not be writable by us, try the files with random suffixes return;
foreach (glob("$base*") ?: array($base) as $filename) {
$fp = file_open_lock($filename);
if ($fp) {
break;
} }
$parts = parse_url(SERVER);
if (!$parts) {
auth_error(lang('Invalid server or credentials.'));
} }
if (!$fp) {
$fp = file_open_lock("$base-" . rand_string()); // Check proper URL parts.
if (isset($parts['user']) || isset($parts['pass']) || isset($parts['query']) || isset($parts['fragment'])) {
auth_error(lang('Invalid server or credentials.'));
} }
// Allow only HTTP/S scheme.
if (isset($parts['scheme']) && !preg_match('~^(https?)$~i', $parts['scheme'])) {
auth_error(lang('Invalid server or credentials.'));
}
// Note that "localhost" and IP address without a scheme is parsed as a path.
$hostPath = (isset($parts['host']) ? $parts['host'] : '') . (isset($parts['path']) ? $parts['path'] : '');
// Validate host.
if (!is_server_host_valid($hostPath)) {
auth_error(lang('Invalid server or credentials.'));
}
// Check privileged ports.
if (isset($parts['port']) && ($parts['port'] < 1024 || $parts['port'] > 65535)) {
auth_error(lang('Connecting to privileged ports is not allowed.'));
}
}
if (!function_exists('is_server_host_valid')) {
/**
* @param string $hostPath
* @return bool
*/
function is_server_host_valid($hostPath)
{
return strpos($hostPath, '/') === false;
}
}
/**
* @param string $server
* @param string $username
* @param string $password
* @param string $defaultServer
* @param int|null $defaultPort
* @return string
*/
function build_http_url($server, $username, $password, $defaultServer, $defaultPort = null) {
if (!preg_match('~^(https?://)?([^:]*)(:\d+)?$~', rtrim($server, '/'), $matches)) {
$this->error = lang('Invalid server or credentials.');
return false;
}
return ($matches[1] ?: "http://") .
($username !== "" || $password !== "" ? "$username:$password@" : "") .
($matches[2] !== "" ? $matches[2] : $defaultServer) .
(isset($matches[3]) ? $matches[3] : ($defaultPort ? ":$defaultPort" : ""));
}
function add_invalid_login() {
global $adminer;
$fp = file_open_lock(get_temp_dir() . "/adminer.invalid");
if (!$fp) { if (!$fp) {
return; return;
} }
@@ -33,7 +95,7 @@ function add_invalid_login(): void {
} }
} }
} }
$invalid = &$invalids[adminer()->bruteForceKey()]; $invalid = &$invalids[$adminer->bruteForceKey()];
if (!$invalid) { if (!$invalid) {
$invalid = array($time + 30*60, 0); // active for 30 minutes $invalid = array($time + 30*60, 0); // active for 30 minutes
} }
@@ -41,22 +103,13 @@ function add_invalid_login(): void {
file_write_unlock($fp, serialize($invalids)); file_write_unlock($fp, serialize($invalids));
} }
/** @param string[] $permanent */ function check_invalid_login() {
function check_invalid_login(array &$permanent): void { global $adminer;
$invalids = array(); $invalids = unserialize(@file_get_contents(get_temp_dir() . "/adminer.invalid")); // @ - may not exist
foreach (glob(get_temp_dir() . "/adminer.invalid*") as $filename) { $invalid = ($invalids ? $invalids[$adminer->bruteForceKey()] : array());
$fp = file_open_lock($filename);
if ($fp) {
$invalids = unserialize(stream_get_contents($fp));
file_unlock($fp);
break;
}
}
/** @var array{int, int} */
$invalid = idx($invalids, adminer()->bruteForceKey(), array());
$next_attempt = ($invalid[1] > 29 ? $invalid[0] - time() : 0); // allow 30 invalid attempts $next_attempt = ($invalid[1] > 29 ? $invalid[0] - time() : 0); // allow 30 invalid attempts
if ($next_attempt > 0) { //! do the same with permanent login if ($next_attempt > 0) { //! do the same with permanent login
auth_error(lang('Too many unsuccessful logins, try again in %d minute(s).', ceil($next_attempt / 60)), $permanent); auth_error(lang('Too many unsuccessful logins, try again in %d minute(s).', ceil($next_attempt / 60)));
} }
} }
@@ -64,20 +117,19 @@ $auth = $_POST["auth"];
if ($auth) { if ($auth) {
session_regenerate_id(); // defense against session fixation session_regenerate_id(); // defense against session fixation
$vendor = $auth["driver"]; $vendor = $auth["driver"];
$server = $auth["server"]; $server = trim($auth["server"]);
$username = $auth["username"]; $username = $auth["username"];
$password = (string) $auth["password"]; $password = (string) $auth["password"];
$db = $auth["db"]; $db = $auth["db"];
set_password($vendor, $server, $username, $password); set_password($vendor, $server, $username, $password);
$_SESSION["db"][$vendor][$server][$username][$db] = true; $_SESSION["db"][$vendor][$server][$username][$db] = true;
if ($auth["permanent"]) { if ($auth["permanent"]) {
$key = implode("-", array_map('base64_encode', array($vendor, $server, $username, $db))); $key = base64_encode($vendor) . "-" . base64_encode($server) . "-" . base64_encode($username) . "-" . base64_encode($db);
$private = adminer()->permanentLogin(true); $private = $adminer->permanentLogin(true);
$permanent[$key] = "$key:" . base64_encode($private ? encrypt_string($password, $private) : ""); $permanent[$key] = "$key:" . base64_encode($private ? encrypt_string($password, $private) : "");
cookie("adminer_permanent", implode(" ", $permanent)); cookie("adminer_permanent", implode(" ", $permanent));
} }
if ( if (count($_POST) == 1 // 1 - auth
count($_POST) == 1 // 1 - auth
|| DRIVER != $vendor || DRIVER != $vendor
|| SERVER != $server || SERVER != $server
|| $_GET["username"] !== $username // "0" == "00" || $_GET["username"] !== $username // "0" == "00"
@@ -86,16 +138,16 @@ if ($auth) {
redirect(auth_url($vendor, $server, $username, $db)); redirect(auth_url($vendor, $server, $username, $db));
} }
} elseif ($_POST["logout"] && (!$_SESSION["token"] || verify_token())) { } elseif ($_POST["logout"] && (!$has_token || verify_token())) {
foreach (array("pwds", "db", "dbs", "queries") as $key) { foreach (array("pwds", "db", "dbs", "queries") as $key) {
set_session($key, null); set_session($key, null);
} }
unset_permanent($permanent); unset_permanent();
redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.') . ' ' . lang('Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.')); redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.') . ' ' . lang('Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.'));
} elseif ($permanent && !$_SESSION["pwds"]) { } elseif ($permanent && !$_SESSION["pwds"]) {
session_regenerate_id(); session_regenerate_id();
$private = adminer()->permanentLogin(); $private = $adminer->permanentLogin();
foreach ($permanent as $key => $val) { foreach ($permanent as $key => $val) {
list(, $cipher) = explode(":", $val); list(, $cipher) = explode(":", $val);
list($vendor, $server, $username, $db) = array_map('base64_decode', explode("-", $key)); list($vendor, $server, $username, $db) = array_map('base64_decode', explode("-", $key));
@@ -104,10 +156,8 @@ if ($auth) {
} }
} }
/** Remove credentials from permanent login function unset_permanent() {
* @param string[] $permanent global $permanent;
*/
function unset_permanent(array &$permanent): void {
foreach ($permanent as $key => $val) { foreach ($permanent as $key => $val) {
list($vendor, $server, $username, $db) = array_map('base64_decode', explode("-", $key)); list($vendor, $server, $username, $db) = array_map('base64_decode', explode("-", $key));
if ($vendor == DRIVER && $server == SERVER && $username == $_GET["username"] && $db == DB) { if ($vendor == DRIVER && $server == SERVER && $username == $_GET["username"] && $db == DB) {
@@ -117,16 +167,16 @@ function unset_permanent(array &$permanent): void {
cookie("adminer_permanent", implode(" ", $permanent)); cookie("adminer_permanent", implode(" ", $permanent));
} }
/** Render an error message and a login form /** Renders an error message and a login form
* @param string $error plain text * @param string plain text
* @param string[] $permanent * @return null exits
* @return never
*/ */
function auth_error(string $error, array &$permanent) { function auth_error($error) {
global $adminer, $has_token;
$session_name = session_name(); $session_name = session_name();
if (isset($_GET["username"])) { if (isset($_GET["username"])) {
header("HTTP/1.1 403 Forbidden"); // 401 requires sending WWW-Authenticate header header("HTTP/1.1 403 Forbidden"); // 401 requires sending WWW-Authenticate header
if (($_COOKIE[$session_name] || $_GET[$session_name]) && !$_SESSION["token"]) { if (($_COOKIE[$session_name] || $_GET[$session_name]) && !$has_token) {
$error = lang('Session expired, please login again.'); $error = lang('Session expired, please login again.');
} else { } else {
restart_session(); restart_session();
@@ -138,17 +188,14 @@ function auth_error(string $error, array &$permanent) {
} }
set_password(DRIVER, SERVER, $_GET["username"], null); set_password(DRIVER, SERVER, $_GET["username"], null);
} }
unset_permanent($permanent); unset_permanent();
} }
} }
if (!$_COOKIE[$session_name] && $_GET[$session_name] && ini_bool("session.use_only_cookies")) { if (!$_COOKIE[$session_name] && $_GET[$session_name] && ini_bool("session.use_only_cookies")) {
$error = lang('Session support must be enabled.'); $error = lang('Session support must be enabled.');
} }
$params = session_get_cookie_params(); $params = session_get_cookie_params();
cookie("adminer_key", ($_COOKIE["adminer_key"] ?: rand_string()), $params["lifetime"]); cookie("adminer_key", ($_COOKIE["adminer_key"] ? $_COOKIE["adminer_key"] : rand_string()), $params["lifetime"]);
if (!$_SESSION["token"]) {
$_SESSION["token"] = rand(1, 1e6); // this is for next attempt
}
page_header(lang('Login'), $error, null); page_header(lang('Login'), $error, null);
echo "<form action='' method='post'>\n"; echo "<form action='' method='post'>\n";
echo "<div>"; echo "<div>";
@@ -156,57 +203,44 @@ function auth_error(string $error, array &$permanent) {
echo "<p class='message'>" . lang('The action will be performed after successful login with the same credentials.') . "\n"; echo "<p class='message'>" . lang('The action will be performed after successful login with the same credentials.') . "\n";
} }
echo "</div>\n"; echo "</div>\n";
adminer()->loginForm(); $adminer->loginForm();
echo "</form>\n"; echo "</form>\n";
page_footer("auth"); page_footer("auth");
exit; exit;
} }
if (isset($_GET["username"]) && !class_exists('Adminer\Db')) { if (isset($_GET["username"]) && !class_exists("Min_DB")) {
unset($_SESSION["pwds"][DRIVER]); unset($_SESSION["pwds"][DRIVER]);
unset_permanent($permanent); unset_permanent();
page_header(lang('No extension'), lang('None of the supported PHP extensions (%s) are available.', implode(", ", Driver::$extensions)), false); page_header(lang('No extension'), lang('None of the supported PHP extensions (%s) are available.', implode(", ", $possible_drivers)), false);
page_footer("auth"); page_footer("auth");
exit; exit;
} }
$connection = ''; stop_session(true);
if (isset($_GET["username"]) && is_string(get_password())) { if (isset($_GET["username"]) && is_string(get_password())) {
list($host, $port) = explode(":", SERVER, 2); validate_server_input();
if (preg_match('~^\s*([-+]?\d+)~', $port, $match) && ($match[1] < 1024 || $match[1] > 65535)) { // is_numeric('80#') would still connect to port 80 check_invalid_login();
auth_error(lang('Connecting to privileged ports is not allowed.'), $permanent);
} $connection = connect();
check_invalid_login($permanent); $driver = new Min_Driver($connection);
$credentials = adminer()->credentials();
$connection = Driver::connect($credentials[0], $credentials[1], $credentials[2]);
if (is_object($connection)) {
Db::$instance = $connection;
Driver::$instance = new Driver($connection);
if ($connection->flavor) {
save_settings(array("vendor-" . DRIVER . "-" . SERVER => get_driver(DRIVER)));
}
}
} }
$login = null; $login = null;
if (!is_object($connection) || ($login = adminer()->login($_GET["username"], get_password())) !== true) { if (!is_object($connection) || ($login = $adminer->login($_GET["username"], get_password())) !== true) {
$error = (is_string($connection) ? nl_br(h($connection)) : (is_string($login) ? $login : lang('Invalid credentials.'))) $error = (is_string($connection) ? h($connection) : (is_string($login) ? $login : lang('Invalid server or credentials.')));
. (preg_match('~^ | $~', get_password()) ? '<br>' . lang('There is a space in the input password which might be the cause.') : ''); auth_error($error . (preg_match('~^ | $~', get_password()) ? '<br>' . lang('There is a space in the input password which might be the cause.') : ''));
auth_error($error, $permanent);
} }
if ($_POST["logout"] && $_SESSION["token"] && !verify_token()) { if ($_POST["logout"] && $has_token && !verify_token()) {
page_header(lang('Logout'), lang('Invalid CSRF token. Send the form again.')); page_header(lang('Logout'), lang('Invalid CSRF token. Send the form again.'));
page_footer("db"); page_footer("db");
exit; exit;
} }
if (!$_SESSION["token"]) {
$_SESSION["token"] = rand(1, 1e6); // defense against cross-site request forgery
}
stop_session(true);
if ($auth && $_POST["token"]) { if ($auth && $_POST["token"]) {
$_POST["token"] = get_token(); // reset token after explicit login $_POST["token"] = $token; // reset token after explicit login
} }
$error = ''; ///< @var string $error = ''; ///< @var string

View File

@@ -1,9 +1,11 @@
<?php <?php
namespace Adminer; function adminer_errors($errno, $errstr) {
return !!preg_match('~^(Trying to access array offset on value of type null|Undefined array key)~', $errstr);
}
error_reporting(6135); // errors and warnings
set_error_handler('adminer_errors', E_WARNING);
include "../adminer/include/version.inc.php";
include "../adminer/include/errors.inc.php";
// this is matched by compile.php
include "../adminer/include/coverage.inc.php"; include "../adminer/include/coverage.inc.php";
// disable filter.default // disable filter.default
@@ -22,7 +24,6 @@ if (function_exists("mb_internal_encoding")) {
} }
include "../adminer/include/functions.inc.php"; include "../adminer/include/functions.inc.php";
include "../adminer/include/html.inc.php";
// used only in compiled file // used only in compiled file
if (isset($_GET["file"])) { if (isset($_GET["file"])) {
@@ -30,16 +31,14 @@ if (isset($_GET["file"])) {
} }
if ($_GET["script"] == "version") { if ($_GET["script"] == "version") {
$filename = get_temp_dir() . "/adminer.version"; $fp = file_open_lock(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) { if ($fp) {
file_write_unlock($fp, serialize(array("signature" => $_POST["signature"], "version" => $_POST["version"]))); file_write_unlock($fp, serialize(array("signature" => $_POST["signature"], "version" => $_POST["version"])));
} }
exit; exit;
} }
// Adminer doesn't use any global variables; they used to be declared here global $adminer, $connection, $driver, $drivers, $edit_functions, $enum_length, $error, $functions, $grouping, $HTTPS, $inout, $jush, $LANG, $langs, $on_actions, $permanent, $structured_types, $has_token, $token, $translations, $types, $unsigned, $VERSION; // allows including Adminer inside a function
if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility
$_SERVER["REQUEST_URI"] = $_SERVER["ORIG_PATH_INFO"]; $_SERVER["REQUEST_URI"] = $_SERVER["ORIG_PATH_INFO"];
@@ -50,13 +49,17 @@ if (!strpos($_SERVER["REQUEST_URI"], '?') && $_SERVER["QUERY_STRING"] != "") { /
if ($_SERVER["HTTP_X_FORWARDED_PREFIX"]) { if ($_SERVER["HTTP_X_FORWARDED_PREFIX"]) {
$_SERVER["REQUEST_URI"] = $_SERVER["HTTP_X_FORWARDED_PREFIX"] . $_SERVER["REQUEST_URI"]; $_SERVER["REQUEST_URI"] = $_SERVER["HTTP_X_FORWARDED_PREFIX"] . $_SERVER["REQUEST_URI"];
} }
define('Adminer\HTTPS', ($_SERVER["HTTPS"] && strcasecmp($_SERVER["HTTPS"], "off")) || ini_bool("session.cookie_secure")); // session.cookie_secure could be set on HTTP if we are behind a reverse proxy $HTTPS = ($_SERVER["HTTPS"] && strcasecmp($_SERVER["HTTPS"], "off")) || ini_bool("session.cookie_secure"); // session.cookie_secure could be set on HTTP if we are behind a reverse proxy
@ini_set("session.use_trans_sid", '0'); // protect links in export, @ - may be disabled @ini_set("session.use_trans_sid", false); // protect links in export, @ - may be disabled
if (!defined("SID")) { if (!defined("SID")) {
session_cache_limiter(""); // to allow restarting session session_cache_limiter(""); // to allow restarting session
session_name("adminer_sid"); // use specific session name to get own namespace session_name("adminer_sid"); // use specific session name to get own namespace
session_set_cookie_params(0, preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"]), "", HTTPS, true); // ini_set() may be disabled $params = array(0, preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"]), "", $HTTPS);
if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
$params[] = true; // HttpOnly
}
call_user_func_array('session_set_cookie_params', $params); // ini_set() may be disabled
session_start(); session_start();
} }
@@ -66,46 +69,50 @@ if (function_exists("get_magic_quotes_runtime") && get_magic_quotes_runtime()) {
set_magic_quotes_runtime(false); set_magic_quotes_runtime(false);
} }
@set_time_limit(0); // @ - can be disabled @set_time_limit(0); // @ - can be disabled
@ini_set("precision", '15'); // @ - can be disabled, 15 - internal PHP precision @ini_set("zend.ze1_compatibility_mode", false); // @ - deprecated
@ini_set("precision", 15); // @ - can be disabled, 15 - internal PHP precision
include "../adminer/include/lang.inc.php"; include "../adminer/include/lang.inc.php";
include "../adminer/lang/" . LANG . ".inc.php"; include "../adminer/lang/$LANG.inc.php";
include "../adminer/include/db.inc.php";
include "../adminer/include/pdo.inc.php"; include "../adminer/include/pdo.inc.php";
include "../adminer/include/driver.inc.php"; include "../adminer/include/driver.inc.php";
include "../adminer/drivers/sqlite.inc.php"; include "../adminer/drivers/sqlite.inc.php";
include "../adminer/drivers/pgsql.inc.php"; include "../adminer/drivers/pgsql.inc.php";
include "../adminer/drivers/oracle.inc.php"; include "../adminer/drivers/oracle.inc.php";
include "../adminer/drivers/mssql.inc.php"; include "../adminer/drivers/mssql.inc.php";
include "../adminer/drivers/mongo.inc.php";
include "./include/adminer.inc.php"; include "./include/adminer.inc.php";
include "../adminer/include/plugins.inc.php"; $adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
if (function_exists('adminer_object')) {
Adminer::$instance = adminer_object();
} elseif (is_dir("adminer-plugins") || file_exists("adminer-plugins.php")) {
Adminer::$instance = new Plugins(null);
} else {
Adminer::$instance = new Adminer;
}
// this is matched by compile.php
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver include "../adminer/drivers/mysql.inc.php"; // must be included as last driver
define('Adminer\JUSH', Driver::$jush); $config = driver_config();
define('Adminer\SERVER', $_GET[DRIVER]); // read from pgsql=localhost, '' means default server, null means no server $possible_drivers = $config['possible_drivers'];
define('Adminer\DB', $_GET["db"]); // for the sake of speed and size $jush = $config['jush'];
define( $types = $config['types'];
'Adminer\ME', $structured_types = $config['structured_types'];
preg_replace('~\?.*~', '', relative_uri()) . '?' $unsigned = $config['unsigned'];
$operators = $config['operators'];
$functions = $config['functions'];
$grouping = $config['grouping'];
$edit_functions = $config['edit_functions'];
if ($adminer->operators === null) {
$adminer->operators = $operators;
}
define("SERVER", $_GET[DRIVER]); // read from pgsql=localhost
define("DB", $_GET["db"]); // for the sake of speed and size
define("ME", preg_replace('~\?.*~', '', relative_uri()) . '?'
. (sid() ? SID . '&' : '') . (sid() ? SID . '&' : '')
. (SERVER !== null ? DRIVER . "=" . urlencode(SERVER) . '&' : '') . (SERVER !== null ? DRIVER . "=" . urlencode(SERVER) . '&' : '')
. ($_GET["ext"] ? "ext=" . urlencode($_GET["ext"]) . '&' : '')
. (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '') . (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '')
. (DB != "" ? 'db=' . urlencode(DB) . '&' . (isset($_GET["ns"]) ? "ns=" . urlencode($_GET["ns"]) . "&" : "") : '') . (DB != "" ? 'db=' . urlencode(DB) . '&' . (isset($_GET["ns"]) ? "ns=" . urlencode($_GET["ns"]) . "&" : "") : '')
); );
include "../adminer/include/version.inc.php";
include "../adminer/include/design.inc.php"; include "../adminer/include/design.inc.php";
include "../adminer/include/xxtea.inc.php"; include "../adminer/include/xxtea.inc.php";
include "../adminer/include/auth.inc.php"; include "../adminer/include/auth.inc.php";
include "./include/editing.inc.php"; include "./include/editing.inc.php";
include "./include/connect.inc.php"; include "./include/connect.inc.php";
$on_actions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; ///< @var string used in foreign_keys()

View File

@@ -1,24 +1,6 @@
<?php <?php
namespace Adminer; function connect_error() {
global $adminer, $connection, $token, $error, $drivers;
if (isset($_GET["status"])) {
$_GET["variables"] = $_GET["status"];
}
if (isset($_GET["import"])) {
$_GET["sql"] = $_GET["import"];
}
if (
!(DB != ""
? connection()->select_db(DB)
: isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]) || isset($_GET["variables"])
|| $_GET["script"] == "connect" || $_GET["script"] == "kill"
)
) {
if (DB != "" || $_GET["refresh"]) {
restart_session();
set_session("dbs", null);
}
if (DB != "") { if (DB != "") {
header("HTTP/1.1 404 Not Found"); header("HTTP/1.1 404 Not Found");
page_header(lang('Database') . ": " . h(DB), lang('Invalid database.'), true); page_header(lang('Database') . ": " . h(DB), lang('Invalid database.'), true);
@@ -29,39 +11,29 @@ if (
page_header(lang('Select database'), $error, false); page_header(lang('Select database'), $error, false);
echo "<p class='links'>\n"; echo "<p class='links'>\n";
foreach ( foreach (array(
array(
'database' => lang('Create database'), 'database' => lang('Create database'),
'privileges' => lang('Privileges'), 'privileges' => lang('Privileges'),
'processlist' => lang('Process list'), 'processlist' => lang('Process list'),
'variables' => lang('Variables'), 'variables' => lang('Variables'),
'status' => lang('Status'), 'status' => lang('Status'),
) as $key => $val ) as $key => $val) {
) {
if (support($key)) { if (support($key)) {
echo "<a href='" . h(ME) . "$key='>$val</a>\n"; echo "<a href='" . h(ME) . "$key='>$val</a>\n";
} }
} }
echo "<p>" . lang('%s version: %s through PHP extension %s', get_driver(DRIVER), "<b>" . h(connection()->server_info) . "</b>", "<b>" . connection()->extension . "</b>") . "\n"; 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"; echo "<p>" . lang('Logged as: %s', "<b>" . h(logged_user()) . "</b>") . "\n";
if (isset(adminer()->plugins) && is_array(adminer()->plugins)) { $databases = $adminer->databases();
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) { if ($databases) {
$scheme = support("scheme"); $scheme = support("scheme");
$collations = collations(); $collations = collations();
echo "<form action='' method='post'>\n"; echo "<form action='' method='post'>\n";
echo "<table class='checkable odds'>\n"; echo "<table cellspacing='0' class='checkable'>\n";
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});"); echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
echo "<thead><tr>" echo "<thead><tr>"
. (support("database") ? "<td>" : "") . (support("database") ? "<td>" : "")
. "<th>" . lang('Database') . (get_session("dbs") !== null ? " - <a href='" . h(ME) . "refresh=1'>" . lang('Refresh') . "</a>" : "") . "<th>" . lang('Database') . " - <a href='" . h(ME) . "refresh=1'>" . lang('Refresh') . "</a>"
. "<td>" . lang('Collation') . "<td>" . lang('Collation')
. "<td>" . lang('Tables') . "<td>" . lang('Tables')
. "<td>" . lang('Size') . " - <a href='" . h(ME) . "dbsize=1'>" . lang('Compute') . "</a>" . script("qsl('a').onclick = partial(ajaxSetHtml, '" . js_escape(ME) . "script=connect');", "") . "<td>" . lang('Size') . " - <a href='" . h(ME) . "dbsize=1'>" . lang('Compute') . "</a>" . script("qsl('a').onclick = partial(ajaxSetHtml, '" . js_escape(ME) . "script=connect');", "")
@@ -73,7 +45,7 @@ if (
foreach ($databases as $db => $tables) { foreach ($databases as $db => $tables) {
$root = h(ME) . "db=" . urlencode($db); $root = h(ME) . "db=" . urlencode($db);
$id = h("Db-" . $db); $id = h("Db-" . $db);
echo "<tr>" . (support("database") ? "<td>" . checkbox("db[]", $db, in_array($db, (array) $_POST["db"]), "", "", "", $id) : ""); echo "<tr" . odd() . ">" . (support("database") ? "<td>" . checkbox("db[]", $db, in_array($db, (array) $_POST["db"]), "", "", "", $id) : "");
echo "<th><a href='$root' id='$id'>" . h($db) . "</a>"; echo "<th><a href='$root' id='$id'>" . h($db) . "</a>";
$collation = h(db_collation($db, $collations)); $collation = h(db_collation($db, $collations));
echo "<td>" . (support("database") ? "<a href='$root" . ($scheme ? "&amp;ns=" : "") . "&amp;database=' title='" . lang('Alter database') . "'>$collation</a>" : $collation); echo "<td>" . (support("database") ? "<a href='$root" . ($scheme ? "&amp;ns=" : "") . "&amp;database=' title='" . lang('Alter database') . "'>$collation</a>" : $collation);
@@ -86,19 +58,34 @@ if (
echo (support("database") echo (support("database")
? "<div class='footer'><div>\n" ? "<div class='footer'><div>\n"
. "<fieldset><legend>" . lang('Selected') . " <span id='selected'></span></legend><div>\n" . "<fieldset><legend>" . lang('Selected') . " <span id='selected'></span></legend><div>\n"
. input_hidden("all") . script("qsl('input').onclick = function () { selectCount('selected', formChecked(this, /^db/)); };") // used by trCheck() . "<input type='hidden' name='all' value=''>" . script("qsl('input').onclick = function () { selectCount('selected', formChecked(this, /^db/)); };") // used by trCheck()
. "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm() . "\n" . "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm() . "\n"
. "</div></fieldset>\n" . "</div></fieldset>\n"
. "</div></div>\n" . "</div></div>\n"
: "" : ""
); );
echo input_token(); echo "<input type='hidden' name='token' value='$token'>\n";
echo "</form>\n"; echo "</form>\n";
echo script("tableCheck();"); echo script("tableCheck();");
} }
} }
page_footer("db"); page_footer("db");
}
if (isset($_GET["status"])) {
$_GET["variables"] = $_GET["status"];
}
if (isset($_GET["import"])) {
$_GET["sql"] = $_GET["import"];
}
if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]) || isset($_GET["variables"]) || $_GET["script"] == "connect" || $_GET["script"] == "kill")) {
if (DB != "" || $_GET["refresh"]) {
restart_session();
set_session("dbs", null);
}
connect_error(); // separate function to catch SQLite error
exit; exit;
} }

View File

@@ -1,14 +1,12 @@
<?php <?php
namespace Adminer;
// coverage is used in tests and removed in compilation // coverage is used in tests and removed in compilation
if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer.coverage")) { if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer_coverage.ser")) {
function save_coverage(): void { function save_coverage() {
$coverage_filename = sys_get_temp_dir() . "/adminer.coverage"; $coverage_filename = sys_get_temp_dir() . "/adminer_coverage.ser";
$coverage = unserialize(file_get_contents($coverage_filename)); $coverage = unserialize(file_get_contents($coverage_filename));
foreach (xdebug_get_code_coverage() as $filename => $lines) { foreach (xdebug_get_code_coverage() as $filename => $lines) {
foreach ($lines as $l => $val) { foreach ($lines as $l => $val) {
if (!idx($coverage[$filename], $l) || $val > 0) { if (!$coverage[$filename][$l] || $val > 0) {
$coverage[$filename][$l] = $val; $coverage[$filename][$l] = $val;
} }
} }
@@ -16,5 +14,5 @@ if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer.cov
} }
} }
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
register_shutdown_function('Adminer\save_coverage'); register_shutdown_function('save_coverage');
} }

View File

@@ -1,56 +0,0 @@
<?php
namespace Adminer;
// this could be interface when "Db extends \mysqli" can have compatible type declarations (PHP 7)
// interfaces can include properties only since PHP 8.4
abstract class SqlDb {
/** @var Db */ static $instance;
public string $extension; // extension name
public string $flavor = ''; // different vendor with the same API, e.g. MariaDB; usually stays empty
public string $server_info; // server version
public int $affected_rows = 0; // number of affected rows
public string $info = ''; // see https://php.net/mysql_info
public int $errno = 0; // last error code
public string $error = ''; // last error message
/** @var Result|bool */ protected $multi; // used for multiquery
/** Connect to server
* @return string error message
*/
abstract function attach(?string $server, string $username, string $password): string;
/** Quote string to use in SQL
* @return string escaped string enclosed in '
*/
abstract function quote(string $string): string;
/** Select database
* @return bool boolish
*/
abstract function select_db(string $database);
/** Send query
* @return Result|bool
*/
abstract function query(string $query, bool $unbuffered = false);
/** Send query with more resultsets
* @return Result|bool
*/
function multi_query(string $query) {
return $this->multi = $this->query($query);
}
/** Get current resultset
* @return Result|bool
*/
function store_result() {
return $this->multi;
}
/** Fetch next resultset */
function next_result(): bool {
return false;
}
}

View File

@@ -1,63 +1,39 @@
<?php <?php
namespace Adminer;
/** Print HTML header /** Print HTML header
* @param string $title used in title, breadcrumb and heading, should be HTML escaped * @param string used in title, breadcrumb and heading, should be HTML escaped
* @param mixed $breadcrumb ["key" => "link", "key2" => ["link", "desc"]], null for nothing, false for driver only, true for driver and server * @param string
* @param string $title2 used after colon in title and heading, should be HTML escaped * @param mixed array("key" => "link", "key2" => array("link", "desc")), null for nothing, false for driver only, true for driver and server
* @param string used after colon in title and heading, should be HTML escaped
* @return null
*/ */
function page_header(string $title, string $error = "", $breadcrumb = array(), string $title2 = ""): void { function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
global $LANG, $VERSION, $adminer, $drivers, $jush;
page_headers(); page_headers();
if (is_ajax() && $error) { if (is_ajax() && $error) {
page_messages($error); page_messages($error);
exit; exit;
} }
if (!ob_get_level()) {
ob_start(null, 4096);
}
$title_all = $title . ($title2 != "" ? ": $title2" : ""); $title_all = $title . ($title2 != "" ? ": $title2" : "");
$title_page = strip_tags($title_all . (SERVER != "" && SERVER != "localhost" ? h(" - " . SERVER) : "") . " - " . adminer()->name()); $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> <!DOCTYPE html>
<html lang="<?php echo LANG; ?>" dir="<?php echo lang('ltr'); ?>"> <html lang="<?php echo $LANG; ?>" dir="<?php echo lang('ltr'); ?>">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="robots" content="noindex"> <meta name="robots" content="noindex">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title><?php echo $title_page; ?></title> <title><?php echo $title_page; ?></title>
<link rel="stylesheet" href="../adminer/static/default.css"> <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">
<?php <?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"; $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 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)); $version = unserialize(file_get_contents($filename));
@@ -75,38 +51,42 @@ fQIDAQAB
$_COOKIE["adminer_version"] = $version["version"]; // doesn't need to send to the browser $_COOKIE["adminer_version"] = $version["version"]; // doesn't need to send to the browser
} }
} }
echo script("mixin(document.body, {onkeydown: bodyKeydown, onclick: bodyClick" ?>
. (isset($_COOKIE["adminer_version"]) ? "" : ", onload: partial(verifyVersion, '" . VERSION . "', '" . js_escape(ME) . "', '" . get_token() . "')") <script<?php echo nonce(); ?>>
. "}); mixin(document.body, {onkeydown: bodyKeydown, onclick: bodyClick<?php
document.body.classList.replace('nojs', 'js'); echo (isset($_COOKIE["adminer_version"]) ? "" : ", onload: partial(verifyVersion, '$VERSION', '" . js_escape(ME) . "', '" . get_token() . "')"); // $token may be empty in auth.inc.php
const offlineMessage = '" . js_escape(lang('You are offline.')) . "'; ?>});
const thousandsSeparator = '" . js_escape(lang(',')) . "';") document.body.className = document.body.className.replace(/ nojs/, ' js');
; var offlineMessage = '<?php echo js_escape(lang('You are offline.')); ?>';
echo "<div id='help' class='jush-" . JUSH . " jsonly hidden'></div>\n"; var thousandsSeparator = '<?php echo js_escape(lang(',')); ?>';
echo script("mixin(qs('#help'), {onmouseover: () => { helpOpen = 1; }, onmouseout: helpMouseout});"); </script>
echo "<div id='content'>\n";
echo "<span id='menuopen' class='jsonly'>" . icon("move", "", "menu", "") . "</span>" . script("qs('#menuopen').onclick = event => { qs('#foot').classList.toggle('foot'); event.stopPropagation(); }"); <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
if ($breadcrumb !== null) { if ($breadcrumb !== null) {
$link = substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1); $link = substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1);
echo '<p id="breadcrumb"><a href="' . h($link ?: ".") . '">' . get_driver(DRIVER) . '</a> » '; echo '<p id="breadcrumb"><a href="' . h($link ? $link : ".") . '">' . $drivers[DRIVER] . '</a> &raquo; ';
$link = substr(preg_replace('~\b(db|ns)=[^&]*&~', '', ME), 0, -1); $link = substr(preg_replace('~\b(db|ns)=[^&]*&~', '', ME), 0, -1);
$server = adminer()->serverName(SERVER); $server = $adminer->serverName(SERVER);
$server = ($server != "" ? $server : lang('Server')); $server = ($server != "" ? $server : lang('Server'));
if ($breadcrumb === false) { if ($breadcrumb === false) {
echo "$server\n"; echo "$server\n";
} else { } else {
echo "<a href='" . h($link) . "' accesskey='1' title='Alt+Shift+1'>$server</a> » "; echo "<a href='" . h($link) . "' accesskey='1' title='Alt+Shift+1'>$server</a> &raquo; ";
if ($_GET["ns"] != "" || (DB != "" && is_array($breadcrumb))) { if ($_GET["ns"] != "" || (DB != "" && is_array($breadcrumb))) {
echo '<a href="' . h($link . "&db=" . urlencode(DB) . (support("scheme") ? "&ns=" : "")) . '">' . h(DB) . '</a> » '; echo '<a href="' . h($link . "&db=" . urlencode(DB) . (support("scheme") ? "&ns=" : "")) . '">' . h(DB) . '</a> &raquo; ';
} }
if (is_array($breadcrumb)) { if (is_array($breadcrumb)) {
if ($_GET["ns"] != "") { if ($_GET["ns"] != "") {
echo '<a href="' . h(substr(ME, 0, -1)) . '">' . h($_GET["ns"]) . '</a> » '; echo '<a href="' . h(substr(ME, 0, -1)) . '">' . h($_GET["ns"]) . '</a> &raquo; ';
} }
foreach ($breadcrumb as $key => $val) { foreach ($breadcrumb as $key => $val) {
$desc = (is_array($val) ? $val[1] : h($val)); $desc = (is_array($val) ? $val[1] : h($val));
if ($desc != "") { if ($desc != "") {
echo "<a href='" . h(ME . "$key=") . urlencode(is_array($val) ? $val[0] : $val) . "'>$desc</a> » "; echo "<a href='" . h(ME . "$key=") . urlencode(is_array($val) ? $val[0] : $val) . "'>$desc</a> &raquo; ";
} }
} }
} }
@@ -122,31 +102,34 @@ const thousandsSeparator = '" . js_escape(lang(',')) . "';")
$databases = null; $databases = null;
} }
stop_session(); stop_session();
define('Adminer\PAGE_HEADER', 1); define("PAGE_HEADER", 1);
} }
/** Send HTTP headers */ /** Send HTTP headers
function page_headers(): void { * @return null
*/
function page_headers() {
global $adminer;
header("Content-Type: text/html; charset=utf-8"); header("Content-Type: text/html; charset=utf-8");
header("Cache-Control: no-cache"); header("Cache-Control: no-cache");
header("X-Frame-Options: deny"); // ClickJacking protection in IE8, Safari 4, Chrome 2, Firefox 3.6.9 header("X-Frame-Options: deny"); // ClickJacking protection in IE8, Safari 4, Chrome 2, Firefox 3.6.9
header("X-XSS-Protection: 0"); // prevents introducing XSS in IE8 by removing safe parts of the page header("X-XSS-Protection: 0"); // prevents introducing XSS in IE8 by removing safe parts of the page
header("X-Content-Type-Options: nosniff"); header("X-Content-Type-Options: nosniff");
header("Referrer-Policy: origin-when-cross-origin"); header("Referrer-Policy: origin-when-cross-origin");
foreach (adminer()->csp(csp()) as $csp) { foreach ($adminer->csp() as $csp) {
$header = array(); $header = array();
foreach ($csp as $key => $val) { foreach ($csp as $key => $val) {
$header[] = "$key $val"; $header[] = "$key $val";
} }
header("Content-Security-Policy: " . implode("; ", $header)); header("Content-Security-Policy: " . implode("; ", $header));
} }
adminer()->headers(); $adminer->headers();
} }
/** Get Content Security Policy headers /** Get Content Security Policy headers
* @return list<string[]> of arrays with directive name in key, allowed sources in value * @return array of arrays with directive name in key, allowed sources in value
*/ */
function csp(): array { function csp() {
return array( return array(
array( array(
"script-src" => "'self' 'unsafe-inline' 'nonce-" . get_nonce() . "' 'strict-dynamic'", // 'self' is a fallback for browsers not supporting 'strict-dynamic', 'unsafe-inline' is a fallback for browsers not supporting 'nonce-' "script-src" => "'self' 'unsafe-inline' 'nonce-" . get_nonce() . "' 'strict-dynamic'", // 'self' is a fallback for browsers not supporting 'strict-dynamic', 'unsafe-inline' is a fallback for browsers not supporting 'nonce-'
@@ -162,7 +145,7 @@ function csp(): array {
/** Get a CSP nonce /** Get a CSP nonce
* @return string Base64 value * @return string Base64 value
*/ */
function get_nonce(): string { function get_nonce() {
static $nonce; static $nonce;
if (!$nonce) { if (!$nonce) {
$nonce = base64_encode(rand_string()); $nonce = base64_encode(rand_string());
@@ -170,10 +153,13 @@ function get_nonce(): string {
return $nonce; return $nonce;
} }
/** Print flash and error messages */ /** Print flash and error messages
function page_messages(string $error): void { * @param string
* @return null
*/
function page_messages($error) {
$uri = preg_replace('~^[^?]*~', '', $_SERVER["REQUEST_URI"]); $uri = preg_replace('~^[^?]*~', '', $_SERVER["REQUEST_URI"]);
$messages = idx($_SESSION["messages"], $uri); $messages = $_SESSION["messages"][$uri];
if ($messages) { if ($messages) {
echo "<div class='message'>" . implode("</div>\n<div class='message'>", $messages) . "</div>" . script("messagesPrint();"); echo "<div class='message'>" . implode("</div>\n<div class='message'>", $messages) . "</div>" . script("messagesPrint();");
unset($_SESSION["messages"][$uri]); unset($_SESSION["messages"][$uri]);
@@ -181,28 +167,29 @@ function page_messages(string $error): void {
if ($error) { if ($error) {
echo "<div class='error'>$error</div>\n"; echo "<div class='error'>$error</div>\n";
} }
if (adminer()->error) { // separate <div>
echo "<div class='error'>" . adminer()->error . "</div>\n";
}
} }
/** Print HTML footer /** Print HTML footer
* @param ''|'auth'|'db'|'ns' $missing * @param string "auth", "db", "ns"
* @return null
*/ */
function page_footer(string $missing = ""): void { function page_footer($missing = "") {
echo "</div>\n\n<div id='foot' class='foot'>\n<div id='menu'>\n"; global $adminer, $token;
adminer()->navigation($missing);
echo "</div>\n";
if ($missing != "auth") {
?> ?>
</div>
<?php switch_lang(); ?>
<?php if ($missing != "auth") { ?>
<form action="" method="post"> <form action="" method="post">
<p class="logout"> <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="submit" name="logout" value="<?php echo lang('Logout'); ?>" id="logout">
<?php echo input_token(); ?> <input type="hidden" name="token" value="<?php echo $token; ?>">
</p>
</form> </form>
<?php } ?>
<div id="menu">
<?php $adminer->navigation($missing); ?>
</div>
<?php <?php
}
echo "</div>\n\n";
echo script("setupSubmitHighlight(document);"); echo script("setupSubmitHighlight(document);");
} }

View File

@@ -1,123 +1,78 @@
<?php <?php
namespace Adminer; $drivers = array();
/** Add or overwrite a driver */ /** Add a driver
function add_driver(string $id, string $name): void { * @param string
SqlDriver::$drivers[$id] = $name; * @param string
* @return null
*/
function add_driver($id, $name) {
global $drivers;
$drivers[$id] = $name;
} }
/** Get driver name */ /*abstract*/ class Min_SQL {
function get_driver(string $id): string { var $_conn;
return SqlDriver::$drivers[$id];
}
abstract class SqlDriver { /** Create object for performing database operations
static Driver $instance; * @param Min_DB
/** @var string[] */ static array $drivers = array(); // all available drivers
/** @var list<string> */ static array $extensions = array(); // possible extensions in the current driver
static string $jush; // JUSH identifier
protected Db $conn;
/** @var int[][] */ protected array $types = array(); // [$group => [$type => $maximum_unsigned_length, ...], ...]
/** @var string[] */ public array $insertFunctions = array(); // ["$type|$type2" => "$function/$function2"] functions used in edit and insert
/** @var string[] */ public array $editFunctions = array(); // ["$type|$type2" => "$function/$function2"] functions used in edit only
/** @var list<string> */ public array $unsigned = array(); // number variants
/** @var list<string> */ public array $operators = array(); // operators used in select
/** @var list<string> */ public array $functions = array(); // functions used in select
/** @var list<string> */ public array $grouping = array(); // grouping functions used in select
public string $onActions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; // used in foreign_keys()
public string $inout = "IN|OUT|INOUT"; // used in routines
public string $enumLength = "'(?:''|[^'\\\\]|\\\\.)*'"; // regular expression for parsing enum lengths
/** @var list<string> */ public array $generated = array(); // allowed types of generated columns
/** Connect to the database
* @return Db|string string for error
*/ */
static function connect(?string $server, string $username, string $password) { function __construct($connection) {
$connection = new Db; $this->_conn = $connection;
return ($connection->attach($server, $username, $password) ?: $connection);
}
/** Create object for performing database operations */
function __construct(Db $connection) {
$this->conn = $connection;
}
/** Get all types
* @return int[] [$type => $maximum_unsigned_length, ...]
*/
function types(): array {
return call_user_func_array('array_merge', array_values($this->types));
}
/** Get structured types
* @return list<string>[]|list<string> [$description => [$type, ...], ...]
*/
function structuredTypes(): array {
return array_map('array_keys', $this->types);
}
/** Get enum values
* @param Field $field
* @return string|void
*/
function enumLength(array $field) {
}
/** Function used to convert the value inputted by user
* @param Field $field
* @return string|void
*/
function unconvertFunction(array $field) {
} }
/** Select data from table /** Select data from table
* @param list<string> $select result of adminer()->selectColumnsProcess()[0] * @param string
* @param list<string> $where result of adminer()->selectSearchProcess() * @param array result of $adminer->selectColumnsProcess()[0]
* @param list<string> $group result of adminer()->selectColumnsProcess()[1] * @param array result of $adminer->selectSearchProcess()
* @param list<string> $order result of adminer()->selectOrderProcess() * @param array result of $adminer->selectColumnsProcess()[1]
* @param int $limit result of adminer()->selectLimitProcess() * @param array result of $adminer->selectOrderProcess()
* @param int $page index of page starting at zero * @param int result of $adminer->selectLimitProcess()
* @param bool $print whether to print the query * @param int index of page starting at zero
* @return Result|false * @param bool whether to print the query
* @return Min_Result
*/ */
function select(string $table, array $select, array $where, array $group, array $order = array(), int $limit = 1, ?int $page = 0, bool $print = false) { function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
global $adminer, $jush;
$is_group = (count($group) < count($select)); $is_group = (count($group) < count($select));
$query = adminer()->selectQueryBuild($select, $where, $group, $order, $limit, $page); $query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page);
if (!$query) { if (!$query) {
$query = "SELECT" . limit( $query = "SELECT" . limit(
($_GET["page"] != "last" && $limit && $group && $is_group && JUSH == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . implode(", ", $select) . "\nFROM " . table($table), ($_GET["page"] != "last" && $limit != "" && $group && $is_group && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . implode(", ", $select) . "\nFROM " . table($table),
($where ? "\nWHERE " . implode(" AND ", $where) : "") . ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : ""), ($where ? "\nWHERE " . implode(" AND ", $where) : "") . ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : ""),
$limit, ($limit != "" ? +$limit : null),
($page ? $limit * $page : 0), ($page ? $limit * $page : 0),
"\n" "\n"
); );
} }
$start = microtime(true); $start = microtime(true);
$return = $this->conn->query($query); $return = $this->_conn->query($query);
if ($print) { if ($print) {
echo adminer()->selectQuery($query, $start, !$return); echo $adminer->selectQuery($query, $start, !$return);
} }
return $return; return $return;
} }
/** Delete data from table /** Delete data from table
* @param string $queryWhere " WHERE ..." * @param string
* @param int $limit 0 or 1 * @param string " WHERE ..."
* @return Result|bool * @param int 0 or 1
* @return bool
*/ */
function delete(string $table, string $queryWhere, int $limit = 0) { function delete($table, $queryWhere, $limit = 0) {
$query = "FROM " . table($table); $query = "FROM " . table($table);
return queries("DELETE" . ($limit ? limit1($table, $query, $queryWhere) : " $query$queryWhere")); return queries("DELETE" . ($limit ? limit1($table, $query, $queryWhere) : " $query$queryWhere"));
} }
/** Update data in table /** Update data in table
* @param string[] $set escaped columns in keys, quoted data in values * @param string
* @param string $queryWhere " WHERE ..." * @param array escaped columns in keys, quoted data in values
* @param int $limit 0 or 1 * @param string " WHERE ..."
* @return Result|bool * @param int 0 or 1
* @param string
* @return bool
*/ */
function update(string $table, array $set, string $queryWhere, int $limit = 0, string $separator = "\n") { function update($table, $set, $queryWhere, $limit = 0, $separator = "\n") {
$values = array(); $values = array();
foreach ($set as $key => $val) { foreach ($set as $key => $val) {
$values[] = "$key = $val"; $values[] = "$key = $val";
@@ -127,143 +82,106 @@ abstract class SqlDriver {
} }
/** Insert data into table /** Insert data into table
* @param string[] $set escaped columns in keys, quoted data in values * @param string
* @return Result|bool * @param array escaped columns in keys, quoted data in values
* @return bool
*/ */
function insert(string $table, array $set) { function insert($table, $set) {
return queries("INSERT INTO " . table($table) . ($set return queries("INSERT INTO " . table($table) . ($set
? " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")" ? " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")"
: " DEFAULT VALUES" : " DEFAULT VALUES"
) . $this->insertReturning($table)); ));
}
/** Get RETURNING clause for INSERT queries (PostgreSQL specific) */
function insertReturning(string $table): string {
return "";
} }
/** Insert or update data in table /** Insert or update data in table
* @param list<string[]> $rows of arrays with escaped columns in keys and quoted data in values * @param string
* @param int[] $primary column names in keys * @param array
* @return Result|bool * @param array of arrays with escaped columns in keys and quoted data in values
* @return bool
*/ */
function insertUpdate(string $table, array $rows, array $primary) { /*abstract*/ function insertUpdate($table, $rows, $primary) {
return false; return false;
} }
/** Begin transaction /** Begin transaction
* @return Result|bool * @return bool
*/ */
function begin() { function begin() {
return queries("BEGIN"); return queries("BEGIN");
} }
/** Commit transaction /** Commit transaction
* @return Result|bool * @return bool
*/ */
function commit() { function commit() {
return queries("COMMIT"); return queries("COMMIT");
} }
/** Rollback transaction /** Rollback transaction
* @return Result|bool * @return bool
*/ */
function rollback() { function rollback() {
return queries("ROLLBACK"); return queries("ROLLBACK");
} }
/** Return query with a timeout /** Return query with a timeout
* @param int $timeout seconds * @param string
* @return string|void null if the driver doesn't support query timeouts * @param int seconds
* @return string or null if the driver doesn't support query timeouts
*/ */
function slowQuery(string $query, int $timeout) { function slowQuery($query, $timeout) {
} }
/** Convert column to be searchable /** Convert column to be searchable
* @param string $idf escaped column name * @param string escaped column name
* @param array{op:string, val:string} $val * @param array array("op" => , "val" => )
* @param Field $field * @param array
* @return string
*/ */
function convertSearch(string $idf, array $val, array $field): string { function convertSearch($idf, $val, $field) {
return $idf; return $idf;
} }
/** Convert operator so it can be used in search */ /** Convert operator so it can be used in search
function convertOperator(string $operator): string { * @param string $operator
* @return string
*/
function convertOperator($operator) {
return $operator; return $operator;
} }
/** Convert value returned by database to actual value /** Convert value returned by database to actual value
* @param Field $field * @param string
* @param array
* @return string
*/ */
function value(?string $val, array $field): ?string { function value($val, $field) {
return (method_exists($this->conn, 'value') return (method_exists($this->_conn, 'value')
? $this->conn->value($val, $field) ? $this->_conn->value($val, $field)
: (is_resource($val) ? stream_get_contents($val) : $val) : (is_resource($val) ? stream_get_contents($val) : $val)
); );
} }
/** Quote binary string */ /** Quote binary string
function quoteBinary(string $s): string { * @param string
* @return string
*/
function quoteBinary($s) {
return q($s); return q($s);
} }
/** Get warnings about the last command /** Get warnings about the last command
* @return string|void HTML * @return string HTML
*/ */
function warnings() { function warnings() {
return '';
} }
/** Get help link for table /** Get help link for table
* @return string|void relative URL * @param string
* @return string relative URL or null
*/ */
function tableHelp(string $name, bool $is_view = false) { function tableHelp($name) {
} }
/** Check if C-style escapes are supported */
function hasCStyleEscapes(): bool {
return false;
}
/** Get supported engines
* @return list<string>
*/
function engines(): array {
return array();
}
/** Check whether table supports indexes
* @param TableStatus $table_status
*/
function supportsIndex(array $table_status): bool {
return !is_view($table_status);
}
/** Get defined check constraints
* @return string[] [$name => $clause]
*/
function checkConstraints(string $table): array {
// MariaDB contains CHECK_CONSTRAINTS.TABLE_NAME, MySQL and PostrgreSQL not
return get_key_vals("SELECT c.CONSTRAINT_NAME, CHECK_CLAUSE
FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS c
JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS t ON c.CONSTRAINT_SCHEMA = t.CONSTRAINT_SCHEMA AND c.CONSTRAINT_NAME = t.CONSTRAINT_NAME
WHERE c.CONSTRAINT_SCHEMA = " . q($_GET["ns"] != "" ? $_GET["ns"] : DB) . "
AND t.TABLE_NAME = " . q($table) . "
AND CHECK_CLAUSE NOT LIKE '% IS NOT NULL'", $this->conn); // ignore default IS NOT NULL checks in PostrgreSQL
}
/** Get all fields in the current schema
* @return array<list<array{field:string, null:bool, type:string, length:?numeric-string, primary?:numeric-string}>>
*/
function allFields(): array {
$return = array();
foreach (get_rows("SELECT TABLE_NAME AS tab, COLUMN_NAME AS field, IS_NULLABLE AS nullable, DATA_TYPE AS type, CHARACTER_MAXIMUM_LENGTH AS length" . (JUSH == 'sql' ? ", COLUMN_KEY = 'PRI' AS `primary`" : "") . "
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = " . q($_GET["ns"] != "" ? $_GET["ns"] : DB) . "
ORDER BY TABLE_NAME, ORDINAL_POSITION", $this->conn) as $row) {
$row["null"] = ($row["nullable"] == "YES");
$return[$row["tab"]][] = $row;
}
return $return;
}
} }

View File

@@ -1,37 +1,34 @@
<?php <?php
namespace Adminer;
// This file is not used in Adminer Editor.
/** Print select result /** Print select result
* @param Result $result * @param Min_Result
* @param string[] $orgtables * @param Min_DB connection to examine indexes
* @param int|numeric-string $limit * @param array
* @return string[] $orgtables * @param int
* @return array $orgtables
*/ */
function print_select_result($result, ?Db $connection2 = null, array $orgtables = array(), $limit = 0): array { function select($result, $connection2 = null, $orgtables = array(), $limit = 0) {
global $jush;
$links = array(); // colno => orgtable - create links from these columns $links = array(); // colno => orgtable - create links from these columns
$indexes = array(); // orgtable => array(column => colno) - primary keys $indexes = array(); // orgtable => array(column => colno) - primary keys
$columns = array(); // orgtable => array(column => ) - not selected columns in primary key $columns = array(); // orgtable => array(column => ) - not selected columns in primary key
$blobs = array(); // colno => bool - display bytes for blobs $blobs = array(); // colno => bool - display bytes for blobs
$types = array(); // colno => type - display char in <code> $types = array(); // colno => type - display char in <code>
$return = array(); // table => orgtable - mapping to use in EXPLAIN $return = array(); // table => orgtable - mapping to use in EXPLAIN
odd(''); // reset odd for each result
for ($i=0; (!$limit || $i < $limit) && ($row = $result->fetch_row()); $i++) { for ($i=0; (!$limit || $i < $limit) && ($row = $result->fetch_row()); $i++) {
if (!$i) { if (!$i) {
echo "<div class='scrollable'>\n"; echo "<div class='scrollable'>\n";
echo "<table class='nowrap odds'>\n"; echo "<table cellspacing='0' class='nowrap'>\n";
echo "<thead><tr>"; echo "<thead><tr>";
for ($j=0; $j < count($row); $j++) { for ($j=0; $j < count($row); $j++) {
$field = $result->fetch_field(); $field = $result->fetch_field();
$name = $field->name; $name = $field->name;
$orgtable = (isset($field->orgtable) ? $field->orgtable : ""); $orgtable = $field->orgtable;
$orgname = (isset($field->orgname) ? $field->orgname : $name); $orgname = $field->orgname;
if ($orgtables && JUSH == "sql") { // MySQL EXPLAIN $return[$field->table] = $orgtable;
if ($orgtables && $jush == "sql") { // MySQL EXPLAIN
$links[$j] = ($name == "table" ? "table=" : ($name == "possible_keys" ? "indexes=" : null)); $links[$j] = ($name == "table" ? "table=" : ($name == "possible_keys" ? "indexes=" : null));
} elseif ($orgtable != "") { } elseif ($orgtable != "") {
if (isset($field->table)) {
$return[$field->table] = $orgtable;
}
if (!isset($indexes[$orgtable])) { if (!isset($indexes[$orgtable])) {
// find primary key in each table // find primary key in each table
$indexes[$orgtable] = array(); $indexes[$orgtable] = array();
@@ -62,11 +59,11 @@ function print_select_result($result, ?Db $connection2 = null, array $orgtables
} }
echo "</thead>\n"; echo "</thead>\n";
} }
echo "<tr>"; echo "<tr" . odd() . ">";
foreach ($row as $key => $val) { foreach ($row as $key => $val) {
$link = ""; $link = "";
if (isset($links[$key]) && !$columns[$links[$key]]) { if (isset($links[$key]) && !$columns[$links[$key]]) {
if ($orgtables && JUSH == "sql") { // MySQL EXPLAIN if ($orgtables && $jush == "sql") { // MySQL EXPLAIN
$table = $row[array_search("table=", $links)]; $table = $row[array_search("table=", $links)];
$link = ME . $links[$key] . urlencode($orgtables[$table] != "" ? $orgtables[$table] : $table); $link = ME . $links[$key] . urlencode($orgtables[$table] != "" ? $orgtables[$table] : $table);
} else { } else {
@@ -75,7 +72,7 @@ function print_select_result($result, ?Db $connection2 = null, array $orgtables
$link .= "&where" . urlencode("[" . bracket_escape($col) . "]") . "=" . urlencode($row[$j]); $link .= "&where" . urlencode("[" . bracket_escape($col) . "]") . "=" . urlencode($row[$j]);
} }
} }
} elseif (is_url($val)) { } elseif (is_web_url($val)) {
$link = $val; $link = $val;
} }
if ($val === null) { if ($val === null) {
@@ -89,10 +86,9 @@ function print_select_result($result, ?Db $connection2 = null, array $orgtables
} }
} }
if ($link) { if ($link) {
$val = "<a href='" . h($link) . "'" . (is_url($link) ? target_blank() : '') . ">$val</a>"; $val = "<a href='" . h($link) . "'" . (is_web_url($link) ? target_blank() : '') . ">$val</a>";
} }
// https://dev.mysql.com/doc/dev/mysql-server/latest/field__types_8h.html echo "<td>$val";
echo "<td" . ($types[$key] <= 9 || $types[$key] == 246 ? " class='number'" : "") . ">$val";
} }
} }
echo ($i ? "</table>\n</div>" : "<p class='message'>" . lang('No rows.')) . "\n"; echo ($i ? "</table>\n</div>" : "<p class='message'>" . lang('No rows.')) . "\n";
@@ -100,9 +96,10 @@ function print_select_result($result, ?Db $connection2 = null, array $orgtables
} }
/** Get referencable tables with single column primary key except self /** Get referencable tables with single column primary key except self
* @return array<string, Field> [$table_name => $field] * @param string
* @return array ($table_name => $field)
*/ */
function referencable_primary(string $self): array { function referencable_primary($self) {
$return = array(); // table_name => field $return = array(); // table_name => field
foreach (table_status('', true) as $table_name => $table) { foreach (table_status('', true) as $table_name => $table) {
if ($table_name != $self && fk_support($table)) { if ($table_name != $self && fk_support($table)) {
@@ -120,11 +117,41 @@ function referencable_primary(string $self): array {
return $return; return $return;
} }
/** Print SQL <textarea> tag /** Get settings stored in a cookie
* @param string|list<array{string}> $value * @return array
*/ */
function textarea(string $name, $value, int $rows = 10, int $cols = 80): void { function adminer_settings() {
echo "<textarea name='" . h($name) . "' rows='$rows' cols='$cols' class='sqlarea jush-" . JUSH . "' spellcheck='false' wrap='off'>"; 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
* @param int
* @param int
* @return null
*/
function textarea($name, $value, $rows = 10, $cols = 80) {
global $jush;
echo "<textarea name='" . h($name) . "' rows='$rows' cols='$cols' class='sqlarea jush-$jush' spellcheck='false' wrap='off'>";
if (is_array($value)) { if (is_array($value)) {
foreach ($value as $val) { // not implode() to save memory foreach ($value as $val) { // not implode() to save memory
echo h($val[0]) . "\n\n\n"; // $val == array($query, $time, $elapsed) echo h($val[0]) . "\n\n\n"; // $val == array($query, $time, $elapsed)
@@ -135,89 +162,39 @@ function textarea(string $name, $value, int $rows = 10, int $cols = 80): void {
echo "</textarea>"; echo "</textarea>";
} }
/** Generate HTML <select> or <input> if $options are empty
* @param string[] $options
*/
function select_input(string $attrs, array $options, ?string $value = "", string $onchange = "", string $placeholder = ""): string {
$tag = ($options ? "select" : "input");
return "<$tag$attrs" . ($options
? "><option value=''>$placeholder" . optionlist($options, $value, true) . "</select>"
: " size='10' value='" . h($value) . "' placeholder='$placeholder'>"
) . ($onchange ? script("qsl('$tag').onchange = $onchange;", "") : ""); //! use oninput for input
}
/** Print one row in JSON object
* @param string $key or "" to close the object
* @param string|int $val
*/
function json_row(string $key, $val = null): void {
static $first = true;
if ($first) {
echo "{";
}
if ($key != "") {
echo ($first ? "" : ",") . "\n\t\"" . addcslashes($key, "\r\n\t\"\\/") . '": ' . ($val !== null ? '"' . addcslashes($val, "\r\n\"\\/") . '"' : 'null');
$first = false;
} else {
echo "\n}\n";
$first = true;
}
}
/** Print table columns for type edit /** Print table columns for type edit
* @param Field $field * @param string
* @param list<string> $collations * @param array
* @param string[] $foreign_keys * @param array
* @param list<string> $extra_types extra types to prepend * @param array returned by referencable_primary()
* @param array extra types to prepend
* @return null
*/ */
function edit_type(string $key, array $field, array $collations, array $foreign_keys = array(), array $extra_types = array()): void { function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_types = array()) {
global $structured_types, $types, $unsigned, $on_actions;
$type = $field["type"]; $type = $field["type"];
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)) { <td><select name="<?php echo h($key); ?>[type]" class="type" aria-labelledby="label-type"><?php
if ($type && !isset($types[$type]) && !isset($foreign_keys[$type]) && !in_array($type, $extra_types)) {
$extra_types[] = $type; $extra_types[] = $type;
} }
$structured_types = driver()->structuredTypes(); if ($foreign_keys) {
if ($foreign_keys) {
$structured_types[lang('Foreign keys')] = $foreign_keys; $structured_types[lang('Foreign keys')] = $foreign_keys;
} }
echo optionlist(array_merge($extra_types, $structured_types), $type); echo optionlist(array_merge($extra_types, $structured_types), $type);
echo "</select><td>"; ?></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 "<input name='" . h($key) . "[length]' value='" . h($field["length"]) . "' size='3'" echo "<select name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>';
. (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : "") //! type="number" with enabled JavaScript echo ($unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : '');
. " aria-labelledby='label-length'>"; 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 "<td class='options'>"; echo ($foreign_keys ? "<select name='" . h($key) . "[on_delete]'" . (preg_match("~`~", $type) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", $on_actions), $field["on_delete"]) . "</select> " : " "); // space for IE
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
);
} }
/** Get partition info /** Filter length value including enums
* @return array{partition_by:string, partition:string, partitions:string, partition_names:list<string>, partition_values:list<string>} * @param string
* @return string
*/ */
function get_partitions_info(string $table): array { function process_length($length) {
$from = "FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = " . q(DB) . " AND TABLE_NAME = " . q($table); global $enum_length;
$result = connection()->query("SELECT PARTITION_METHOD, PARTITION_EXPRESSION, PARTITION_ORDINAL_POSITION $from ORDER BY PARTITION_ORDINAL_POSITION DESC LIMIT 1");
$return = array();
list($return["partition_by"], $return["partition"], $return["partitions"]) = $result->fetch_row();
$partitions = get_key_vals("SELECT PARTITION_NAME, PARTITION_DESCRIPTION $from AND PARTITION_NAME != '' ORDER BY PARTITION_ORDINAL_POSITION");
$return["partition_names"] = array_keys($partitions);
$return["partition_values"] = array_values($partitions);
return $return;
}
/** Filter length value including enums */
function process_length(?string $length): string {
$enum_length = driver()->enumLength;
return (preg_match("~^\\s*\\(?\\s*$enum_length(?:\\s*,\\s*$enum_length)*+\\s*\\)?\\s*\$~", $length) && preg_match_all("~$enum_length~", $length, $matches) return (preg_match("~^\\s*\\(?\\s*$enum_length(?:\\s*,\\s*$enum_length)*+\\s*\\)?\\s*\$~", $length) && preg_match_all("~$enum_length~", $length, $matches)
? "(" . implode(",", $matches[0]) . ")" ? "(" . implode(",", $matches[0]) . ")"
: preg_replace('~^[0-9].*~', '(\0)', preg_replace('~[^-0-9,+()[\]]~', '', $length)) : preg_replace('~^[0-9].*~', '(\0)', preg_replace('~[^-0-9,+()[\]]~', '', $length))
@@ -225,26 +202,25 @@ function process_length(?string $length): string {
} }
/** Create SQL string from field type /** Create SQL string from field type
* @param FieldType $field * @param array
* @param string
* @return string
*/ */
function process_type(array $field, string $collate = "COLLATE"): string { function process_type($field, $collate = "COLLATE") {
global $unsigned;
return " $field[type]" return " $field[type]"
. process_length($field["length"]) . process_length($field["length"])
. (preg_match(number_type(), $field["type"]) && in_array($field["unsigned"], driver()->unsigned) ? " $field[unsigned]" : "") . (preg_match(number_type(), $field["type"]) && in_array($field["unsigned"], $unsigned) ? " $field[unsigned]" : "")
. (preg_match('~char|text|enum|set~', $field["type"]) && $field["collation"] ? " $collate " . (JUSH == "mssql" ? $field["collation"] : q($field["collation"])) : "") . (preg_match('~char|text|enum|set~', $field["type"]) && $field["collation"] ? " $collate " . q($field["collation"]) : "")
; ;
} }
/** Create SQL string from field /** Create SQL string from field
* @param Field $field basic field information * @param array basic field information
* @param Field $type_field information about field type * @param array information about field type
* @return list<string> ["field", "type", "NULL", "DEFAULT", "ON UPDATE", "COMMENT", "AUTO_INCREMENT"] * @return array array("field", "type", "NULL", "DEFAULT", "ON UPDATE", "COMMENT", "AUTO_INCREMENT")
*/ */
function process_field(array $field, array $type_field): array { function process_field($field, $type_field) {
// MariaDB exports CURRENT_TIMESTAMP as a function.
if ($field["on_update"]) {
$field["on_update"] = str_ireplace("current_timestamp()", "CURRENT_TIMESTAMP", $field["on_update"]);
}
return array( return array(
idf_escape(trim($field["field"])), idf_escape(trim($field["field"])),
process_type($type_field), process_type($type_field),
@@ -257,32 +233,25 @@ function process_field(array $field, array $type_field): array {
} }
/** Get default value clause /** Get default value clause
* @param Field $field * @param array
* @return string
*/ */
function default_value(array $field): string { function default_value($field) {
$default = $field["default"]; $default = $field["default"];
$generated = $field["generated"]; return ($default === null ? "" : " DEFAULT " . (preg_match('~char|binary|text|enum|set~', $field["type"]) || preg_match('~^(?![a-z])~i', $default) ? q($default) : $default));
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|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))
)
));
} }
/** Get type class to use in CSS /** Get type class to use in CSS
* @return string|void class='' * @param string
* @return string class=''
*/ */
function type_class(string $type) { function type_class($type) {
foreach ( foreach (array(
array(
'char' => 'text', 'char' => 'text',
'date' => 'time|year', 'date' => 'time|year',
'binary' => 'blob', 'binary' => 'blob',
'enum' => 'set', 'enum' => 'set',
) as $key => $val ) as $key => $val) {
) {
if (preg_match("~$key|$val~", $type)) { if (preg_match("~$key|$val~", $type)) {
return " class='$key'"; return " class='$key'";
} }
@@ -290,72 +259,71 @@ function type_class(string $type) {
} }
/** Print table interior for fields editing /** Print table interior for fields editing
* @param (Field|RoutineField)[] $fields * @param array
* @param list<string> $collations * @param array
* @param 'TABLE'|'PROCEDURE' $type * @param string TABLE or PROCEDURE
* @param string[] $foreign_keys * @param array returned by referencable_primary()
* @return null
*/ */
function edit_fields(array $fields, array $collations, $type = "TABLE", array $foreign_keys = array()): void { function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = array()) {
global $inout;
$fields = array_values($fields); $fields = array_values($fields);
$default_class = (($_POST ? $_POST["defaults"] : get_setting("defaults")) ? "" : " class='hidden'"); $default_class = (($_POST ? $_POST["defaults"] : adminer_setting("defaults")) ? "" : " class='hidden'");
$comment_class = (($_POST ? $_POST["comments"] : get_setting("comments")) ? "" : " class='hidden'"); $comment_class = (($_POST ? $_POST["comments"] : adminer_setting("comments")) ? "" : " class='hidden'");
echo "<thead><tr>\n"; ?>
echo ($type == "PROCEDURE" ? "<td>" : ""); <thead><tr>
echo "<th id='label-name'>" . ($type == "TABLE" ? lang('Column name') : lang('Parameter name')); <?php if ($type == "PROCEDURE") { ?><td><?php } ?>
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;"); <th id="label-name"><?php echo ($type == "TABLE" ? lang('Column name') : lang('Parameter name')); ?>
echo "<td id='label-length'>" . lang('Length'); <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;"); ?>
echo "<td>" . lang('Options'); // no label required, options have their own label <td id="label-length"><?php echo lang('Length'); ?>
if ($type == "TABLE") { <td><?php echo lang('Options'); /* no label required, options have their own label */ ?>
echo "<td id='label-null'>NULL\n"; <?php if ($type == "TABLE") { ?>
echo "<td><input type='radio' name='auto_increment_col' value=''><abbr id='label-ai' title='" . lang('Auto Increment') . "'>AI</abbr>"; <td id="label-null">NULL
echo doc_link(array( <td><input type="radio" name="auto_increment_col" value=""><acronym id="label-ai" title="<?php echo lang('Auto Increment'); ?>">AI</acronym><?php echo doc_link(array(
'sql' => "example-auto-increment.html", 'sql' => "example-auto-increment.html",
'mariadb' => "auto_increment/", 'mariadb' => "auto_increment/",
'sqlite' => "autoinc.html", 'sqlite' => "autoinc.html",
'pgsql' => "datatype-numeric.html#DATATYPE-SERIAL", 'pgsql' => "datatype.html#DATATYPE-SERIAL",
'mssql' => "t-sql/statements/create-table-transact-sql-identity-property", 'mssql' => "ms186775.aspx",
)); )); ?>
echo "<td id='label-default'$default_class>" . lang('Default value'); <td id="label-default"<?php echo $default_class; ?>><?php echo lang('Default value'); ?>
echo (support("comment") ? "<td id='label-comment'$comment_class>" . lang('Comment') : ""); <?php echo (support("comment") ? "<td id='label-comment'$comment_class>" . lang('Comment') : ""); ?>
} <?php } ?>
echo "<td>" . icon("plus", "add[" . (support("move_col") ? 0 : count($fields)) . "]", "+", lang('Add next')); <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) . ";"); ?>
echo "</thead>\n<tbody>\n"; </thead>
<tbody>
<?php
echo script("mixin(qsl('tbody'), {onclick: editingClick, onkeydown: editingKeydown, oninput: editingInput});"); echo script("mixin(qsl('tbody'), {onclick: editingClick, onkeydown: editingKeydown, oninput: editingInput});");
foreach ($fields as $i => $field) { foreach ($fields as $i => $field) {
$i++; $i++;
$orig = $field[($_POST ? "orig" : "field")]; $orig = $field[($_POST ? "orig" : "field")];
$display = (isset($_POST["add"][$i-1]) || (isset($field["field"]) && !idx($_POST["drop_col"], $i))) && (support("drop_col") || $orig == ""); $display = (isset($_POST["add"][$i-1]) || (isset($field["field"]) && !$_POST["drop_col"][$i])) && (support("drop_col") || $orig == "");
echo "<tr" . ($display ? "" : " style='display: none;'") . ">\n"; ?>
echo ($type == "PROCEDURE" ? "<td>" . html_select("fields[$i][inout]", explode("|", driver()->inout), $field["inout"]) : "") . "<th>"; <tr<?php echo ($display ? "" : " style='display: none;'"); ?>>
if ($display) { <?php echo ($type == "PROCEDURE" ? "<td>" . html_select("fields[$i][inout]", explode("|", $inout), $field["inout"]) : ""); ?>
echo "<input name='fields[$i][field]' value='" . h($field["field"]) . "' data-maxlength='64' autocapitalize='off' aria-labelledby='label-name'>"; <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); ?>
echo input_hidden("fields[$i][orig]", $orig); <?php if ($type == "TABLE") { ?>
edit_type("fields[$i]", $field, $collations, $foreign_keys); <td><?php echo checkbox("fields[$i][null]", 1, $field["null"], "", "", "block", "label-null"); ?>
if ($type == "TABLE") { <td><label class="block"><input type="radio" name="auto_increment_col" value="<?php echo $i; ?>"<?php if ($field["auto_increment"]) { ?> checked<?php } ?> aria-labelledby="label-ai"></label><td<?php echo $default_class; ?>><?php
echo "<td>" . checkbox("fields[$i][null]", 1, $field["null"], "", "", "block", "label-null"); echo checkbox("fields[$i][has_default]", 1, $field["has_default"], "", "", "", "label-default"); ?><input name="fields[<?php echo $i; ?>][default]" value="<?php echo h($field["default"]); ?>" aria-labelledby="label-default"><?php
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")
);
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 (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>"; echo "<td>";
echo (support("move_col") ? echo (support("move_col") ?
icon("plus", "add[$i]", "+", lang('Add next')) . " " "<input type='image' class='icon' name='add[$i]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'> "
. icon("up", "up[$i]", "", lang('Move up')) . " " . "<input type='image' class='icon' name='up[$i]' src='../adminer/static/up.gif' alt='↑' title='" . lang('Move up') . "'> "
. icon("down", "down[$i]", "", lang('Move down')) . " " . "<input type='image' class='icon' name='down[$i]' src='../adminer/static/down.gif' alt='↓' title='" . lang('Move down') . "'> "
: ""); : "");
echo ($orig == "" || support("drop_col") ? icon("cross", "drop_col[$i]", "x", lang('Remove')) : ""); echo ($orig == "" || support("drop_col") ? "<input type='image' class='icon' name='drop_col[$i]' src='../adminer/static/cross.gif' alt='x' title='" . lang('Remove') . "'>" : "");
} }
} }
/** Move fields up and down or add field /** Move fields up and down or add field
* @param Field[] $fields * @param array
* @return bool
*/ */
function process_fields(array &$fields): bool { function process_fields(&$fields) {
$offset = 0; $offset = 0;
if ($_POST["up"]) { if ($_POST["up"]) {
$last = 0; $last = 0;
@@ -393,19 +361,21 @@ function process_fields(array &$fields): bool {
} }
/** Callback used in routine() /** Callback used in routine()
* @param list<string> $match * @param array
* @return string
*/ */
function normalize_enum(array $match): string { function normalize_enum($match) {
$val = $match[0]; return "'" . str_replace("'", "''", addcslashes(stripcslashes(str_replace($match[0][0] . $match[0][0], $match[0][0], substr($match[0], 1, -1))), '\\')) . "'";
return "'" . str_replace("'", "''", addcslashes(stripcslashes(str_replace($val[0] . $val[0], $val[0], substr($val, 1, -1))), '\\')) . "'";
} }
/** Issue grant or revoke commands /** Issue grant or revoke commands
* @param 'GRANT'|'REVOKE' $grant * @param string GRANT or REVOKE
* @param list<string> $privileges * @param array
* @return Result|bool * @param string
* @param string
* @return bool
*/ */
function grant(string $grant, array $privileges, ?string $columns, string $on) { function grant($grant, $privileges, $columns, $on) {
if (!$privileges) { if (!$privileges) {
return true; return true;
} }
@@ -420,14 +390,20 @@ function grant(string $grant, array $privileges, ?string $columns, string $on) {
} }
/** Drop old object and create a new one /** Drop old object and create a new one
* @param string $drop drop old object query * @param string drop old object query
* @param string $create create new object query * @param string create new object query
* @param string $drop_created drop new object query * @param string drop new object query
* @param string $test create test object query * @param string create test object query
* @param string $drop_test drop test object query * @param string drop test object query
* @return void redirect on success * @param string
* @param string
* @param string
* @param string
* @param string
* @param string
* @return null redirect in success
*/ */
function drop_create(string $drop, string $create, string $drop_created, string $test, string $drop_test, string $location, string $message_drop, string $message_alter, string $message_create, string $old_name, string $new_name): void { function drop_create($drop, $create, $drop_created, $test, $drop_test, $location, $message_drop, $message_alter, $message_create, $old_name, $new_name) {
if ($_POST["drop"]) { if ($_POST["drop"]) {
query_redirect($drop, $location, $message_drop); query_redirect($drop, $location, $message_drop);
} elseif ($old_name == "") { } elseif ($old_name == "") {
@@ -448,67 +424,78 @@ function drop_create(string $drop, string $create, string $drop_created, string
} }
/** Generate SQL query for creating trigger /** Generate SQL query for creating trigger
* @param Trigger $row * @param string
* @param array result of trigger()
* @return string
*/ */
function create_trigger(string $on, array $row): string { function create_trigger($on, $row) {
global $jush;
$timing_event = " $row[Timing] $row[Event]" . (preg_match('~ OF~', $row["Event"]) ? " $row[Of]" : ""); // SQL injection $timing_event = " $row[Timing] $row[Event]" . (preg_match('~ OF~', $row["Event"]) ? " $row[Of]" : ""); // SQL injection
return "CREATE TRIGGER " return "CREATE TRIGGER "
. idf_escape($row["Trigger"]) . idf_escape($row["Trigger"])
. (JUSH == "mssql" ? $on . $timing_event : $timing_event . $on) . ($jush == "mssql" ? $on . $timing_event : $timing_event . $on)
. rtrim(" $row[Type]\n$row[Statement]", ";") . rtrim(" $row[Type]\n$row[Statement]", ";")
. ";" . ";"
; ;
} }
/** Generate SQL query for creating routine /** Generate SQL query for creating routine
* @param 'PROCEDURE'|'FUNCTION' $routine * @param string "PROCEDURE" or "FUNCTION"
* @param Routine $row * @param array result of routine()
* @return string
*/ */
function create_routine($routine, array $row): string { function create_routine($routine, $row) {
global $inout, $jush;
$set = array(); $set = array();
$fields = (array) $row["fields"]; $fields = (array) $row["fields"];
ksort($fields); // enforce fields order ksort($fields); // enforce fields order
foreach ($fields as $field) { foreach ($fields as $field) {
if ($field["field"] != "") { if ($field["field"] != "") {
$set[] = (preg_match("~^(driver()->inout)\$~", $field["inout"]) ? "$field[inout] " : "") . idf_escape($field["field"]) . process_type($field, "CHARACTER SET"); $set[] = (preg_match("~^($inout)\$~", $field["inout"]) ? "$field[inout] " : "") . idf_escape($field["field"]) . process_type($field, "CHARACTER SET");
} }
} }
$definition = rtrim($row["definition"], ";"); $definition = rtrim("\n$row[definition]", ";");
return "CREATE $routine " return "CREATE $routine "
. idf_escape(trim($row["name"])) . idf_escape(trim($row["name"]))
. " (" . implode(", ", $set) . ")" . " (" . implode(", ", $set) . ")"
. ($routine == "FUNCTION" ? " RETURNS" . process_type($row["returns"], "CHARACTER SET") : "") . (isset($_GET["function"]) ? " RETURNS" . process_type($row["returns"], "CHARACTER SET") : "")
. ($row["language"] ? " LANGUAGE $row[language]" : "") . ($row["language"] ? " LANGUAGE $row[language]" : "")
. (JUSH == "pgsql" ? " AS " . q($definition) : "\n$definition;") . ($jush == "pgsql" ? " AS " . q($definition) : "$definition;")
; ;
} }
/** Remove current user definer from SQL command */ /** Remove current user definer from SQL command
function remove_definer(string $query): string { * @param string
* @return string
*/
function remove_definer($query) {
return preg_replace('~^([A-Z =]+) DEFINER=`' . preg_replace('~@(.*)~', '`@`(%|\1)', logged_user()) . '`~', '\1', $query); //! proper escaping of user return preg_replace('~^([A-Z =]+) DEFINER=`' . preg_replace('~@(.*)~', '`@`(%|\1)', logged_user()) . '`~', '\1', $query); //! proper escaping of user
} }
/** Format foreign key to use in SQL query /** Format foreign key to use in SQL query
* @param ForeignKey $foreign_key * @param array ("db" => string, "ns" => string, "table" => string, "source" => array, "target" => array, "on_delete" => one of $on_actions, "on_update" => one of $on_actions)
* @return string
*/ */
function format_foreign_key(array $foreign_key): string { function format_foreign_key($foreign_key) {
global $on_actions;
$db = $foreign_key["db"]; $db = $foreign_key["db"];
$ns = $foreign_key["ns"]; $ns = $foreign_key["ns"];
return " FOREIGN KEY (" . implode(", ", array_map('Adminer\idf_escape', $foreign_key["source"])) . ") REFERENCES " return " FOREIGN KEY (" . implode(", ", array_map('idf_escape', $foreign_key["source"])) . ") REFERENCES "
. ($db != "" && $db != $_GET["db"] ? idf_escape($db) . "." : "") . ($db != "" && $db != $_GET["db"] ? idf_escape($db) . "." : "")
. ($ns != "" && $ns != $_GET["ns"] ? idf_escape($ns) . "." : "") . ($ns != "" && $ns != $_GET["ns"] ? idf_escape($ns) . "." : "")
. idf_escape($foreign_key["table"]) . table($foreign_key["table"])
. " (" . implode(", ", array_map('Adminer\idf_escape', $foreign_key["target"])) . ")" //! reuse $name - check in older MySQL versions . " (" . implode(", ", array_map('idf_escape', $foreign_key["target"])) . ")" //! reuse $name - check in older MySQL versions
. (preg_match("~^(driver()->onActions)\$~", $foreign_key["on_delete"]) ? " ON DELETE $foreign_key[on_delete]" : "") . (preg_match("~^($on_actions)\$~", $foreign_key["on_delete"]) ? " ON DELETE $foreign_key[on_delete]" : "")
. (preg_match("~^(driver()->onActions)\$~", $foreign_key["on_update"]) ? " ON UPDATE $foreign_key[on_update]" : "") . (preg_match("~^($on_actions)\$~", $foreign_key["on_update"]) ? " ON UPDATE $foreign_key[on_update]" : "")
; ;
} }
/** Add a file to TAR /** Add a file to TAR
* @param TmpFile $tmp_file * @param string
* @return void prints the output * @param TmpFile
* @return null prints the output
*/ */
function tar_file(string $filename, $tmp_file): void { function tar_file($filename, $tmp_file) {
$return = pack("a100a8a8a8a12a12", $filename, 644, 0, 0, decoct($tmp_file->size), decoct(time())); $return = pack("a100a8a8a8a12a12", $filename, 644, 0, 0, decoct($tmp_file->size), decoct(time()));
$checksum = 8*32; // space for checksum itself $checksum = 8*32; // space for checksum itself
for ($i=0; $i < strlen($return); $i++) { for ($i=0; $i < strlen($return); $i++) {
@@ -521,47 +508,59 @@ function tar_file(string $filename, $tmp_file): void {
echo str_repeat("\0", 511 - ($tmp_file->size + 511) % 512); echo str_repeat("\0", 511 - ($tmp_file->size + 511) % 512);
} }
/** Get INI bytes value */ /** Get INI bytes value
function ini_bytes(string $ini): int { * @param string
* @return int
*/
function ini_bytes($ini) {
$val = ini_get($ini); $val = ini_get($ini);
switch (strtolower(substr($val, -1))) { switch (strtolower(substr($val, -1))) {
case 'g': case 'g': $val *= 1024; // no break
$val = (int) $val * 1024; // no break case 'm': $val *= 1024; // no break
case 'm': case 'k': $val *= 1024;
$val = (int) $val * 1024; // no break
case 'k':
$val = (int) $val * 1024;
} }
return $val; return $val;
} }
/** Create link to database documentation /** Create link to database documentation
* @param string[] $paths JUSH => $path * @param array $jush => $path
* @param string $text HTML code * @param string HTML code
* @return string HTML code * @return string HTML code
*/ */
function doc_link(array $paths, string $text = "<sup>?</sup>"): string { function doc_link($paths, $text = "<sup>?</sup>") {
$server_info = connection()->server_info; global $jush, $connection;
$server_info = $connection->server_info;
$version = preg_replace('~^(\d\.?\d).*~s', '\1', $server_info); // two most significant digits $version = preg_replace('~^(\d\.?\d).*~s', '\1', $server_info); // two most significant digits
$urls = array( $urls = array(
'sql' => "https://dev.mysql.com/doc/refman/$version/en/", 'sql' => "https://dev.mysql.com/doc/refman/$version/en/",
'sqlite' => "https://www.sqlite.org/", 'sqlite' => "https://www.sqlite.org/",
'pgsql' => "https://www.postgresql.org/docs/" . (connection()->flavor == 'cockroach' ? "current" : $version) . "/", 'pgsql' => "https://www.postgresql.org/docs/$version/",
'mssql' => "https://learn.microsoft.com/en-us/sql/", 'mssql' => "https://msdn.microsoft.com/library/",
'oracle' => "https://www.oracle.com/pls/topic/lookup?ctx=db" . preg_replace('~^.* (\d+)\.(\d+)\.\d+\.\d+\.\d+.*~s', '\1\2', $server_info) . "&id=", 'oracle' => "https://www.oracle.com/pls/topic/lookup?ctx=db" . preg_replace('~^.* (\d+)\.(\d+)\.\d+\.\d+\.\d+.*~s', '\1\2', $server_info) . "&id=",
); );
if (connection()->flavor == 'maria') { if (preg_match('~MariaDB~', $server_info)) {
$urls['sql'] = "https://mariadb.com/kb/en/"; $urls['sql'] = "https://mariadb.com/kb/en/library/";
$paths['sql'] = (isset($paths['mariadb']) ? $paths['mariadb'] : str_replace(".html", "/", $paths['sql'])); $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>" : ""); return ($paths[$jush] ? "<a href='" . h($urls[$jush] . $paths[$jush]) . "'" . target_blank() . ">$text</a>" : "");
}
/** Wrap gzencode() for usage in ob_start()
* @param string
* @return string
*/
function ob_gzencode($string) {
// ob_start() callback recieves an optional parameter $phase but gzencode() accepts optional parameter $level
return gzencode($string);
} }
/** Compute size of database /** Compute size of database
* @param string
* @return string formatted * @return string formatted
*/ */
function db_size(string $db): string { function db_size($db) {
if (!connection()->select_db($db)) { global $connection;
if (!$connection->select_db($db)) {
return "?"; return "?";
} }
$return = 0; $return = 0;
@@ -571,11 +570,15 @@ function db_size(string $db): string {
return format_number($return); return format_number($return);
} }
/** Print SET NAMES if utf8mb4 might be needed */ /** Print SET NAMES if utf8mb4 might be needed
function set_utf8mb4(string $create): void { * @param string
* @return null
*/
function set_utf8mb4($create) {
global $connection;
static $set = false; static $set = false;
if (!$set && preg_match('~\butf8mb4~i', $create)) { // possible false positive if (!$set && preg_match('~\butf8mb4~i', $create)) { // possible false positive
$set = true; $set = true;
echo "SET NAMES " . charset(connection()) . ";\n\n"; echo "SET NAMES " . charset($connection) . ";\n\n";
} }
} }

View File

@@ -1,9 +0,0 @@
<?php
namespace Adminer;
error_reporting(24575); // all but E_DEPRECATED (overriding mysqli methods without types is deprecated)
set_error_handler(function ($errno, $errstr) {
// "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('~^Undefined (array key|offset|index)~', $errstr);
}, E_WARNING | E_NOTICE); // warning since PHP 8.0

File diff suppressed because it is too large Load Diff

View File

@@ -1,478 +0,0 @@
<?php
namespace Adminer;
/** Return <script> element */
function script(string $source, string $trailing = "\n"): string {
return "<script" . nonce() . ">$source</script>$trailing";
}
/** Return <script src> element */
function script_src(string $url): string {
return "<script src='" . h($url) . "'" . nonce() . "></script>\n";
}
/** Get a nonce="" attribute with CSP nonce */
function nonce(): string {
return ' nonce="' . get_nonce() . '"';
}
/** Get <input type="hidden">
* @param string|int $value
* @return string HTML
*/
function input_hidden(string $name, $value = ""): string {
return "<input type='hidden' name='" . h($name) . "' value='" . h($value) . "'>\n";
}
/** Get CSRF <input type="hidden" name="token">
* @return string HTML
*/
function input_token(): string {
return input_hidden("token", get_token());
}
/** Get a target="_blank" attribute */
function target_blank(): string {
return ' target="_blank" rel="noreferrer noopener"';
}
/** Escape for HTML */
function h(?string $string): string {
return str_replace("\0", "&#0;", htmlspecialchars($string, ENT_QUOTES, 'utf-8'));
}
/** Convert \n to <br> */
function nl_br(string $string): string {
return str_replace("\n", "<br>", $string); // nl2br() uses XHTML before PHP 5.3
}
/** Generate HTML checkbox
* @param string|int $value
*/
function checkbox(string $name, $value, ?bool $checked, string $label = "", string $onclick = "", string $class = "", string $labelled_by = ""): string {
$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 string[]|string[][] $options array of strings or arrays (creates optgroup)
* @param mixed $selected
* @param bool $use_keys always use array keys for value="", otherwise only string keys are used
*/
function optionlist($options, $selected = null, bool $use_keys = false): string {
$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[] $options
*/
function html_select(string $name, array $options, ?string $value = "", string $onchange = "", string $labelled_by = ""): string {
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[] $options
*/
function html_radios(string $name, array $options, string $value = ""): string {
$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 */
function confirm(string $message = "", string $selector = "qsl('input')"): string {
return script("$selector.onclick = () => confirm('" . ($message ? js_escape($message) : lang('Are you sure?')) . "');", "");
}
/** Print header for hidden fieldset (close by </div></fieldset>)
* @param bool $visible
*/
function print_fieldset(string $id, string $legend, $visible = false): void {
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 */
function bold(bool $bold, string $class = ""): string {
return ($bold ? " class='active $class'" : ($class ? " class='$class'" : ""));
}
/** Escape string for JavaScript apostrophes */
function js_escape(string $string): string {
return addcslashes($string, "\r\n'\\/"); // slash for <script>
}
/** Generate page number for pagination */
function pagination(int $page, ?int $current): string {
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 mixed[] $process
* @param list<string> $ignore
*/
function hidden_fields(array $process, array $ignore = array(), string $prefix = ''): bool {
$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 */
function hidden_fields_get(): void {
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 'radio'|'checkbox' $type
* @param Field $field
* @param mixed $value string|array
*/
function enum_input(string $type, string $attrs, array $field, $value, ?string $empty = null): string {
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 Field|RoutineField $field
* @param mixed $value
*/
function input(array $field, $value, ?string $function, ?bool $autofocus = false): void {
$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) . " ";
$table = $_GET["edit"] ?: $_GET["select"];
if ($field["type"] == "enum") {
echo h($functions[""]) . "<td>" . adminer()->editInput($table, $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($table, $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($table, $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 Field|RoutineField $field
* @return mixed false to leave the original value
*/
function process_input(array $field) {
if (stripos($field["default"], "GENERATED ALWAYS AS ") === 0) {
return;
}
$idf = bracket_escape($field["field"]);
$function = idx($_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"]
*/
function search_tables(): void {
$_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 $command JS expression
* @param int $side 0 top, 1 left
*/
function on_help(string $command, int $side = 0): string {
return script("mixin(qsl('select, input'), {onmouseover: function (event) { helpMouseover.call(this, event, $command, $side) }, onmouseout: helpMouseout});", "");
}
/** Print edit data form
* @param Field[] $fields
* @param mixed $row
*/
function edit_form(string $table, array $fields, $row, ?bool $update, string $error = ''): void {
$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 = idx($_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"]
? idx($_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";
}
/** Shorten UTF-8 string
* @return string escaped string with appended ...
*/
function shorten_utf8(string $string, int $length = 80, string $suffix = ""): string {
if (!preg_match("(^(" . repeat_pattern("[\t\r\n -\x{10FFFF}]", $length) . ")($)?)u", $string, $match)) { // ~s causes trash in $match[2] under some PHP versions, (.|\n) is slow
preg_match("(^(" . repeat_pattern("[\t\r\n -~]", $length) . ")($)?)", $string, $match);
}
return h($match[1]) . $suffix . (isset($match[2]) ? "" : "<i>…</i>");
}
/** Get button with icon */
function icon(string $icon, string $name, string $html, string $title): string {
return "<button type='submit' name='$name' title='" . h($title) . "' class='icon icon-$icon'><span>$html</span></button>";
}

View File

@@ -1,17 +1,11 @@
<?php <?php
namespace Adminer;
// not used in a single language version // not used in a single language version
/** Get available languages $langs = array(
* @return string[]
*/
function langs(): array {
return array(
'en' => 'English', // Jakub Vrána - https://www.vrana.cz 'en' => 'English', // Jakub Vrána - https://www.vrana.cz
'ar' => 'العربية', // Y.M Amine - Algeria - nbr7@live.fr 'ar' => 'العربية', // Y.M Amine - Algeria - nbr7@live.fr
'bg' => 'Български', // Deyan Delchev 'bg' => 'Български', // Deyan Delchev
'bn' => 'বাংলা', // Dipak Kumar - dipak.ndc@gmail.com, Hossain Ahmed Saiman - hossain.ahmed@altscope.com 'bn' => 'বাংলা', // Dipak Kumar - dipak.ndc@gmail.com | Hossain Ahmed Saiman - hossain.ahmed@altscope.com
'bs' => 'Bosanski', // Emir Kurtovic 'bs' => 'Bosanski', // Emir Kurtovic
'ca' => 'Català', // Joan Llosas 'ca' => 'Català', // Joan Llosas
'cs' => 'Čeština', // Jakub Vrána - https://www.vrana.cz 'cs' => 'Čeština', // Jakub Vrána - https://www.vrana.cz
@@ -31,8 +25,8 @@ function langs(): array {
'ja' => '日本語', // Hitoshi Ozawa - http://sourceforge.jp/projects/oss-ja-jpn/releases/ 'ja' => '日本語', // Hitoshi Ozawa - http://sourceforge.jp/projects/oss-ja-jpn/releases/
'ka' => 'ქართული', // Saba Khmaladze skhmaladze@uglt.org 'ka' => 'ქართული', // Saba Khmaladze skhmaladze@uglt.org
'ko' => '한국어', // dalli - skcha67@gmail.com 'ko' => '한국어', // dalli - skcha67@gmail.com
'lt' => 'Lietuvių', // Paulius Leščinskas - http://www.lescinskas.lt
'lv' => 'Latviešu', // Kristaps Lediņš - https://krysits.com 'lv' => 'Latviešu', // Kristaps Lediņš - https://krysits.com
'lt' => 'Lietuvių', // Paulius Leščinskas - http://www.lescinskas.lt
'ms' => 'Bahasa Melayu', // Pisyek 'ms' => 'Bahasa Melayu', // Pisyek
'nl' => 'Nederlands', // Maarten Balliauw - http://blog.maartenballiauw.be 'nl' => 'Nederlands', // Maarten Balliauw - http://blog.maartenballiauw.be
'no' => 'Norsk', // Iver Odin Kvello, mupublishing.com 'no' => 'Norsk', // Iver Odin Kvello, mupublishing.com
@@ -49,35 +43,39 @@ function langs(): array {
'th' => 'ภาษาไทย', // Panya Saraphi, elect.tu@gmail.com - http://www.opencart2u.com/ 'th' => 'ภาษาไทย', // Panya Saraphi, elect.tu@gmail.com - http://www.opencart2u.com/
'tr' => 'Türkçe', // Bilgehan Korkmaz - turktron.com 'tr' => 'Türkçe', // Bilgehan Korkmaz - turktron.com
'uk' => 'Українська', // Valerii Kryzhov 'uk' => 'Українська', // Valerii Kryzhov
'uz' => 'Oʻzbekcha', // Junaydullaev Inoyatullokhon - https://av.uz/
'vi' => 'Tiếng Việt', // Giang Manh @ manhgd google mail 'vi' => 'Tiếng Việt', // Giang Manh @ manhgd google mail
'zh' => '简体中文', // Mr. Lodar, vea - urn2.net - vea.urn2@gmail.com 'zh' => '简体中文', // Mr. Lodar, vea - urn2.net - vea.urn2@gmail.com
'zh-tw' => '繁體中文', // http://tzangms.com 'zh-tw' => '繁體中文', // http://tzangms.com
); );
/** Get current language
* @return string
*/
function get_lang() {
global $LANG;
return $LANG;
} }
/** Translate string /** Translate string
* @param literal-string $idf * @param string
* @param float|string $number * @param int
* @return string
*/ */
function lang(string $idf, $number = null): string { function lang($idf, $number = null) {
// this is matched by compile.php global $LANG, $translations;
$translation = (Lang::$translations[$idf] ?: $idf); $translation = ($translations[$idf] ? $translations[$idf] : $idf);
if (is_array($translation)) { if (is_array($translation)) {
// this is matched by compile.php
$pos = ($number == 1 ? 0 $pos = ($number == 1 ? 0
: (LANG == 'cs' || LANG == 'sk' ? ($number && $number < 5 ? 1 : 2) // different forms for 1, 2-4, other : ($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 : ($LANG == 'fr' ? (!$number ? 0 : 1) // different forms for 0-1, other
: (LANG == 'pl' ? ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2) // different forms for 1, 2-4 except 12-14, other : ($LANG == 'pl' ? ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2) // different forms for 1, 2-4 except 12-14, other
: (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 == '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 == 'lt' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1, 12-19, other
: (LANG == 'lv' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number ? 1 : 2)) // different forms for 1 except 11, other, 0 : ($LANG == 'bs' || $LANG == 'ru' || $LANG == 'sr' || $LANG == 'uk' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1 except 11, 2-4 except 12-14, other
: (in_array(LANG, array('bs', 'ru', 'sr', 'uk')) ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1 except 11, 2-4 except 12-14, other : 1 // different forms for 1, other
: 1)))))))) // different forms for 1, other ))))))); // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
; // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
$translation = $translation[$pos]; $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(); $args = func_get_args();
array_shift($args); array_shift($args);
$format = str_replace("%d", "%s", $translation); $format = str_replace("%d", "%s", $translation);
@@ -87,25 +85,27 @@ function lang(string $idf, $number = null): string {
return vsprintf($format, $args); return vsprintf($format, $args);
} }
function switch_lang(): void { function switch_lang() {
global $LANG, $langs;
echo "<form action='' method='post'>\n<div id='lang'>"; echo "<form action='' method='post'>\n<div id='lang'>";
echo lang('Language') . ": " . html_select("lang", langs(), LANG, "this.form.submit();"); echo lang('Language') . ": " . html_select("lang", $langs, $LANG, "this.form.submit();");
echo " <input type='submit' value='" . lang('Use') . "' class='hidden'>\n"; echo " <input type='submit' value='" . lang('Use') . "' class='hidden'>\n";
echo input_token(); echo "<input type='hidden' name='token' value='" . get_token() . "'>\n"; // $token may be empty in auth.inc.php
echo "</div>\n</form>\n"; echo "</div>\n</form>\n";
} }
if (isset($_POST["lang"]) && verify_token()) { // $error not yet available if (isset($_POST["lang"]) && verify_token()) { // $error not yet available
cookie("adminer_lang", $_POST["lang"]); cookie("adminer_lang", $_POST["lang"]);
$_SESSION["lang"] = $_POST["lang"]; // cookies may be disabled $_SESSION["lang"] = $_POST["lang"]; // cookies may be disabled
$_SESSION["translations"] = array(); // used in compiled version
redirect(remove_from_uri()); redirect(remove_from_uri());
} }
$LANG = "en"; $LANG = "en";
if (idx(langs(), $_COOKIE["adminer_lang"])) { if (isset($langs[$_COOKIE["adminer_lang"]])) {
cookie("adminer_lang", $_COOKIE["adminer_lang"]); cookie("adminer_lang", $_COOKIE["adminer_lang"]);
$LANG = $_COOKIE["adminer_lang"]; $LANG = $_COOKIE["adminer_lang"];
} elseif (idx(langs(), $_SESSION["lang"])) { } elseif (isset($langs[$_SESSION["lang"]])) {
$LANG = $_SESSION["lang"]; $LANG = $_SESSION["lang"];
} else { } else {
$accept_language = array(); $accept_language = array();
@@ -115,20 +115,14 @@ if (idx(langs(), $_COOKIE["adminer_lang"])) {
} }
arsort($accept_language); arsort($accept_language);
foreach ($accept_language as $key => $q) { foreach ($accept_language as $key => $q) {
if (idx(langs(), $key)) { if (isset($langs[$key])) {
$LANG = $key; $LANG = $key;
break; break;
} }
$key = preg_replace('~-.*~', '', $key); $key = preg_replace('~-.*~', '', $key);
if (!isset($accept_language[$key]) && idx(langs(), $key)) { if (!isset($accept_language[$key]) && isset($langs[$key])) {
$LANG = $key; $LANG = $key;
break; break;
} }
} }
} }
define('Adminer\LANG', $LANG);
class Lang {
/** @var array<literal-string, string|list<string>> */ static array $translations;
}

View File

@@ -1,33 +1,35 @@
<?php <?php
namespace Adminer;
// PDO can be used in several database drivers // PDO can be used in several database drivers
if (extension_loaded('pdo')) { if (extension_loaded('pdo')) {
abstract class PdoDb extends SqlDb { /*abstract*/ class Min_PDO {
protected \PDO $pdo; var $_result, $server_info, $affected_rows, $errno, $error, $pdo;
/** Connect to server using DSN function __construct() {
* @param mixed[] $options global $adminer;
* @return string error message $pos = array_search("SQL", $adminer->operators);
*/ if ($pos !== false) {
function dsn(string $dsn, string $username, string $password, array $options = array()): string { unset($adminer->operators[$pos]);
$options[\PDO::ATTR_ERRMODE] = \PDO::ERRMODE_SILENT; }
$options[\PDO::ATTR_STATEMENT_CLASS] = array('Adminer\PdoResult'); }
function dsn($dsn, $username, $password, $options = array()) {
$options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT;
$options[PDO::ATTR_STATEMENT_CLASS] = array('Min_PDOStatement');
try { try {
$this->pdo = new \PDO($dsn, $username, $password, $options); $this->pdo = new PDO($dsn, $username, $password, $options);
} catch (\Exception $ex) { } catch (Exception $ex) {
return $ex->getMessage(); auth_error(h($ex->getMessage()));
} }
$this->server_info = @$this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION); $this->server_info = @$this->pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
return '';
} }
function quote(string $string): string { /*abstract function select_db($database);*/
function quote($string) {
return $this->pdo->quote($string); return $this->pdo->quote($string);
} }
function query(string $query, bool $unbuffered = false) { function query($query, $unbuffered = false) {
/** @var Result|bool */
$result = $this->pdo->query($query); $result = $this->pdo->query($query);
$this->error = ""; $this->error = "";
if (!$result) { if (!$result) {
@@ -41,9 +43,13 @@ if (extension_loaded('pdo')) {
return $result; return $result;
} }
function multi_query($query) {
return $this->_result = $this->query($query);
}
function store_result($result = null) { function store_result($result = null) {
if (!$result) { if (!$result) {
$result = $this->multi; $result = $this->_result;
if (!$result) { if (!$result) {
return false; return false;
} }
@@ -56,40 +62,41 @@ if (extension_loaded('pdo')) {
return true; return true;
} }
function next_result(): bool { function next_result() {
/** @var PdoResult|bool */ if (!$this->_result) {
$result = $this->multi;
if (!is_object($result)) {
return false; return false;
} }
$result->_offset = 0; $this->_result->_offset = 0;
return @$result->nextRowset(); // @ - PDO_PgSQL doesn't support it return @$this->_result->nextRowset(); // @ - PDO_PgSQL doesn't support it
}
function result($query, $field = 0) {
$result = $this->query($query);
if (!$result) {
return false;
}
$row = $result->fetch();
return $row[$field];
} }
} }
class PdoResult extends \PDOStatement { class Min_PDOStatement extends PDOStatement {
public $_offset = 0, $num_rows; var $_offset = 0, $num_rows;
function fetch_assoc() { function fetch_assoc() {
return $this->fetch(\PDO::FETCH_ASSOC); return $this->fetch(PDO::FETCH_ASSOC);
} }
function fetch_row() { function fetch_row() {
return $this->fetch(\PDO::FETCH_NUM); return $this->fetch(PDO::FETCH_NUM);
} }
function fetch_field(): \stdClass { function fetch_field() {
$row = (object) $this->getColumnMeta($this->_offset++); $row = (object) $this->getColumnMeta($this->_offset++);
$type = $row->pdo_type; $row->orgtable = $row->table;
$row->type = ($type == \PDO::PARAM_INT ? 0 : 15); $row->orgname = $row->name;
$row->charsetnr = ($type == \PDO::PARAM_LOB || (isset($row->flags) && in_array("blob", (array) $row->flags)) ? 63 : 0); $row->charsetnr = (in_array("blob", (array) $row->flags) ? 63 : 0);
return $row; return $row;
} }
function seek($offset) {
for ($i=0; $i < $offset; $i++) {
$this->fetch();
}
}
} }
} }

View File

@@ -1,85 +0,0 @@
<?php
namespace Adminer;
class Plugins {
/** @var true[] */ private static array $append = array('dumpFormat' => true, 'dumpOutput' => true, 'editRowPrint' => true, 'editFunctions' => true); // these hooks expect the value to be appended to the result
/** @var list<object> @visibility protected(set) */ public array $plugins;
/** @visibility protected(set) */ public string $error = ''; // HTML
/** @var list<object>[] */ private array $hooks = array();
/** Register plugins
* @param ?list<object> $plugins object instances or null to autoload plugins from adminer-plugins/
*/
function __construct(?array $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)) {
// we need to use reflection because PHP 7.1 throws ArgumentCountError for missing arguments but older versions issue a warning
$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;
$adminer = new Adminer;
$plugins[] = $adminer;
$reflection = new \ReflectionObject($adminer);
foreach ($reflection->getMethods() as $method) {
foreach ($plugins as $plugin) {
$name = $method->getName();
if (method_exists($plugin, $name)) {
$this->hooks[$name][] = $plugin;
}
}
}
}
/**
* @param literal-string $name
* @param mixed[] $params
* @return mixed
*/
function __call(string $name, array $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];
}
$return = null;
foreach ($this->hooks[$name] as $plugin) {
$value = call_user_func_array(array($plugin, $name), $args);
if ($value !== null) {
if (!self::$append[$name]) { // non-null value from non-appending method short-circuits the other plugins
return $value;
}
$return = $value + (array) $return;
}
}
return $return;
}
}

View File

@@ -1,22 +1,22 @@
<?php <?php
namespace Adminer;
class TmpFile { class TmpFile {
/** @var resource */ private $handler; var $handler;
/** @visibility protected(set) */ public int $size; var $size;
function __construct() { function __construct() {
$this->handler = tmpfile(); $this->handler = tmpfile();
} }
function write(string $contents): void { function write($contents) {
$this->size += strlen($contents); $this->size += strlen($contents);
fwrite($this->handler, $contents); fwrite($this->handler, $contents);
} }
function send(): void { function send() {
fseek($this->handler, 0); fseek($this->handler, 0);
fpassthru($this->handler); fpassthru($this->handler);
fclose($this->handler); fclose($this->handler);
} }
} }

View File

@@ -1,4 +1,2 @@
<?php <?php
namespace Adminer; $VERSION = "4.9";
const VERSION = "5.1.1";

View File

@@ -1,12 +1,10 @@
<?php <?php
namespace Adminer;
/** PHP implementation of XXTEA encryption algorithm /** PHP implementation of XXTEA encryption algorithm
* @author Ma Bingyao <andot@ujn.edu.cn> * @author Ma Bingyao <andot@ujn.edu.cn>
* @link http://www.coolcode.cn/?action=show&id=128 * @link http://www.coolcode.cn/?action=show&id=128
*/ */
function int32(int $n): int { function int32($n) {
while ($n >= 2147483648) { while ($n >= 2147483648) {
$n -= 4294967296; $n -= 4294967296;
} }
@@ -16,10 +14,7 @@ function int32(int $n): int {
return (int) $n; return (int) $n;
} }
/** function long2str($v, $w) {
* @param int[] $v
*/
function long2str(array $v, bool $w): string {
$s = ''; $s = '';
foreach ($v as $val) { foreach ($v as $val) {
$s .= pack('V', $val); $s .= pack('V', $val);
@@ -30,10 +25,7 @@ function long2str(array $v, bool $w): string {
return $s; return $s;
} }
/** function str2long($s, $w) {
* @return int[]
*/
function str2long(string $s, bool $w): array {
$v = array_values(unpack('V*', str_pad($s, 4 * ceil(strlen($s) / 4), "\0"))); $v = array_values(unpack('V*', str_pad($s, 4 * ceil(strlen($s) / 4), "\0")));
if ($w) { if ($w) {
$v[] = strlen($s); $v[] = strlen($s);
@@ -41,15 +33,16 @@ function str2long(string $s, bool $w): array {
return $v; return $v;
} }
function xxtea_mx(int $z, int $y, int $sum, int $k): int { function xxtea_mx($z, $y, $sum, $k) {
return int32((($z >> 5 & 0x7FFFFFF) ^ $y << 2) + (($y >> 3 & 0x1FFFFFFF) ^ $z << 4)) ^ int32(($sum ^ $y) + ($k ^ $z)); return int32((($z >> 5 & 0x7FFFFFF) ^ $y << 2) + (($y >> 3 & 0x1FFFFFFF) ^ $z << 4)) ^ int32(($sum ^ $y) + ($k ^ $z));
} }
/** Cipher /** Cipher
* @param string $str plain-text password * @param string plain-text password
* @param string
* @return string binary cipher * @return string binary cipher
*/ */
function encrypt_string(string $str, string $key): string { function encrypt_string($str, $key) {
if ($str == "") { if ($str == "") {
return ""; return "";
} }
@@ -78,10 +71,11 @@ function encrypt_string(string $str, string $key): string {
} }
/** Decipher /** Decipher
* @param string $str binary cipher * @param string binary cipher
* @return string|false plain-text password * @param string
* @return string plain-text password
*/ */
function decrypt_string(string $str, string $key) { function decrypt_string($str, $key) {
if ($str == "") { if ($str == "") {
return ""; return "";
} }

View File

@@ -6,17 +6,16 @@
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 * @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) * @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;
include "./include/bootstrap.inc.php"; include "./include/bootstrap.inc.php";
include "./include/tmpfile.inc.php"; include "./include/tmpfile.inc.php";
$enum_length = "'(?:''|[^'\\\\]|\\\\.)*'";
$inout = "IN|OUT|INOUT";
if (isset($_GET["select"]) && ($_POST["edit"] || $_POST["clone"]) && !$_POST["save"]) { if (isset($_GET["select"]) && ($_POST["edit"] || $_POST["clone"]) && !$_POST["save"]) {
$_GET["edit"] = $_GET["select"]; $_GET["edit"] = $_GET["select"];
} }
// this is matched by compile.php
if (isset($_GET["callf"])) { if (isset($_GET["callf"])) {
$_GET["call"] = $_GET["callf"]; $_GET["call"] = $_GET["callf"];
} }
@@ -60,8 +59,6 @@ if (isset($_GET["download"])) {
include "./sequence.inc.php"; include "./sequence.inc.php";
} elseif (isset($_GET["type"])) { } elseif (isset($_GET["type"])) {
include "./type.inc.php"; include "./type.inc.php";
} elseif (isset($_GET["check"])) {
include "./check.inc.php";
} elseif (isset($_GET["trigger"])) { } elseif (isset($_GET["trigger"])) {
include "./trigger.inc.php"; include "./trigger.inc.php";
} elseif (isset($_GET["user"])) { } elseif (isset($_GET["user"])) {

View File

@@ -1,9 +1,7 @@
<?php <?php
namespace Adminer;
$TABLE = $_GET["indexes"]; $TABLE = $_GET["indexes"];
$index_types = array("PRIMARY", "UNIQUE", "INDEX"); $index_types = array("PRIMARY", "UNIQUE", "INDEX");
$table_status = table_status1($TABLE, true); $table_status = table_status($TABLE, true);
if (preg_match('~MyISAM|M?aria' . (min_version(5.6, '10.0.5') ? '|InnoDB' : '') . '~i', $table_status["Engine"])) { if (preg_match('~MyISAM|M?aria' . (min_version(5.6, '10.0.5') ? '|InnoDB' : '') . '~i', $table_status["Engine"])) {
$index_types[] = "FULLTEXT"; $index_types[] = "FULLTEXT";
} }
@@ -12,15 +10,13 @@ if (preg_match('~MyISAM|M?aria' . (min_version(5.7, '10.2.2') ? '|InnoDB' : '')
} }
$indexes = indexes($TABLE); $indexes = indexes($TABLE);
$primary = array(); $primary = array();
if (JUSH == "mongo") { // doesn't support primary key if ($jush == "mongo") { // doesn't support primary key
$primary = $indexes["_id_"]; $primary = $indexes["_id_"];
unset($index_types[0]); unset($index_types[0]);
unset($indexes["_id_"]); unset($indexes["_id_"]);
} }
$row = $_POST; $row = $_POST;
if ($row) {
save_settings(array("index_options" => $row["options"]));
}
if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) { if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) {
$alter = array(); $alter = array();
foreach ($row["indexes"] as $index) { foreach ($row["indexes"] as $index) {
@@ -33,22 +29,22 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) {
ksort($index["columns"]); ksort($index["columns"]);
foreach ($index["columns"] as $key => $column) { foreach ($index["columns"] as $key => $column) {
if ($column != "") { if ($column != "") {
$length = idx($index["lengths"], $key); $length = $index["lengths"][$key];
$desc = idx($index["descs"], $key); $desc = $index["descs"][$key];
$set[] = idf_escape($column) . ($length ? "(" . (+$length) . ")" : "") . ($desc ? " DESC" : ""); $set[] = idf_escape($column) . ($length ? "(" . (+$length) . ")" : "") . ($desc ? " DESC" : "");
$columns[] = $column; $columns[] = $column;
$lengths[] = ($length ?: null); $lengths[] = ($length ? $length : null);
$descs[] = $desc; $descs[] = $desc;
} }
} }
if ($columns) {
$existing = $indexes[$name]; $existing = $indexes[$name];
if ($existing) { if ($existing) {
ksort($existing["columns"]); ksort($existing["columns"]);
ksort($existing["lengths"]); ksort($existing["lengths"]);
ksort($existing["descs"]); ksort($existing["descs"]);
if ( if ($index["type"] == $existing["type"]
$index["type"] == $existing["type"]
&& array_values($existing["columns"]) === $columns && array_values($existing["columns"]) === $columns
&& (!$existing["lengths"] || array_values($existing["lengths"]) === $lengths) && (!$existing["lengths"] || array_values($existing["lengths"]) === $lengths)
&& array_values($existing["descs"]) === $descs && array_values($existing["descs"]) === $descs
@@ -58,7 +54,6 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) {
continue; continue;
} }
} }
if ($columns) {
$alter[] = array($index["type"], $name, $set); $alter[] = array($index["type"], $name, $set);
} }
} }
@@ -96,23 +91,16 @@ if (!$row) {
$indexes[] = array("columns" => array(1 => "")); $indexes[] = array("columns" => array(1 => ""));
$row["indexes"] = $indexes; $row["indexes"] = $indexes;
} }
$lengths = (JUSH == "sql" || JUSH == "mssql");
$show_options = ($_POST ? $_POST["options"] : get_setting("index_options"));
?> ?>
<form action="" method="post"> <form action="" method="post">
<div class="scrollable"> <div class="scrollable">
<table class="nowrap"> <table cellspacing="0" class="nowrap">
<thead><tr> <thead><tr>
<th id="label-type"><?php echo lang('Index Type'); ?> <th id="label-type"><?php echo lang('Index Type'); ?>
<th><input type="submit" class="wayoff"><?php <th><input type="submit" class="wayoff"><?php echo lang('Column (length)'); ?>
echo lang('Column') . ($lengths ? "<span class='idxopts" . ($show_options ? "" : " hidden") . "'> (" . lang('length') . ")</span>" : "");
if ($lengths || support("descidx")) {
echo checkbox("options", 1, $show_options, lang('Options'), "indexOptionsShow(this.checked)", "jsonly") . "\n";
}
?>
<th id="label-name"><?php echo lang('Name'); ?> <th id="label-name"><?php echo lang('Name'); ?>
<th><noscript><?php echo icon("plus", "add[0]", "+", lang('Add next')); ?></noscript> <th><noscript><?php echo "<input type='image' class='icon' name='add[0]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>"; ?></noscript>
</thead> </thead>
<?php <?php
if ($primary) { if ($primary) {
@@ -126,7 +114,7 @@ if ($primary) {
$j = 1; $j = 1;
foreach ($row["indexes"] as $index) { foreach ($row["indexes"] as $index) {
if (!$_POST["drop_col"] || $j != key($_POST["drop_col"])) { 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);" : ""), "label-type"); 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 "<td>"; echo "<td>";
ksort($index["columns"]); ksort($index["columns"]);
@@ -136,17 +124,16 @@ foreach ($row["indexes"] as $index) {
" name='indexes[$j][columns][$i]' title='" . lang('Column') . "'", " name='indexes[$j][columns][$i]' title='" . lang('Column') . "'",
($fields ? array_combine($fields, $fields) : $fields), ($fields ? array_combine($fields, $fields) : $fields),
$column, $column,
"partial(" . ($i == count($index["columns"]) ? "indexesAddColumn" : "indexesChangeColumn") . ", '" . js_escape(JUSH == "sql" ? "" : $_GET["indexes"] . "_") . "')" "partial(" . ($i == count($index["columns"]) ? "indexesAddColumn" : "indexesChangeColumn") . ", '" . js_escape($jush == "sql" ? "" : $_GET["indexes"] . "_") . "')"
); );
echo "<span class='idxopts" . ($show_options ? "" : " hidden") . "'>"; echo ($jush == "sql" || $jush == "mssql" ? "<input type='number' name='indexes[$j][lengths][$i]' class='size' value='" . h($index["lengths"][$key]) . "' title='" . lang('Length') . "'>" : "");
echo ($lengths ? "<input type='number' name='indexes[$j][lengths][$i]' class='size' value='" . h(idx($index["lengths"], $key)) . "' title='" . lang('Length') . "'>" : ""); echo (support("descidx") ? checkbox("indexes[$j][descs][$i]", 1, $index["descs"][$key], lang('descending')) : "");
echo (support("descidx") ? checkbox("indexes[$j][descs][$i]", 1, idx($index["descs"], $key), lang('descending')) : ""); echo " </span>";
echo "</span> </span>";
$i++; $i++;
} }
echo "<td><input name='indexes[$j][name]' value='" . h($index["name"]) . "' autocapitalize='off' aria-labelledby='label-name'>\n"; echo "<td><input name='indexes[$j][name]' value='" . h($index["name"]) . "' autocapitalize='off' aria-labelledby='label-name'>\n";
echo "<td>" . icon("cross", "drop_col[$j]", "x", lang('Remove')) . script("qsl('button').onclick = partial(editingRemoveRow, 'indexes\$1[type]');"); echo "<td><input type='image' class='icon' name='drop_col[$j]' src='../adminer/static/cross.gif' alt='x' title='" . lang('Remove') . "'>" . script("qsl('input').onclick = partial(editingRemoveRow, 'indexes\$1[type]');");
} }
$j++; $j++;
} }
@@ -155,5 +142,5 @@ foreach ($row["indexes"] as $index) {
</div> </div>
<p> <p>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php echo input_token(); ?> <input type="hidden" name="token" value="<?php echo $token; ?>">
</form> </form>

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'تسجيل الدخول', 'Login' => 'تسجيل الدخول',
'Logout successful.' => 'تم تسجيل الخروج بنجاح.', 'Logout successful.' => 'تم تسجيل الخروج بنجاح.',
'Invalid credentials.' => 'بيانات الدخول غير صالحة.', 'Invalid server or credentials.' => null,
'Server' => 'الخادم', 'Server' => 'الخادم',
'Username' => 'اسم المستخدم', 'Username' => 'اسم المستخدم',
'Password' => 'كلمة المرور', 'Password' => 'كلمة المرور',
@@ -32,6 +30,7 @@ Lang::$translations = array(
'Create database' => 'إنشاء قاعدة بيانات', 'Create database' => 'إنشاء قاعدة بيانات',
'SQL command' => 'استعلام SQL', 'SQL command' => 'استعلام SQL',
'Logout' => 'تسجيل الخروج', 'Logout' => 'تسجيل الخروج',
'database' => 'قاعدة بيانات',
'Use' => 'استعمال', 'Use' => 'استعمال',
'No tables.' => 'لا توجد جداول.', 'No tables.' => 'لا توجد جداول.',
'select' => 'تحديد', 'select' => 'تحديد',
@@ -77,7 +76,7 @@ Lang::$translations = array(
'Routine has been called, %d row(s) affected.' => 'تم استدعاء الروتين, عدد الأسطر المعدلة %d.', 'Routine has been called, %d row(s) affected.' => 'تم استدعاء الروتين, عدد الأسطر المعدلة %d.',
'Call' => 'استدعاء', 'Call' => 'استدعاء',
'No extension' => 'امتداد غير موجود', 'No extension' => 'امتداد غير موجود',
'None of the supported PHP extensions (%s) are available.' => 'إمتدادات php (%s) المدعومة غير موجودة.', 'None of the supported PHP extensions (%s) are available.' => 'إمتدادات php المدعومة غير موجودة.',
'Session support must be enabled.' => 'عليك تفعيل نظام الجلسات.', 'Session support must be enabled.' => 'عليك تفعيل نظام الجلسات.',
'Session expired, please login again.' => 'إنتهت الجلسة، من فضلك أعد تسجيل الدخول.', 'Session expired, please login again.' => 'إنتهت الجلسة، من فضلك أعد تسجيل الدخول.',
'Text length' => 'طول النص', 'Text length' => 'طول النص',
@@ -95,7 +94,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'نوع المؤشر', 'Index Type' => 'نوع المؤشر',
'length' => 'الطول', 'Column (length)' => 'العمود (الطول)',
'View has been dropped.' => 'تم مسح العرض.', 'View has been dropped.' => 'تم مسح العرض.',
'View has been altered.' => 'تم تعديل العرض.', 'View has been altered.' => 'تم تعديل العرض.',
'View has been created.' => 'تم إنشاء العرض.', 'View has been created.' => 'تم إنشاء العرض.',
@@ -171,8 +170,8 @@ Lang::$translations = array(
'Tables and views' => 'الجداول و العروض', 'Tables and views' => 'الجداول و العروض',
'Engine' => 'المحرك', 'Engine' => 'المحرك',
'Collation' => 'ترتيب', 'Collation' => 'ترتيب',
'Data Length' => 'طول المعطيات', 'Data Length' => 'طول المعطيات.',
'Index Length' => 'طول المؤشر', 'Index Length' => 'طول المؤشر.',
'Data Free' => 'المساحة الحرة', 'Data Free' => 'المساحة الحرة',
'Rows' => 'الأسطر', 'Rows' => 'الأسطر',
',' => ',', ',' => ',',
@@ -192,7 +191,7 @@ Lang::$translations = array(
'Partitions' => 'التقسيمات', 'Partitions' => 'التقسيمات',
'Partition name' => 'اسم التقسيم', 'Partition name' => 'اسم التقسيم',
'Values' => 'القيم', 'Values' => 'القيم',
'%d row(s) have been imported.' => 'تم استيراد %d سطرا.', '%d row(s) have been imported.' => 'تم استيراد %d سطرا',
'anywhere' => 'في اي مكان', 'anywhere' => 'في اي مكان',
'Import' => 'استيراد', 'Import' => 'استيراد',
'Stop on error' => 'أوقف في حالة حدوث خطأ', 'Stop on error' => 'أوقف في حالة حدوث خطأ',
@@ -251,8 +250,8 @@ Lang::$translations = array(
'Network' => 'شبكة', 'Network' => 'شبكة',
'Geometry' => 'هندسة', 'Geometry' => 'هندسة',
'File exists.' => 'الملف موجود.', 'File exists.' => 'الملف موجود.',
'Attachments' => 'ملفات مرفقة', 'Attachments' => 'ملفات مرفقة.',
'Item%s has been inserted.' => '%sتم إدراج العنصر.', 'Item%s has been inserted.' => 'تم إدراج العنصر.',
'now' => 'الآن', 'now' => 'الآن',
'%d query(s) executed OK.' => array('تم تنفيذ الاستعلام %d بنجاح.', 'تم تنفيذ الاستعلامات %d بنجاح.'), '%d query(s) executed OK.' => array('تم تنفيذ الاستعلام %d بنجاح.', 'تم تنفيذ الاستعلامات %d بنجاح.'),
'Show only errors' => 'إظهار الأخطاء فقط', 'Show only errors' => 'إظهار الأخطاء فقط',
@@ -265,6 +264,42 @@ Lang::$translations = array(
'Permanent link' => 'رابط دائم', 'Permanent link' => 'رابط دائم',
'Edit all' => 'تعديل الكل', 'Edit all' => 'تعديل الكل',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
);
// run `php ../../lang.php ar` to update this file 'Drop %s?' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'overwrite' => null,
'DB' => null,
'Ctrl+click on a value to modify it.' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Система', 'System' => 'Система',
'Server' => 'Сървър', 'Server' => 'Сървър',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Изход', 'Logout' => 'Изход',
'Logged as: %s' => 'Текущ потребител: %s', 'Logged as: %s' => 'Текущ потребител: %s',
'Logout successful.' => 'Излизането е успешно.', 'Logout successful.' => 'Излизането е успешно.',
'Invalid credentials.' => 'Невалидни потребителски данни.', 'Invalid server or credentials.' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array('Прекалено много неуспешни опити за вход, опитайте пак след %d минута.', 'Прекалено много неуспешни опити за вход, опитайте пак след %d минути.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Прекалено много неуспешни опити за вход, опитайте пак след %d минута.', 'Прекалено много неуспешни опити за вход, опитайте пак след %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 метод, за да я направите постоянна.', '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 метод, за да я направите постоянна.',
'Language' => 'Език', 'Language' => 'Език',
@@ -80,6 +78,7 @@ Lang::$translations = array(
'Data' => 'Данни', 'Data' => 'Данни',
'Database' => 'База данни', 'Database' => 'База данни',
'database' => 'база данни',
'Use' => 'Избор', 'Use' => 'Избор',
'Select database' => 'Избор на база данни', 'Select database' => 'Избор на база данни',
'Invalid database.' => 'Невалидна база данни.', 'Invalid database.' => 'Невалидна база данни.',
@@ -194,7 +193,7 @@ Lang::$translations = array(
'Alter indexes' => 'Промяна на индекси', 'Alter indexes' => 'Промяна на индекси',
'Add next' => 'Добавяне на следващ', 'Add next' => 'Добавяне на следващ',
'Index Type' => 'Вид на индекса', 'Index Type' => 'Вид на индекса',
'length' => 'дължина', 'Column (length)' => 'Колона (дължина)',
'Foreign keys' => 'Препратки', 'Foreign keys' => 'Препратки',
'Foreign key' => 'Препратка', 'Foreign key' => 'Препратка',
@@ -256,7 +255,7 @@ Lang::$translations = array(
// in-place editing in select // in-place editing in select
'Modify' => 'Промяна', 'Modify' => 'Промяна',
'Ctrl+click on a value to modify it.' => 'Ctrl+щракване в стойността, за да я промените.', '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 // %s can contain auto-increment value
'Item%s has been inserted.' => 'Елементи%s бяха вмъкнати.', 'Item%s has been inserted.' => 'Елементи%s бяха вмъкнати.',
@@ -334,6 +333,18 @@ Lang::$translations = array(
'Type has been dropped.' => 'Вида беше пермахнат.', 'Type has been dropped.' => 'Вида беше пермахнат.',
'Type has been created.' => 'Вида беше създаден.', 'Type has been created.' => 'Вида беше създаден.',
'Alter type' => 'Промяна на вид', 'Alter type' => 'Промяна на вид',
);
// run `php ../../lang.php bg` to update this file 'Drop %s?' => null,
'overwrite' => null,
'DB' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'লগইন', 'Login' => 'লগইন',
'Logout successful.' => 'সফলভাবে লগআউট হয়েছে।', 'Logout successful.' => 'সফলভাবে লগআউট হয়েছে।',
'Invalid credentials.' => 'ভুল পাসওয়ার্ড।', 'Invalid server or credentials.' => null,
'Server' => 'সার্ভার', 'Server' => 'সার্ভার',
'Username' => 'ইউজারের নাম', 'Username' => 'ইউজারের নাম',
'Password' => 'পাসওয়ার্ড', 'Password' => 'পাসওয়ার্ড',
@@ -33,12 +31,13 @@ Lang::$translations = array(
'Create database' => 'ডাটাবেজ তৈরী করুন', 'Create database' => 'ডাটাবেজ তৈরী করুন',
'SQL command' => 'SQL-কমান্ড', 'SQL command' => 'SQL-কমান্ড',
'Logout' => 'লগআউট', 'Logout' => 'লগআউট',
'database' => 'ডাটাবেজ',
'Use' => 'ব্যবহার', 'Use' => 'ব্যবহার',
'No tables.' => 'কোন টেবিল নাই।', 'No tables.' => 'কোন টেবিল নাই।',
'select' => 'নির্বাচন', 'select' => 'নির্বাচন',
'Item has been deleted.' => 'বিষয়বস্তু মুছে ফেলা হয়েছে।', 'Item has been deleted.' => 'বিষয়বস্তু মুছে ফেলা হয়েছে।',
'Item has been updated.' => 'বিষয়বস্তু হালনাগাদ করা হয়েছে।', 'Item has been updated.' => 'বিষয়বস্তু হালনাগাদ করা হয়েছে।',
'Item%s has been inserted.' => 'বিষয়বস্তুসমূহ%s সংযোজন করা হয়েছে।', 'Item%s has been inserted.' => 'বিষয়বস্তুসমূহ সংযোজন করা হয়েছে।',
'Edit' => 'সম্পাদনা', 'Edit' => 'সম্পাদনা',
'Insert' => 'সংযোজন', 'Insert' => 'সংযোজন',
'Save and insert next' => 'সংরক্ষন ও পরবর্তী সংযোজন করুন', 'Save and insert next' => 'সংরক্ষন ও পরবর্তী সংযোজন করুন',
@@ -61,7 +60,7 @@ Lang::$translations = array(
'edit' => 'সম্পাদনা', 'edit' => 'সম্পাদনা',
'Page' => 'পৃষ্ঠা', 'Page' => 'পৃষ্ঠা',
'Query executed OK, %d row(s) affected.' => array('কোয়্যারী সম্পাদন হয়েছে, %d সারি প্রভাবিত হয়েছে।', 'কোয়্যারী সম্পাদন হয়েছে, %d সারি প্রভাবিত হয়েছে।'), 'Query executed OK, %d row(s) affected.' => array('কোয়্যারী সম্পাদন হয়েছে, %d সারি প্রভাবিত হয়েছে।', 'কোয়্যারী সম্পাদন হয়েছে, %d সারি প্রভাবিত হয়েছে।'),
'Error in query' => 'অনুসন্ধানে ভুল আছে', 'Error in query' => 'অনুসন্ধানে ভুল আছে',
'Execute' => 'সম্পাদন করো', 'Execute' => 'সম্পাদন করো',
'Table' => 'টেবিল', 'Table' => 'টেবিল',
'Foreign keys' => 'ফরেন কী', 'Foreign keys' => 'ফরেন কী',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'অন ডিলিট', 'ON DELETE' => 'অন ডিলিট',
'ON UPDATE' => 'অন আপডেট', 'ON UPDATE' => 'অন আপডেট',
'Index Type' => 'সূচী-ধরণ', 'Index Type' => 'সূচী-ধরণ',
'length' => 'দৈর্ঘ্য', 'Column (length)' => 'কলাম (দৈর্ঘ্য)',
'View has been dropped.' => 'ভিউ মুছে ফেলা হয়েছে।', 'View has been dropped.' => 'ভিউ মুছে ফেলা হয়েছে।',
'View has been altered.' => 'ভিউ পরিবর্তন করা হয়েছে।', 'View has been altered.' => 'ভিউ পরিবর্তন করা হয়েছে।',
'View has been created.' => 'ভিউ তৈরী করা হয়েছে।', 'View has been created.' => 'ভিউ তৈরী করা হয়েছে।',
@@ -139,7 +138,7 @@ Lang::$translations = array(
'Routine' => 'রুটিন', 'Routine' => 'রুটিন',
'Grant' => 'অনুমতি', 'Grant' => 'অনুমতি',
'Revoke' => 'প্রত্যাহার', 'Revoke' => 'প্রত্যাহার',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'খুব বড় POST ডাটা। ডাটা সংক্ষিপ্ত করো অথবা %s কনফিগারেশন নির্দেশ বৃদ্ধি করো', 'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'খুব বড় POST ডাটা। ডাটা সংক্ষিপ্ত করো অথবা %s কনফিগারেশন নির্দেশ বৃদ্ধি করো',
'Logged as: %s' => '%s হিসাবে লগড', 'Logged as: %s' => '%s হিসাবে লগড',
'Move up' => 'উপরে স্থানান্তর', 'Move up' => 'উপরে স্থানান্তর',
'Move down' => 'নীচে স্থানান্তর', 'Move down' => 'নীচে স্থানান্তর',
@@ -175,7 +174,7 @@ Lang::$translations = array(
'Check' => 'পরীক্ষা', 'Check' => 'পরীক্ষা',
'Repair' => 'মেরামত', 'Repair' => 'মেরামত',
'Truncate' => 'ছাঁটাই', 'Truncate' => 'ছাঁটাই',
'Tables have been truncated.' => 'টেবিল ছাঁটাই করা হয়েছে', 'Tables have been truncated.' => 'টেবিল ছাঁটাই করা হয়েছে',
'Rows' => 'সারিসমূহ', 'Rows' => 'সারিসমূহ',
',' => ',', ',' => ',',
'0123456789' => '০১২৩৪৫৬৭৮৯', '0123456789' => '০১২৩৪৫৬৭৮৯',
@@ -186,7 +185,7 @@ Lang::$translations = array(
'Save and continue edit' => 'সংরক্ষণ করুন এবং সম্পাদনা চালিয়ে যান', 'Save and continue edit' => 'সংরক্ষণ করুন এবং সম্পাদনা চালিয়ে যান',
'original' => 'প্রকৃত', 'original' => 'প্রকৃত',
'Tables have been dropped.' => 'টেবিলসমূহ মুছে ফেলা হয়েছে।', 'Tables have been dropped.' => 'টেবিলসমূহ মুছে ফেলা হয়েছে।',
'%d item(s) have been affected.' => '%d টি বিষয়বস্তু প্রভাবিত হয়েছে', '%d item(s) have been affected.' => '%d টি বিষয়বস্তু প্রভাবিত হয়েছে',
'Whole result' => 'সম্পূর্ণ ফলাফল', 'Whole result' => 'সম্পূর্ণ ফলাফল',
'Clone' => 'ক্লোন', 'Clone' => 'ক্লোন',
'Maximum number of allowed fields exceeded. Please increase %s.' => 'অনুমোদিত ফিল্ড এর সর্বাধিক সংখ্যা অতিক্রম করে গেছে। অনুগ্রহপূর্বক %s বৃদ্ধি করুন।', 'Maximum number of allowed fields exceeded. Please increase %s.' => 'অনুমোদিত ফিল্ড এর সর্বাধিক সংখ্যা অতিক্রম করে গেছে। অনুগ্রহপূর্বক %s বৃদ্ধি করুন।',
@@ -207,7 +206,7 @@ Lang::$translations = array(
'Relations' => 'সম্পর্ক', 'Relations' => 'সম্পর্ক',
'Run file' => 'ফাইল চালাও', 'Run file' => 'ফাইল চালাও',
'Clear' => 'সাফ করো', 'Clear' => 'সাফ করো',
'Maximum allowed file size is %sB.' => 'সর্বাধিক অনুমোদিত ফাইল সাইজ %sB', 'Maximum allowed file size is %sB.' => 'সর্বাধিক অনুমোদিত ফাইল সাইজ %sB.',
'Numbers' => 'সংখ্যা', 'Numbers' => 'সংখ্যা',
'Date and time' => 'তারিখ এবং সময়', 'Date and time' => 'তারিখ এবং সময়',
'Strings' => 'স্ট্রিং', 'Strings' => 'স্ট্রিং',
@@ -253,7 +252,7 @@ Lang::$translations = array(
'Geometry' => 'জ্যামিতি', 'Geometry' => 'জ্যামিতি',
'File exists.' => 'ফাইল রয়েছে।', 'File exists.' => 'ফাইল রয়েছে।',
'Attachments' => 'সংযুক্তিগুলো', 'Attachments' => 'সংযুক্তিগুলো',
'%d query(s) executed OK.' => array('SQL-অনুসন্ধান সফলভাবে সম্পন্ন হয়েছে', '%d SQL-অনুসন্ধানসমূহ সফলভাবে সম্পন্ন হয়েছে'), '%d query(s) executed OK.' => array('SQL-অনুসন্ধান সফলভাবে সম্পন্ন হয়েছে', '%d SQL-অনুসন্ধানসমূহ সফলভাবে সম্পন্ন হয়েছে'),
'Show only errors' => 'শুধুমাত্র ত্রুটিগুলো দেখান', 'Show only errors' => 'শুধুমাত্র ত্রুটিগুলো দেখান',
'Refresh' => 'রিফ্রেশ', 'Refresh' => 'রিফ্রেশ',
'Invalid schema.' => 'অবৈধ স্কিমা।', 'Invalid schema.' => 'অবৈধ স্কিমা।',
@@ -265,6 +264,42 @@ Lang::$translations = array(
'Permanent link' => 'স্থায়ী লিংক', 'Permanent link' => 'স্থায়ী লিংক',
'Edit all' => 'সবগুলো সম্পাদনা করুন', 'Edit all' => 'সবগুলো সম্পাদনা করুন',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
);
// run `php ../../lang.php bn` to update this file 'Drop %s?' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'overwrite' => null,
'DB' => null,
'Ctrl+click on a value to modify it.' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem', 'System' => 'Sistem',
'Server' => 'Server', 'Server' => 'Server',
@@ -12,11 +10,11 @@ Lang::$translations = array(
'Logout' => 'Odjava', 'Logout' => 'Odjava',
'Logged as: %s' => 'Prijavi se kao: %s', 'Logged as: %s' => 'Prijavi se kao: %s',
'Logout successful.' => 'Uspešna odjava.', 'Logout successful.' => 'Uspešna odjava.',
'Invalid credentials.' => 'Nevažeće dozvole.', 'Invalid server or credentials.' => null,
'Language' => 'Jezik', 'Language' => 'Jezik',
'Invalid CSRF token. Send the form again.' => 'Nevažeći CSRF kod. Proslijedite ponovo formu.', 'Invalid CSRF token. Send the form again.' => 'Nevažeći CSRF kod. Proslijedite ponovo formu.',
'No extension' => 'Bez dodataka', 'No extension' => 'Bez dodataka',
'None of the supported PHP extensions (%s) are available.' => 'Nijedan od podržanih PHP dodataka (%s) nije dostupan.', 'None of the supported PHP extensions (%s) are available.' => 'Nijedan od podržanih PHP dodataka nije dostupan.',
'Session support must be enabled.' => 'Morate omogućiti podršku za sesije.', 'Session support must be enabled.' => 'Morate omogućiti podršku za sesije.',
'Session expired, please login again.' => 'Vaša sesija je istekla, prijavite se ponovo.', 'Session expired, please login again.' => 'Vaša sesija je istekla, prijavite se ponovo.',
'%s version: %s through PHP extension %s' => '%s verzija: %s pomoću PHP dodatka je %s', '%s version: %s through PHP extension %s' => '%s verzija: %s pomoću PHP dodatka je %s',
@@ -75,6 +73,7 @@ Lang::$translations = array(
'Data' => 'Podaci', 'Data' => 'Podaci',
'Database' => 'Baza podataka', 'Database' => 'Baza podataka',
'database' => 'baza podataka',
'Use' => 'Koristi', 'Use' => 'Koristi',
'Select database' => 'Izaberite bazu', 'Select database' => 'Izaberite bazu',
'Invalid database.' => 'Neispravna baza podataka.', 'Invalid database.' => 'Neispravna baza podataka.',
@@ -184,7 +183,7 @@ Lang::$translations = array(
'Alter indexes' => 'Ažuriraj indekse', 'Alter indexes' => 'Ažuriraj indekse',
'Add next' => 'Dodaj slijedeći', 'Add next' => 'Dodaj slijedeći',
'Index Type' => 'Tip indeksa', 'Index Type' => 'Tip indeksa',
'length' => 'dužina', 'Column (length)' => 'kolumna (dužina)',
'Foreign keys' => 'Strani ključevi', 'Foreign keys' => 'Strani ključevi',
'Foreign key' => 'Strani ključ', 'Foreign key' => 'Strani ključ',
@@ -319,6 +318,33 @@ Lang::$translations = array(
'Type has been dropped.' => 'Tip je izbrisan.', 'Type has been dropped.' => 'Tip je izbrisan.',
'Type has been created.' => 'tip je spašen.', 'Type has been created.' => 'tip je spašen.',
'Alter type' => 'Ažuriraj tip', 'Alter type' => 'Ažuriraj tip',
);
// run `php ../../lang.php bs` to update this file 'Drop %s?' => null,
'Materialized view' => null,
'Vacuum' => null,
'overwrite' => null,
'DB' => null,
'File must be in UTF-8 encoding.' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Inicia la sessió', 'Login' => 'Inicia la sessió',
'Logout successful.' => 'Desconnexió correcta.', 'Logout successful.' => 'Desconnexió correcta.',
'Invalid credentials.' => 'Credencials invàlides.', 'Invalid server or credentials.' => null,
'Server' => 'Servidor', 'Server' => 'Servidor',
'Username' => 'Nom d\'usuari', 'Username' => 'Nom d\'usuari',
'Password' => 'Contrasenya', 'Password' => 'Contrasenya',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Crea una base de dades', 'Create database' => 'Crea una base de dades',
'SQL command' => 'Ordre SQL', 'SQL command' => 'Ordre SQL',
'Logout' => 'Desconnecta', 'Logout' => 'Desconnecta',
'database' => 'base de dades',
'Use' => 'Utilitza', 'Use' => 'Utilitza',
'No tables.' => 'No hi ha cap taula.', 'No tables.' => 'No hi ha cap taula.',
'select' => 'registres', 'select' => 'registres',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Tipus d\'índex', 'Index Type' => 'Tipus d\'índex',
'length' => 'longitud', 'Column (length)' => 'Columna (longitud)',
'View has been dropped.' => 'S\'ha suprimit la vista.', 'View has been dropped.' => 'S\'ha suprimit la vista.',
'View has been altered.' => 'S\'ha modificat la vista.', 'View has been altered.' => 'S\'ha modificat la vista.',
'View has been created.' => 'S\'ha creat la vista.', 'View has been created.' => 'S\'ha creat la vista.',
@@ -266,6 +265,41 @@ Lang::$translations = array(
'Permanent link' => 'Enllaç permanent', 'Permanent link' => 'Enllaç permanent',
'Edit all' => 'Edita-ho tot', 'Edit all' => 'Edita-ho tot',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
);
// run `php ../../lang.php ca` to update this file 'Drop %s?' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'overwrite' => null,
'DB' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Systém', 'System' => 'Systém',
'Server' => 'Server', 'Server' => 'Server',
@@ -13,10 +11,7 @@ Lang::$translations = array(
'Logged as: %s' => 'Přihlášen jako: %s', 'Logged as: %s' => 'Přihlášen jako: %s',
'Logout successful.' => 'Odhlášení proběhlo v pořádku.', '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.', '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', 'Invalid server or credentials.' => 'Neplatný server nebo přihlašovací údaje.',
'%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.', '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>.', '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>.',
'Database does not support password.' => 'Databáze nepodporuje heslo.', 'Database does not support password.' => 'Databáze nepodporuje heslo.',
@@ -93,6 +88,7 @@ Lang::$translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Databáze', 'Database' => 'Databáze',
'database' => 'databáze',
'DB' => 'DB', 'DB' => 'DB',
'Use' => 'Vybrat', 'Use' => 'Vybrat',
'Select database' => 'Vybrat databázi', 'Select database' => 'Vybrat databázi',
@@ -210,7 +206,7 @@ Lang::$translations = array(
'Alter indexes' => 'Pozměnit indexy', 'Alter indexes' => 'Pozměnit indexy',
'Add next' => 'Přidat další', 'Add next' => 'Přidat další',
'Index Type' => 'Typ indexu', 'Index Type' => 'Typ indexu',
'length' => 'délka', 'Column (length)' => 'Sloupec (délka)',
'Foreign keys' => 'Cizí klíče', 'Foreign keys' => 'Cizí klíče',
'Foreign key' => 'Cizí klíč', 'Foreign key' => 'Cizí klíč',
@@ -260,8 +256,8 @@ Lang::$translations = array(
'%d row(s)' => array('%d řádek', '%d řádky', '%d řádků'), '%d row(s)' => array('%d řádek', '%d řádky', '%d řádků'),
'Page' => 'Stránka', 'Page' => 'Stránka',
'last' => 'poslední', 'last' => 'poslední',
'Load more data' => 'Načíst další data', 'Load more data' => 'Nahrát další data',
'Loading' => 'Načítá se', 'Loading' => 'Nahrává se',
'Whole result' => 'Celý výsledek', 'Whole result' => 'Celý výsledek',
'%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtů'), '%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtů'),
@@ -350,14 +346,4 @@ Lang::$translations = array(
'Type has been dropped.' => 'Typ byl odstraněn.', 'Type has been dropped.' => 'Typ byl odstraněn.',
'Type has been created.' => 'Typ byl vytvořen.', 'Type has been created.' => 'Typ byl vytvořen.',
'Alter type' => 'Pozměnit typ', 'Alter type' => 'Pozměnit typ',
// Table check constraints
'Checks' => 'Kontroly',
'Create check' => 'Vytvořit kontrolu',
'Alter check' => 'Změnit kontrolu',
'Check has been created.' => 'Kontrola byla vytvořena.',
'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

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'System' => 'System', 'System' => 'System',
'Server' => 'Server', 'Server' => 'Server',
'Username' => 'Brugernavn', 'Username' => 'Brugernavn',
@@ -11,7 +9,7 @@ Lang::$translations = array(
'Logout' => 'Log ud', 'Logout' => 'Log ud',
'Logged as: %s' => 'Logget ind som: %s', 'Logged as: %s' => 'Logget ind som: %s',
'Logout successful.' => 'Log af vellykket.', 'Logout successful.' => 'Log af vellykket.',
'Invalid credentials.' => 'Ugyldige log ind oplysninger.', 'Invalid server or credentials.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-kodeordet er udløbet. <a href="https://www.adminer.org/en/extension/"%s>Implementer</a> en metode for %s for at gøre det permanent.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-kodeordet er udløbet. <a href="https://www.adminer.org/en/extension/"%s>Implementer</a> en metode for %s for at gøre det permanent.',
'Language' => 'Sprog', 'Language' => 'Sprog',
'Invalid CSRF token. Send the form again.' => 'Ugyldigt CSRF-token - Genindsend formen.', 'Invalid CSRF token. Send the form again.' => 'Ugyldigt CSRF-token - Genindsend formen.',
@@ -66,6 +64,7 @@ Lang::$translations = array(
'Format' => 'Format', 'Format' => 'Format',
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Database', 'Database' => 'Database',
'database' => 'database',
'Use' => 'Brug', 'Use' => 'Brug',
'Select database' => 'Vælg database', 'Select database' => 'Vælg database',
'Invalid database.' => 'Ugyldig database.', 'Invalid database.' => 'Ugyldig database.',
@@ -166,7 +165,7 @@ Lang::$translations = array(
'Alter indexes' => 'Ændre indekser', 'Alter indexes' => 'Ændre indekser',
'Add next' => 'Læg til næste', 'Add next' => 'Læg til næste',
'Index Type' => 'Indekstype', 'Index Type' => 'Indekstype',
'length' => 'længde', 'Column (length)' => 'Kolonne (længde)',
'Foreign keys' => 'Fremmednøgler', 'Foreign keys' => 'Fremmednøgler',
'Foreign key' => 'Fremmednøgle', 'Foreign key' => 'Fremmednøgle',
'Foreign key has been dropped.' => 'Fremmednøglen er slettet.', 'Foreign key has been dropped.' => 'Fremmednøglen er slettet.',
@@ -280,6 +279,27 @@ Lang::$translations = array(
'Type has been created.' => 'Typen er oprettet.', 'Type has been created.' => 'Typen er oprettet.',
'Alter type' => 'Ændre type', 'Alter type' => 'Ændre type',
'Saving' => 'Gemmer', 'Saving' => 'Gemmer',
);
// run `php ../../lang.php da` to update this file 'Drop %s?' => null,
'Materialized view' => null,
'overwrite' => null,
'DB' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,11 +1,9 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Login', 'Login' => 'Login',
'Logout successful.' => 'Abmeldung erfolgreich.', 'Logout successful.' => 'Abmeldung erfolgreich.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Danke, dass Sie Adminer genutzt haben. <a href="https://www.adminer.org/de/donation/">Spenden willkommen!</a>.', 'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Danke, dass Sie Adminer genutzt haben. <a href="https://www.adminer.org/de/donation/">Spenden willkommen!</a>',
'Invalid credentials.' => 'Ungültige Anmelde-Informationen.', 'Invalid server or credentials.' => 'Ungültige Server oder Anmelde-Informationen.',
'Server' => 'Server', 'Server' => 'Server',
'Username' => 'Benutzer', 'Username' => 'Benutzer',
'Password' => 'Passwort', 'Password' => 'Passwort',
@@ -34,7 +32,8 @@ Lang::$translations = array(
'Create database' => 'Datenbank erstellen', 'Create database' => 'Datenbank erstellen',
'SQL command' => 'SQL-Kommando', 'SQL command' => 'SQL-Kommando',
'Logout' => 'Abmelden', 'Logout' => 'Abmelden',
'Use' => 'Auswählen', 'database' => 'Datenbank',
'Use' => 'Benutzung',
'No tables.' => 'Keine Tabellen.', 'No tables.' => 'Keine Tabellen.',
'select' => 'zeigen', 'select' => 'zeigen',
'Item has been deleted.' => 'Datensatz wurde gelöscht.', 'Item has been deleted.' => 'Datensatz wurde gelöscht.',
@@ -98,7 +97,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Index-Typ', 'Index Type' => 'Index-Typ',
'length' => 'Länge', 'Column (length)' => 'Spalte (Länge)',
'View has been dropped.' => 'View wurde entfernt.', 'View has been dropped.' => 'View wurde entfernt.',
'View has been altered.' => 'View wurde geändert.', 'View has been altered.' => 'View wurde geändert.',
'View has been created.' => 'View wurde erstellt.', 'View has been created.' => 'View wurde erstellt.',
@@ -281,33 +280,26 @@ Lang::$translations = array(
'If you did not send this request from Adminer then close this page.' => 'Wenn Sie diese Anfrage nicht von Adminer gesendet haben, schließen Sie diese Seite.', 'If you did not send this request from Adminer then close this page.' => 'Wenn Sie diese Anfrage nicht von Adminer gesendet haben, schließen Sie diese Seite.',
'You can upload a big SQL file via FTP and import it from server.' => 'Sie können eine große SQL-Datei per FTP hochladen und dann vom Server importieren.', 'You can upload a big SQL file via FTP and import it from server.' => 'Sie können eine große SQL-Datei per FTP hochladen und dann vom Server importieren.',
'You are offline.' => 'Sie sind offline.', 'You are offline.' => 'Sie sind offline.',
'You have no privileges to update this table.' => 'Sie haben keine Rechte, diese Tabelle zu aktualisieren.', 'You have no privileges to update this table.' => 'Sie haben keine Rechte, um diese Tabelle zu aktualisieren.',
'Saving' => 'Speichere', 'Saving' => 'Speichere',
'yes' => 'ja', 'yes' => 'ja',
'no' => 'nein', 'no' => 'nein',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Das Master-Passwort ist abgelaufen. <a href="https://www.adminer.org/de/extension/"%s>Implementieren</a> Sie die %s Methode, um es permanent zu machen.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Das Master-Passwort ist abgelaufen. <a href="https://www.adminer.org/de/extension/"%s>Implementieren</a> Sie die %s Methode, um es permanent zu machen.',
'%d / ' => '%d / ', '%d / ' => '%d / ',
'Drop %s?' => '%s entfernen?',
'Materialized view' => 'Strukturierte Ansicht',
'Vacuum' => 'Vacuum',
'overwrite' => 'überschreiben',
'DB' => 'DB',
'ATTACH queries are not supported.' => 'ATTACH Abfragen werden nicht unterstützt.',
'Warnings' => 'Warnungen',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer unterstützt den Zugriff auf eine Datenbank ohne Passwort nicht, <a href="https://www.adminer.org/de/password/"%s>mehr Informationen</a>.',
'Full table scan' => 'Vollständige Überprüfung der Tabelle',
'The action will be performed after successful login with the same credentials.' => 'Die Aktion wird nach erfolgreicher Anmeldung mit denselben Anmeldedaten ausgeführt.',
'Connecting to privileged ports is not allowed.' => 'Die Verbindung zu privilegierten Ports ist nicht erlaubt.',
'There is a space in the input password which might be the cause.' => 'Es gibt ein Leerzeichen im Eingabepasswort, das die Ursache sein könnte.',
'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 'Drop %s?' => null,
'Materialized view' => null,
'Vacuum' => null,
'overwrite' => null,
'DB' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Full table scan' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Σύστημα', 'System' => 'Σύστημα',
'Server' => 'Διακομιστής', 'Server' => 'Διακομιστής',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Αποσύνδεση', 'Logout' => 'Αποσύνδεση',
'Logged as: %s' => 'Συνδεθήκατε ως %s', 'Logged as: %s' => 'Συνδεθήκατε ως %s',
'Logout successful.' => 'Αποσυνδεθήκατε με επιτυχία.', 'Logout successful.' => 'Αποσυνδεθήκατε με επιτυχία.',
'Invalid credentials.' => 'Εσφαλμένα Διαπιστευτήρια.', 'Invalid server or credentials.' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array('Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτό.', 'Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτά.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτό.', 'Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτά.'),
'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 για να τον κάνετε μόνιμο.', '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 για να τον κάνετε μόνιμο.',
'Language' => 'Γλώσσα', 'Language' => 'Γλώσσα',
@@ -81,6 +79,7 @@ Lang::$translations = array(
'Data' => 'Δεδομένα', 'Data' => 'Δεδομένα',
'Database' => 'Β. Δεδομένων', 'Database' => 'Β. Δεδομένων',
'database' => 'β. δεδομένων',
'Use' => 'χρήση', 'Use' => 'χρήση',
'Select database' => 'Επιλέξτε Β.Δ.', 'Select database' => 'Επιλέξτε Β.Δ.',
'Invalid database.' => 'Λανθασμένη Β.Δ.', 'Invalid database.' => 'Λανθασμένη Β.Δ.',
@@ -195,7 +194,7 @@ Lang::$translations = array(
'Alter indexes' => 'Τροποποίηση δεικτών', 'Alter indexes' => 'Τροποποίηση δεικτών',
'Add next' => 'Προσθήκη επόμενου', 'Add next' => 'Προσθήκη επόμενου',
'Index Type' => 'Τύπος δείκτη', 'Index Type' => 'Τύπος δείκτη',
'length' => 'μήκος', 'Column (length)' => 'Στήλη (μήκος)',
'Foreign keys' => 'Εξαρτημένα κλειδιά', 'Foreign keys' => 'Εξαρτημένα κλειδιά',
'Foreign key' => 'Εξαρτημένο κλειδί', 'Foreign key' => 'Εξαρτημένο κλειδί',
@@ -334,6 +333,18 @@ Lang::$translations = array(
'Type has been dropped.' => 'Ο τύπος διαγράφηκε.', 'Type has been dropped.' => 'Ο τύπος διαγράφηκε.',
'Type has been created.' => 'Ο τύπος δημιουργήθηκε.', 'Type has been created.' => 'Ο τύπος δημιουργήθηκε.',
'Alter type' => 'Τροποποίηση τύπου', 'Alter type' => 'Τροποποίηση τύπου',
);
// run `php ../../lang.php el` to update this file 'Drop %s?' => null,
'overwrite' => null,
'DB' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Too many unsuccessful logins, try again in %d minute(s).' => array('Too many unsuccessful logins, try again in %d minute.', 'Too many unsuccessful logins, try again in %d minutes.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Too many unsuccessful logins, try again in %d minute.', 'Too many unsuccessful logins, try again in %d minutes.'),
'Query executed OK, %d row(s) affected.' => array('Query executed OK, %d row affected.', 'Query executed OK, %d rows affected.'), 'Query executed OK, %d row(s) affected.' => array('Query executed OK, %d row affected.', 'Query executed OK, %d rows affected.'),
'%d byte(s)' => array('%d byte', '%d bytes'), '%d byte(s)' => array('%d byte', '%d bytes'),
@@ -15,5 +13,3 @@ Lang::$translations = array(
'%d in total' => '%d in total', '%d in total' => '%d in total',
'%d query(s) executed OK.' => array('%d query executed OK.', '%d queries executed OK.'), '%d query(s) executed OK.' => array('%d query executed OK.', '%d queries executed OK.'),
); );
// run `php ../../lang.php en` to update this file

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Login', 'Login' => 'Login',
'Logout successful.' => 'Sesión finalizada con éxito.', 'Logout successful.' => 'Sesión finalizada con éxito.',
'Invalid credentials.' => 'Usuario y/o clave de acceso incorrecta.', 'Invalid server or credentials.' => null,
'Server' => 'Servidor', 'Server' => 'Servidor',
'Username' => 'Usuario', 'Username' => 'Usuario',
'Password' => 'Contraseña', 'Password' => 'Contraseña',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Crear Base de datos', 'Create database' => 'Crear Base de datos',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Cerrar sesión', 'Logout' => 'Cerrar sesión',
'database' => 'base de datos',
'Use' => 'Usar', 'Use' => 'Usar',
'No tables.' => 'No existen tablas.', 'No tables.' => 'No existen tablas.',
'select' => 'registros', 'select' => 'registros',
@@ -44,7 +43,6 @@ Lang::$translations = array(
'Save and insert next' => 'Guardar e insertar siguiente', 'Save and insert next' => 'Guardar e insertar siguiente',
'Delete' => 'Eliminar', 'Delete' => 'Eliminar',
'Database' => 'Base de datos', 'Database' => 'Base de datos',
'DB' => 'BD',
'Routines' => 'Procedimientos', 'Routines' => 'Procedimientos',
'Indexes have been altered.' => 'Índices actualizados.', 'Indexes have been altered.' => 'Índices actualizados.',
'Indexes' => 'Índices', 'Indexes' => 'Índices',
@@ -63,22 +61,18 @@ Lang::$translations = array(
'Page' => 'Página', 'Page' => 'Página',
'Query executed OK, %d row(s) affected.' => array('Consulta ejecutada, %d registro afectado.', 'Consulta ejecutada, %d registros afectados.'), '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', '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', 'Execute' => 'Ejecutar',
'Table' => 'Tabla', 'Table' => 'Tabla',
'Foreign keys' => 'Claves externas', 'Foreign keys' => 'Claves externas',
'Triggers' => 'Disparadores', 'Triggers' => 'Disparadores',
'View' => 'Vista', 'View' => 'Vista',
'Materialized view' => 'Vista materializada',
'Unable to select the table' => 'No es posible seleccionar la tabla', '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.', 'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Vuelva a enviar los datos del formulario.',
'Comment' => 'Comentario', 'Comment' => 'Comentario',
'Default values' => 'Valores predeterminados', 'Default values' => 'Valores predeterminados',
'%d byte(s)' => array('%d byte', '%d bytes'), '%d byte(s)' => array('%d byte', '%d bytes'),
'No commands to execute.' => 'Ningún comando para ejecutar.', 'No commands to execute.' => 'No es posible ejecutar ningún comando.',
'Unable to upload a file.' => 'No es posible cargar el archivo.', 'Unable to upload a file.' => 'No es posible importar el archivo.',
'File upload' => 'Importar archivo', 'File upload' => 'Importar archivo',
'File uploads are disabled.' => 'Importación de archivos deshablilitada.', '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.'), 'Routine has been called, %d row(s) affected.' => array('Consulta ejecutada, %d registro afectado.', 'Consulta ejecutada, %d registros afectados.'),
@@ -88,9 +82,9 @@ Lang::$translations = array(
'Session support must be enabled.' => 'Deben estar habilitadas las sesiones.', '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.', 'Session expired, please login again.' => 'Sesión caducada, por favor escriba su clave de nuevo.',
'Text length' => 'Longitud de texto', 'Text length' => 'Longitud de texto',
'Foreign key has been dropped.' => 'Clave foranea eliminada.', 'Foreign key has been dropped.' => 'Clave externa eliminada.',
'Foreign key has been altered.' => 'Clave foranea modificada.', 'Foreign key has been altered.' => 'Clave externa modificada.',
'Foreign key has been created.' => 'Clave foranea creada.', 'Foreign key has been created.' => 'Clave externa creada.',
'Foreign key' => 'Clave externa', 'Foreign key' => 'Clave externa',
'Target table' => 'Tabla de destino', 'Target table' => 'Tabla de destino',
'Change' => 'Modificar', 'Change' => 'Modificar',
@@ -102,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'AL BORRAR', 'ON DELETE' => 'AL BORRAR',
'ON UPDATE' => 'AL ACTUALIZAR', 'ON UPDATE' => 'AL ACTUALIZAR',
'Index Type' => 'Tipo de índice', 'Index Type' => 'Tipo de índice',
'length' => 'longitud', 'Column (length)' => 'Columna (longitud)',
'View has been dropped.' => 'Vista eliminada.', 'View has been dropped.' => 'Vista eliminada.',
'View has been altered.' => 'Vista modificada.', 'View has been altered.' => 'Vista modificada.',
'View has been created.' => 'Vista creada.', 'View has been created.' => 'Vista creada.',
@@ -145,8 +139,6 @@ Lang::$translations = array(
'Grant' => 'Conceder', 'Grant' => 'Conceder',
'Revoke' => 'Impedir', '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.', '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', 'Logged as: %s' => 'Logueado como: %s',
'Move up' => 'Mover arriba', 'Move up' => 'Mover arriba',
'Move down' => 'Mover abajo', 'Move down' => 'Mover abajo',
@@ -154,8 +146,8 @@ Lang::$translations = array(
'Aggregation' => 'Agregados', 'Aggregation' => 'Agregados',
'Export' => 'Exportar', 'Export' => 'Exportar',
'Output' => 'Salida', 'Output' => 'Salida',
'open' => 'abrir', 'open' => 'mostrar',
'save' => 'guardar', 'save' => 'archivo',
'Format' => 'Formato', 'Format' => 'Formato',
'Tables' => 'Tablas', 'Tables' => 'Tablas',
'Data' => 'Datos', 'Data' => 'Datos',
@@ -202,7 +194,6 @@ Lang::$translations = array(
'Partition name' => 'Nombre de partición', 'Partition name' => 'Nombre de partición',
'Values' => 'Valores', 'Values' => 'Valores',
'%d row(s) have been imported.' => array('%d registro importado.', '%d registros importados.'), '%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', 'anywhere' => 'donde sea',
'Import' => 'Importar', 'Import' => 'Importar',
'Stop on error' => 'Parar en caso de error', 'Stop on error' => 'Parar en caso de error',
@@ -264,7 +255,7 @@ Lang::$translations = array(
'Attachments' => 'Adjuntos', 'Attachments' => 'Adjuntos',
'%d query(s) executed OK.' => array('%d sentencia SQL ejecutada correctamente.', '%d sentencias SQL ejecutadas correctamente.'), '%d query(s) executed OK.' => array('%d sentencia SQL ejecutada correctamente.', '%d sentencias SQL ejecutadas correctamente.'),
'Show only errors' => 'Mostrar solamente errores', 'Show only errors' => 'Mostrar solamente errores',
'Refresh' => 'Actualizar', 'Refresh' => 'Refrescar',
'Invalid schema.' => 'Esquema inválido.', 'Invalid schema.' => 'Esquema inválido.',
'Please use one of the extensions %s.' => 'Por favor, use una de las extensiones %s.', 'Please use one of the extensions %s.' => 'Por favor, use una de las extensiones %s.',
'now' => 'ahora', 'now' => 'ahora',
@@ -275,27 +266,40 @@ Lang::$translations = array(
'Edit all' => 'Editar todos', 'Edit all' => 'Editar todos',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
'Loaded plugins' => 'Plugins cargados', 'Drop %s?' => null,
// '<b>%s</b> must return an array.' => '<b>%s</b> tiene que retornar un arreglo.', 'Tables have been optimized.' => null,
// 'Configure <b>%s</b> in <b>%s</b>.' => 'Configurar <b>%s</b> en <b>%s</b>.', 'Materialized view' => null,
'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.', 'Vacuum' => null,
'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>.', 'Selected' => null,
'Database does not support password.' => 'La base de datos no soporta password.', 'overwrite' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array('Muchos intentos de acceso Intente en %d minutos.'), 'DB' => null,
'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.', 'File must be in UTF-8 encoding.' => null,
'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.', 'Modify' => null,
'Connecting to privileged ports is not allowed.' => 'Conexiones a puertos privilegiados no son permitidas.', 'Load more data' => null,
'Disable %s or enable %s or %s extensions.' => 'Desactivar %s o activar %s o %s extensiones.', 'Loading' => null,
'The action will be performed after successful login with the same credentials.' => 'La operacion sera ejecutada despues de ingresar nuevamente con las mismas credenciales.', 'ATTACH queries are not supported.' => null,
'You have no privileges to update this table.' => 'Usted no tiene privilegios para actualizar esta tabla.', 'Warnings' => null,
'%d / ' => array(),
// Table check constraints 'Limit rows' => null,
'Checks' => 'Chequeos', 'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Create check' => 'Crear chequeo', 'Default value' => null,
'Alter check' => 'Cambiar chequeo', 'Full table scan' => null,
'Check has been created.' => 'Chequeo creado.', 'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Check has been altered.' => 'Chequeo cambiado.', 'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Check has been dropped.' => 'Chequeo eliminado.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
); );
// run `php ../../lang.php es` to update this file

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Logi sisse', 'Login' => 'Logi sisse',
'Logout successful.' => 'Väljalogimine õnnestus.', 'Logout successful.' => 'Väljalogimine õnnestus.',
'Invalid credentials.' => 'Ebakorrektsed andmed.', 'Invalid server or credentials.' => null,
'Server' => 'Server', 'Server' => 'Server',
'Username' => 'Kasutajanimi', 'Username' => 'Kasutajanimi',
'Password' => 'Parool', 'Password' => 'Parool',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Loo uus andmebaas', 'Create database' => 'Loo uus andmebaas',
'SQL command' => 'SQL-Päring', 'SQL command' => 'SQL-Päring',
'Logout' => 'Logi välja', 'Logout' => 'Logi välja',
'database' => 'andmebaas',
'Use' => 'Kasuta', 'Use' => 'Kasuta',
'No tables.' => 'Tabeleid ei leitud.', 'No tables.' => 'Tabeleid ei leitud.',
'select' => 'kuva', 'select' => 'kuva',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Indeksi tüüp', 'Index Type' => 'Indeksi tüüp',
'length' => 'pikkus', 'Column (length)' => 'Veerg (pikkus)',
'View has been dropped.' => 'Vaade (VIEW) on edukalt kustutatud.', 'View has been dropped.' => 'Vaade (VIEW) on edukalt kustutatud.',
'View has been altered.' => 'Vaade (VIEW) on edukalt muudetud.', 'View has been altered.' => 'Vaade (VIEW) on edukalt muudetud.',
'View has been created.' => 'Vaade (VIEW) on edukalt loodud.', 'View has been created.' => 'Vaade (VIEW) on edukalt loodud.',
@@ -266,6 +265,41 @@ Lang::$translations = array(
'Permanent link' => 'Püsilink', 'Permanent link' => 'Püsilink',
'Edit all' => 'Muuda kõiki', 'Edit all' => 'Muuda kõiki',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
);
// run `php ../../lang.php et` to update this file 'Drop %s?' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'overwrite' => null,
'DB' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'سیستم', 'System' => 'سیستم',
'Server' => 'سرور', 'Server' => 'سرور',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'خروج', 'Logout' => 'خروج',
'Logged as: %s' => 'ورود به عنوان: %s', 'Logged as: %s' => 'ورود به عنوان: %s',
'Logout successful.' => 'با موفقیت خارج شدید.', 'Logout successful.' => 'با موفقیت خارج شدید.',
'Invalid credentials.' => 'اعتبار سنجی نامعتبر.', 'Invalid server or credentials.' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array('ورودهای ناموفق بیش از حد، %d دقیقه دیگر تلاش نمایید.', 'ورودهای ناموفق بیش از حد، %d دقیقه دیگر تلاش نمایید.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('ورودهای ناموفق بیش از حد، %d دقیقه دیگر تلاش نمایید.', 'ورودهای ناموفق بیش از حد، %d دقیقه دیگر تلاش نمایید.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'رمز اصلی باطل شده است. روش %s را <a href="https://www.adminer.org/en/extension/"%s>پیاده سازی</a> کرده تا آن را دائمی سازید.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'رمز اصلی باطل شده است. روش %s را <a href="https://www.adminer.org/en/extension/"%s>پیاده سازی</a> کرده تا آن را دائمی سازید.',
'Language' => 'زبان', 'Language' => 'زبان',
@@ -79,6 +77,7 @@ Lang::$translations = array(
'Data' => 'داده', 'Data' => 'داده',
'Database' => 'پایگاه داده', 'Database' => 'پایگاه داده',
'database' => 'پایگاه داده',
'Use' => 'استفاده', 'Use' => 'استفاده',
'Select database' => 'انتخاب پایگاه داده', 'Select database' => 'انتخاب پایگاه داده',
'Invalid database.' => 'پایگاه داده نامعتبر.', 'Invalid database.' => 'پایگاه داده نامعتبر.',
@@ -146,7 +145,7 @@ Lang::$translations = array(
'Tables' => 'جدولها', 'Tables' => 'جدولها',
'Tables and views' => 'جدولها و نمایه ها', 'Tables and views' => 'جدولها و نمایه ها',
'Table' => 'جدول', 'Table' => 'جدول',
'No tables.' => 'جدولی وجود ندارد.', 'No tables.' => 'جدولی وجود ندارد',
'Alter table' => 'ویرایش جدول', 'Alter table' => 'ویرایش جدول',
'Create table' => 'ایجاد جدول', 'Create table' => 'ایجاد جدول',
'Table has been dropped.' => 'جدول حذف شد.', 'Table has been dropped.' => 'جدول حذف شد.',
@@ -193,7 +192,7 @@ Lang::$translations = array(
'Alter indexes' => 'ویرایش ایندکسها', 'Alter indexes' => 'ویرایش ایندکسها',
'Add next' => 'افرودن بعدی', 'Add next' => 'افرودن بعدی',
'Index Type' => 'نوع ایندکس', 'Index Type' => 'نوع ایندکس',
'length' => 'طول', 'Column (length)' => 'ستون (طول)',
'Foreign keys' => 'کلیدهای خارجی', 'Foreign keys' => 'کلیدهای خارجی',
'Foreign key' => 'کلید خارجی', 'Foreign key' => 'کلید خارجی',
@@ -238,7 +237,7 @@ Lang::$translations = array(
'Action' => 'عملیات', 'Action' => 'عملیات',
'Full table scan' => 'اسکن کامل جدول', 'Full table scan' => 'اسکن کامل جدول',
'Unable to select the table' => 'قادر به انتخاب جدول نیستید', 'Unable to select the table' => 'قادر به انتخاب جدول نیستید',
'No rows.' => 'سطری وجود ندارد.', 'No rows.' => 'سطری وجود ندارد',
'%d / ' => '%d / ', '%d / ' => '%d / ',
'%d row(s)' => array('%d سطر', '%d سطر'), '%d row(s)' => array('%d سطر', '%d سطر'),
'Page' => 'صفحه', 'Page' => 'صفحه',
@@ -332,6 +331,20 @@ Lang::$translations = array(
'Type has been dropped.' => 'نوع حذف شد.', 'Type has been dropped.' => 'نوع حذف شد.',
'Type has been created.' => 'نوع ایجاد شد.', 'Type has been created.' => 'نوع ایجاد شد.',
'Alter type' => 'ویرایش نوع', 'Alter type' => 'ویرایش نوع',
);
// run `php ../../lang.php fa` to update this file 'Drop %s?' => null,
'overwrite' => null,
'DB' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Järjestelmä', 'System' => 'Järjestelmä',
'Server' => 'Palvelin', 'Server' => 'Palvelin',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Kirjaudu ulos', 'Logout' => 'Kirjaudu ulos',
'Logged as: %s' => 'Olet kirjautunut käyttäjänä: %s', 'Logged as: %s' => 'Olet kirjautunut käyttäjänä: %s',
'Logout successful.' => 'Uloskirjautuminen onnistui.', 'Logout successful.' => 'Uloskirjautuminen onnistui.',
'Invalid credentials.' => 'Virheelliset kirjautumistiedot.', 'Invalid server or credentials.' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array('Liian monta epäonnistunutta sisäänkirjautumisyritystä, kokeile uudestaan %d minuutin kuluttua.', 'Liian monta epäonnistunutta sisäänkirjautumisyritystä, kokeile uudestaan %d minuutin kuluttua.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Liian monta epäonnistunutta sisäänkirjautumisyritystä, kokeile uudestaan %d minuutin kuluttua.', 'Liian monta epäonnistunutta sisäänkirjautumisyritystä, kokeile uudestaan %d minuutin kuluttua.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-salasana ei ole enää voimassa. <a href="https://www.adminer.org/en/extension/"%s>Toteuta</a> %s-metodi sen tekemiseksi pysyväksi.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-salasana ei ole enää voimassa. <a href="https://www.adminer.org/en/extension/"%s>Toteuta</a> %s-metodi sen tekemiseksi pysyväksi.',
'Language' => 'Kieli', 'Language' => 'Kieli',
@@ -81,6 +79,7 @@ Lang::$translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Tietokanta', 'Database' => 'Tietokanta',
'database' => 'tietokanta',
'Use' => 'Käytä', 'Use' => 'Käytä',
'Select database' => 'Valitse tietokanta', 'Select database' => 'Valitse tietokanta',
'Invalid database.' => 'Tietokanta ei kelpaa.', 'Invalid database.' => 'Tietokanta ei kelpaa.',
@@ -195,7 +194,7 @@ Lang::$translations = array(
'Alter indexes' => 'Muuta indeksejä', 'Alter indexes' => 'Muuta indeksejä',
'Add next' => 'Lisää seuraava', 'Add next' => 'Lisää seuraava',
'Index Type' => 'Indeksityyppi', 'Index Type' => 'Indeksityyppi',
'length' => 'pituus', 'Column (length)' => 'Sarake (pituus)',
'Foreign keys' => 'Vieraat avaimet', 'Foreign keys' => 'Vieraat avaimet',
'Foreign key' => 'Vieras avain', 'Foreign key' => 'Vieras avain',
@@ -349,5 +348,3 @@ Lang::$translations = array(
'Database does not support password.' => 'Tietokanta ei tue salasanaa.', '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.', '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

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Authentification', 'Login' => 'Authentification',
'Logout successful.' => 'Au revoir !', 'Logout successful.' => 'Au revoir !',
'Invalid credentials.' => 'Authentification échouée.', 'Invalid server or credentials.' => null,
'Server' => 'Serveur', 'Server' => 'Serveur',
'Username' => 'Utilisateur', 'Username' => 'Utilisateur',
'Password' => 'Mot de passe', 'Password' => 'Mot de passe',
@@ -32,6 +30,7 @@ Lang::$translations = array(
'Create database' => 'Créer une base de données', 'Create database' => 'Créer une base de données',
'SQL command' => 'Requête SQL', 'SQL command' => 'Requête SQL',
'Logout' => 'Déconnexion', 'Logout' => 'Déconnexion',
'database' => 'base de données',
'Use' => 'Utiliser', 'Use' => 'Utiliser',
'No tables.' => 'Aucune table.', 'No tables.' => 'Aucune table.',
'select' => 'select', 'select' => 'select',
@@ -95,7 +94,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Type d\'index', 'Index Type' => 'Type d\'index',
'length' => 'longueur', 'Column (length)' => 'Colonne (longueur)',
'View has been dropped.' => 'La vue a été effacée.', 'View has been dropped.' => 'La vue a été effacée.',
'View has been altered.' => 'La vue a été modifiée.', 'View has been altered.' => 'La vue a été modifiée.',
'View has been created.' => 'La vue a été créée.', 'View has been created.' => 'La vue a été créée.',
@@ -242,7 +241,7 @@ Lang::$translations = array(
'Type has been dropped.' => 'Le type a été supprimé.', 'Type has been dropped.' => 'Le type a été supprimé.',
'Type has been created.' => 'Le type a été créé.', '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.', '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', 'last' => 'dernière',
'From server' => 'Depuis le serveur', 'From server' => 'Depuis le serveur',
'System' => 'Système', 'System' => 'Système',
@@ -289,18 +288,18 @@ Lang::$translations = array(
'Default value' => 'Valeur par défaut', 'Default value' => 'Valeur par défaut',
'If you did not send this request from Adminer then close this page.' => 'Si vous n\'avez pas envoyé cette requête depuis Adminer, alors fermez cette page.', 'If you did not send this request from Adminer then close this page.' => 'Si vous n\'avez pas envoyé cette requête depuis Adminer, alors fermez cette page.',
'You are offline.' => 'Vous êtes hors ligne.', 'You are offline.' => 'Vous êtes hors ligne.',
'Drop %s?' => 'Supprimer %s?', 'Drop %s?' => 'Supprimer %s?',
'overwrite' => 'écraser', 'overwrite' => 'écraser',
'DB' => 'BD', 'DB' => 'BD',
'ATTACH queries are not supported.' => 'Requêtes ATTACH ne sont pas supportées.', 'ATTACH queries are not supported.' => 'Requêtes ATTACH ne sont pas supportées.',
'Warnings' => 'Avertissements', 'Warnings' => 'Avertissements',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer ne supporte pas l\'accès aux bases de données sans mot de passe, <a href="https://www.adminer.org/en/password/"%s>plus d\'information</a>.', 'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer ne supporte pas l\'accès aux bases de données sans mot de passe, <a href="https://www.adminer.org/en/password/"%s>plus d\'information</a>.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'The action will be performed after successful login with the same credentials.' => 'Cette action sera exécutée après s\'être connecté avec les mêmes données de connexion.', 'The action will be performed after successful login with the same credentials.' => 'Cette action sera exécutée après s\'être connecté avec les mêmes données de connexion.',
'Connecting to privileged ports is not allowed.' => 'La connexion aux ports privilégiés n\'est pas autorisée.', 'Connecting to privileged ports is not allowed.' => 'La connexion aux ports privilégiés n\'est pas autorisée.',
'There is a space in the input password which might be the cause.' => 'Il y a un espace dans le mot de passe entré qui pourrait en être la cause.', 'There is a space in the input password which might be the cause.' => 'Il y a un espace dans le mot de passe entré qui pourrait en être la cause.',
'Unknown error.' => 'Erreur inconnue.', 'Unknown error.' => 'Erreur inconnue',
'Database does not support password.' => 'La base de données ne support pas les mots de passe.', '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.', '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

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Conectar', 'Login' => 'Conectar',
'Logout successful.' => 'Pechouse a sesión con éxito.', 'Logout successful.' => 'Pechouse a sesión con éxito.',
'Invalid credentials.' => 'Credenciais (usuario e/ou contrasinal) inválidos.', 'Invalid server or credentials.' => null,
'Server' => 'Servidor', 'Server' => 'Servidor',
'Username' => 'Usuario', 'Username' => 'Usuario',
'Password' => 'Contrasinal', 'Password' => 'Contrasinal',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Crear Base de datos', 'Create database' => 'Crear Base de datos',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Pechar sesión', 'Logout' => 'Pechar sesión',
'database' => 'base de datos',
'Use' => 'Usar', 'Use' => 'Usar',
'No tables.' => 'Nengunha táboa.', 'No tables.' => 'Nengunha táboa.',
'select' => 'selecciona', 'select' => 'selecciona',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'AO BORRAR (ON DELETE)', 'ON DELETE' => 'AO BORRAR (ON DELETE)',
'ON UPDATE' => 'AO ACTUALIZAR (ON UPDATE)', 'ON UPDATE' => 'AO ACTUALIZAR (ON UPDATE)',
'Index Type' => 'Tipo de índice', 'Index Type' => 'Tipo de índice',
'length' => 'lonxitude', 'Column (length)' => 'Columna (lonxitude)',
'View has been dropped.' => 'Eliminouse a vista.', 'View has been dropped.' => 'Eliminouse a vista.',
'View has been altered.' => 'Modificouse a vista.', 'View has been altered.' => 'Modificouse a vista.',
'View has been created.' => 'Creouse a vista.', 'View has been created.' => 'Creouse a vista.',
@@ -266,11 +265,11 @@ Lang::$translations = array(
'Permanent link' => 'Ligazón permanente', 'Permanent link' => 'Ligazón permanente',
'Edit all' => 'Editar todo', 'Edit all' => 'Editar todo',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
'Tables have been optimized.' => 'Optimizáronse as táboas.', 'Tables have been optimized.' => 'Optimizáronse as táboas',
'Materialized view' => 'Vista materializada', 'Materialized view' => 'Vista materializada',
'Vacuum' => 'Baleirar', 'Vacuum' => 'Baleirar',
'Selected' => 'Selección', 'Selected' => 'Selección',
'File must be in UTF-8 encoding.' => 'O ficheiro ten que estar codificado con UTF-8.', 'File must be in UTF-8 encoding.' => 'O ficheiro ten que estar codificado con UTF-8',
'Modify' => 'Modificar', 'Modify' => 'Modificar',
'Loading' => 'Cargando', 'Loading' => 'Cargando',
'Load more data' => 'Cargar máis datos', 'Load more data' => 'Cargar máis datos',
@@ -278,17 +277,29 @@ Lang::$translations = array(
'Limit rows' => 'Limitar filas', 'Limit rows' => 'Limitar filas',
'Default value' => 'Valor por defecto', 'Default value' => 'Valor por defecto',
'Full table scan' => 'Escaneo completo da táboa', 'Full table scan' => 'Escaneo completo da táboa',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Demasiados intentos de conexión, intentao de novo en %d minuto.', 'Demasiados intentos de conexión, intentao de novo en %d minutos.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Demasiados intentos de conexión, intentao de novo en %d minuto', 'Demasiados intentos de conexión, intentao de novo en %d minutos'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'O contrasinal principal caducou. <a href="https://www.adminer.org/en/extension/"%s>Implementa</a> o método %s para facelo permanente.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'O contrasinal principal caducou. <a href="https://www.adminer.org/en/extension/"%s>Implementa</a> o método %s para facelo permanente.',
'If you did not send this request from Adminer then close this page.' => 'Se non enviaches esta petición dende o Adminer entón pecha esta páxina.', 'If you did not send this request from Adminer then close this page.' => 'Se non enviaches esta petición dende o Adminer entón pecha esta páxina',
'You can upload a big SQL file via FTP and import it from server.' => 'Podes subir un ficheiro SQL de gran tamaño vía FTP e importalo dende o servidor.', 'You can upload a big SQL file via FTP and import it from server.' => 'Podes subir un ficheiro SQL de gran tamaño vía FTP e importalo dende o servidor',
'Size' => 'Tamaño', 'Size' => 'Tamaño',
'Compute' => 'Calcular', 'Compute' => 'Calcular',
'You are offline.' => 'Non tes conexión.', 'You are offline.' => 'Non tes conexión',
'You have no privileges to update this table.' => 'Non tes privilexios para actualizar esta táboa.', 'You have no privileges to update this table.' => 'Non tes privilexios para actualizar esta táboa',
'Saving' => 'Gardando', 'Saving' => 'Gardando',
'yes' => 'si', 'yes' => 'si',
'no' => 'non', 'no' => 'non',
);
// run `php ../../lang.php gl` to update this file 'Drop %s?' => null,
'overwrite' => null,
'DB' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'התחברות', 'Login' => 'התחברות',
'Logout successful.' => 'ההתחברות הצליחה', 'Logout successful.' => 'ההתחברות הצליחה',
'Invalid credentials.' => 'פרטי התחברות שגויים', 'Invalid server or credentials.' => null,
'Server' => 'שרת', 'Server' => 'שרת',
'Username' => 'שם משתמש', 'Username' => 'שם משתמש',
'Password' => 'סיסמה', 'Password' => 'סיסמה',
@@ -32,6 +30,7 @@ Lang::$translations = array(
'Create database' => 'צור מסד נתונים', 'Create database' => 'צור מסד נתונים',
'SQL command' => 'שאילתת SQL', 'SQL command' => 'שאילתת SQL',
'Logout' => 'התנתק', 'Logout' => 'התנתק',
'database' => 'מסד נתונים',
'Use' => 'השתמש', 'Use' => 'השתמש',
'No tables.' => 'אין טבלאות', 'No tables.' => 'אין טבלאות',
'select' => 'בחר', 'select' => 'בחר',
@@ -95,7 +94,7 @@ Lang::$translations = array(
'ON DELETE' => 'בעת מחיקה', 'ON DELETE' => 'בעת מחיקה',
'ON UPDATE' => 'בעת עידכון', 'ON UPDATE' => 'בעת עידכון',
'Index Type' => 'סוג אינדקס', 'Index Type' => 'סוג אינדקס',
'length' => 'אורך', 'Column (length)' => 'עמודה (אורך)',
'View has been dropped.' => 'התצוגה הושלכה', 'View has been dropped.' => 'התצוגה הושלכה',
'View has been altered.' => 'התצוגה שונתה', 'View has been altered.' => 'התצוגה שונתה',
'View has been created.' => 'התצוגה נוצרה', 'View has been created.' => 'התצוגה נוצרה',
@@ -280,7 +279,7 @@ Lang::$translations = array(
'Default value' => 'ערך ברירת מחדל', 'Default value' => 'ערך ברירת מחדל',
'Full table scan' => 'סריקה טבלה מלאה', 'Full table scan' => 'סריקה טבלה מלאה',
'Too many unsuccessful logins, try again in %d minute(s).' => 'יותר מידי נסיונות כניסה נכשלו, אנא נסה עוד %d דקות', 'Too many unsuccessful logins, try again in %d minute(s).' => 'יותר מידי נסיונות כניסה נכשלו, אנא נסה עוד %d דקות',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'תודה שהשתמש ב-adminer אנא שקול <a href="https://www.adminer.org/en/donation/">לתרום</a>', 'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'תודה שהשתמש ב-adminer אנא שקול <a href="https://www.adminer.org/en/donation/">לתרום</a>.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'סיסמת המאסטר פגה <a href="https://www.adminer.org/en/extension/"%s>התקן תוסף</a> על מנת להפוך את זה לתמידי', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'סיסמת המאסטר פגה <a href="https://www.adminer.org/en/extension/"%s>התקן תוסף</a> על מנת להפוך את זה לתמידי',
'If you did not send this request from Adminer then close this page.' => 'אם לא אתה שלחת בקשה ל-Adminer הינך יכול לסגור חלון זה', 'If you did not send this request from Adminer then close this page.' => 'אם לא אתה שלחת בקשה ל-Adminer הינך יכול לסגור חלון זה',
'You can upload a big SQL file via FTP and import it from server.' => 'ניתן לעלות קבצים ב-FTP ואז למשוך אותם מהשרת', 'You can upload a big SQL file via FTP and import it from server.' => 'ניתן לעלות קבצים ב-FTP ואז למשוך אותם מהשרת',
@@ -291,6 +290,16 @@ Lang::$translations = array(
'Saving' => 'שומר', 'Saving' => 'שומר',
'yes' => 'כן', 'yes' => 'כן',
'no' => 'לא', 'no' => 'לא',
);
// run `php ../../lang.php he` to update this file 'Drop %s?' => null,
'overwrite' => null,
'DB' => null,
'Warnings' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Belépés', 'Login' => 'Belépés',
'Logout successful.' => 'Sikeres kilépés.', 'Logout successful.' => 'Sikeres kilépés.',
'Invalid credentials.' => 'Érvénytelen adatok.', 'Invalid server or credentials.' => null,
'Server' => 'Szerver', 'Server' => 'Szerver',
'Username' => 'Felhasználó', 'Username' => 'Felhasználó',
'Password' => 'Jelszó', 'Password' => 'Jelszó',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Adatbázis létrehozása', 'Create database' => 'Adatbázis létrehozása',
'SQL command' => 'SQL parancs', 'SQL command' => 'SQL parancs',
'Logout' => 'Kilépés', 'Logout' => 'Kilépés',
'database' => 'adatbázis',
'Use' => 'Használ', 'Use' => 'Használ',
'No tables.' => 'Nincs tábla.', 'No tables.' => 'Nincs tábla.',
'select' => 'kiválasztás', 'select' => 'kiválasztás',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'törléskor', 'ON DELETE' => 'törléskor',
'ON UPDATE' => 'frissítéskor', 'ON UPDATE' => 'frissítéskor',
'Index Type' => 'Index típusa', 'Index Type' => 'Index típusa',
'length' => 'méret', 'Column (length)' => 'Oszop (méret)',
'View has been dropped.' => 'A nézet eldobva.', 'View has been dropped.' => 'A nézet eldobva.',
'View has been altered.' => 'A nézet módosult.', 'View has been altered.' => 'A nézet módosult.',
'View has been created.' => 'A nézet létrejött.', 'View has been created.' => 'A nézet létrejött.',
@@ -265,6 +264,42 @@ Lang::$translations = array(
'Permanent link' => 'Hivatkozás', 'Permanent link' => 'Hivatkozás',
'Edit all' => 'Összes szerkesztése', 'Edit all' => 'Összes szerkesztése',
'HH:MM:SS' => 'óó:pp:mm', 'HH:MM:SS' => 'óó:pp:mm',
);
// run `php ../../lang.php hu` to update this file 'Drop %s?' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'overwrite' => null,
'DB' => null,
'Ctrl+click on a value to modify it.' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem', 'System' => 'Sistem',
'Server' => 'Server', 'Server' => 'Server',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Keluar', 'Logout' => 'Keluar',
'Logged as: %s' => 'Masuk sebagai: %s', 'Logged as: %s' => 'Masuk sebagai: %s',
'Logout successful.' => 'Berhasil keluar.', 'Logout successful.' => 'Berhasil keluar.',
'Invalid credentials.' => 'Akses tidak sah.', 'Invalid server or credentials.' => null,
'Language' => 'Bahasa', 'Language' => 'Bahasa',
'Invalid CSRF token. Send the form again.' => 'Token CSRF tidak sah. Kirim ulang formulir.', 'Invalid CSRF token. Send the form again.' => 'Token CSRF tidak sah. Kirim ulang formulir.',
'No extension' => 'Ekstensi tidak ada', 'No extension' => 'Ekstensi tidak ada',
@@ -75,6 +73,7 @@ Lang::$translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Basis data', 'Database' => 'Basis data',
'database' => 'basis data',
'Use' => 'Gunakan', 'Use' => 'Gunakan',
'Select database' => 'Pilih basis data', 'Select database' => 'Pilih basis data',
'Invalid database.' => 'Basis data tidak sah.', 'Invalid database.' => 'Basis data tidak sah.',
@@ -184,7 +183,7 @@ Lang::$translations = array(
'Alter indexes' => 'Ubah indeks', 'Alter indexes' => 'Ubah indeks',
'Add next' => 'Tambah setelahnya', 'Add next' => 'Tambah setelahnya',
'Index Type' => 'Jenis Indeks', 'Index Type' => 'Jenis Indeks',
'length' => 'panjang', 'Column (length)' => 'Kolom (panjang)',
'Foreign keys' => 'Kunci asing', 'Foreign keys' => 'Kunci asing',
'Foreign key' => 'Kunci asing', 'Foreign key' => 'Kunci asing',
@@ -314,6 +313,38 @@ Lang::$translations = array(
'Type has been dropped.' => 'Jenis berhasil dihapus.', 'Type has been dropped.' => 'Jenis berhasil dihapus.',
'Type has been created.' => 'Jenis berhasil dibuat.', 'Type has been created.' => 'Jenis berhasil dibuat.',
'Alter type' => 'Ubah jenis', 'Alter type' => 'Ubah jenis',
);
// run `php ../../lang.php id` to update this file 'Drop %s?' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'overwrite' => null,
'DB' => null,
'Ctrl+click on a value to modify it.' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Autenticazione', 'Login' => 'Autenticazione',
'Logout successful.' => 'Uscita effettuata con successo.', 'Logout successful.' => 'Uscita effettuata con successo.',
'Invalid credentials.' => 'Credenziali non valide.', 'Invalid server or credentials.' => 'Server o credenziali non valide.',
'Server' => 'Server', 'Server' => 'Server',
'Username' => 'Utente', 'Username' => 'Utente',
'Password' => 'Password', 'Password' => 'Password',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Crea database', 'Create database' => 'Crea database',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Esci', 'Logout' => 'Esci',
'database' => 'database',
'Use' => 'Usa', 'Use' => 'Usa',
'No tables.' => 'No tabelle.', 'No tables.' => 'No tabelle.',
'select' => 'seleziona', 'select' => 'seleziona',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Tipo indice', 'Index Type' => 'Tipo indice',
'length' => 'lunghezza', 'Column (length)' => 'Colonna (lunghezza)',
'View has been dropped.' => 'Vista eliminata.', 'View has been dropped.' => 'Vista eliminata.',
'View has been altered.' => 'Vista modificata.', 'View has been altered.' => 'Vista modificata.',
'View has been created.' => 'Vista creata.', 'View has been created.' => 'Vista creata.',
@@ -266,8 +265,9 @@ Lang::$translations = array(
'Permanent link' => 'Link permanente', 'Permanent link' => 'Link permanente',
'Edit all' => 'Modifica tutto', 'Edit all' => 'Modifica tutto',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
'Drop %s?' => 'Scartare %s?', 'Drop %s?' => 'Scartare %s?',
'Tables have been optimized.' => 'Le tabelle sono state ottimizzate.', 'Tables have been optimized.' => 'Le tabelle sono state ottimizzate',
'Materialized view' => 'Vista materializzata', 'Materialized view' => 'Vista materializzata',
'Vacuum' => 'Aspira', 'Vacuum' => 'Aspira',
'Selected' => 'Selezionato', 'Selected' => 'Selezionato',
@@ -279,12 +279,13 @@ Lang::$translations = array(
'Loading' => 'Caricamento', 'Loading' => 'Caricamento',
'ATTACH queries are not supported.' => 'ATTACH queries non sono supportate.', 'ATTACH queries are not supported.' => 'ATTACH queries non sono supportate.',
'Warnings' => 'Attenzione', 'Warnings' => 'Attenzione',
'%d / ' => '%d / ', '%d / ' => array('%d / '),
'Limit rows' => 'Limite righe', 'Limit rows' => 'Limite righe',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer non supporta accesso a databse senza password, <a href="https://www.adminer.org/it/password/"%s>piú informazioni</a>.', 'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer non supporta accesso a databse senza password, <a href="https://www.adminer.org/it/password/"%s>piú informazioni</a>.',
'Default value' => 'Valore predefinito', 'Default value' => 'Valore predefinito',
'Full table scan' => 'Analizza intera tabella', 'Full table scan' => 'Analizza intera tabella',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Troppi tentativi infruttuosi di login, si prega di riprovare in %d minuto.', 'Troppi tentativi infruttuosi di login, si prega di riprovare in %d minuti.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Troppi tentativi infruttuosi di login, si prega di riprovare in %d minuto.', 'Troppi tentativi infruttuosi di login, si prega di riprovare in %d minuti.'),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'La password principale é scaduta. <a href="https://www.adminer.org/it/extension/"%s>Implementare</a> %s come metodo per renderla permanente.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'La password principale é scaduta. <a href="https://www.adminer.org/it/extension/"%s>Implementare</a> %s come metodo per renderla permanente.',
'The action will be performed after successful login with the same credentials.' => 'La azione verrá eseguita dopo un login valido con le stesse credenziali.', 'The action will be performed after successful login with the same credentials.' => 'La azione verrá eseguita dopo un login valido con le stesse credenziali.',
'Connecting to privileged ports is not allowed.' => 'LA connessione a porte privilegiate non é permessa.', 'Connecting to privileged ports is not allowed.' => 'LA connessione a porte privilegiate non é permessa.',
@@ -296,11 +297,9 @@ Lang::$translations = array(
'You are offline.' => 'Sei disconnesso.', 'You are offline.' => 'Sei disconnesso.',
'You have no privileges to update this table.' => 'Non hai i privilegi per aggiornare questa tabella.', 'You have no privileges to update this table.' => 'Non hai i privilegi per aggiornare questa tabella.',
'Saving' => 'Salvataggio', 'Saving' => 'Salvataggio',
'Unknown error.' => 'Errore sconosciuto.', 'Unknown error.' => 'Errore sconosciuto',
'Database does not support password.' => 'Il database non supporta password.', 'Database does not support password.' => 'Il database non supporta password.',
'Disable %s or enable %s or %s extensions.' => 'Disabilita %s o abilita %s oppure %s estensioni.', 'Disable %s or enable %s or %s extensions.' => 'Disabilita %s o abilita %s oppure %s estensioni.',
'yes' => 'si', 'yes' => 'si',
'no' => 'no', 'no' => 'no',
); );
// run `php ../../lang.php it` to update this file

View File

@@ -1,28 +1,17 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'ログイン', 'Login' => 'ログイン',
'Logout successful.' => 'ログアウトしました。', 'Logout successful.' => 'ログアウト',
'Invalid credentials.' => '不正なログインです。', 'Invalid server or credentials.' => null,
'Server' => 'サーバ', 'Server' => 'サーバ',
'Username' => 'ユーザ名', 'Username' => 'ユーザ名',
'Password' => 'パスワード', '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>)',
'%s must <a%s>return an array</a>.' => '%s は<a%s>配列を返す</a>必要があります。',
'<a%s>Configure</a> %s in %s.' => '%2$s の %1$s <a%s>を設定してください</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' => 'データベースを選択してください', 'Select database' => 'データベースを選択してください',
'Invalid database.' => '不正なデータベースです。', 'Invalid database.' => '不正なデータベース',
'Table has been dropped.' => 'テーブルを削除しました', 'Table has been dropped.' => 'テーブルを削除しました',
'Table has been altered.' => 'テーブルを変更しました', 'Table has been altered.' => 'テーブルを変更しました',
'Table has been created.' => 'テーブルを作成しました', 'Table has been created.' => 'テーブルを作成しました',
'Alter table' => 'テーブル変更', 'Alter table' => 'テーブル変更',
'Create table' => 'テーブルを作成', 'Create table' => 'テーブルを作成',
'Table name' => 'テーブル名', 'Table name' => 'テーブル名',
'engine' => 'エンジン', 'engine' => 'エンジン',
@@ -34,29 +23,27 @@ Lang::$translations = array(
'Options' => '設定', 'Options' => '設定',
'Save' => '保存', 'Save' => '保存',
'Drop' => '削除', 'Drop' => '削除',
'Drop %s?' => '%s を削除しますか?', 'Database has been dropped.' => 'データベースを削除しました',
'Database has been dropped.' => 'データベースを削除しました', 'Database has been created.' => 'データベースを作成しました',
'Database has been created.' => 'データベースを作成しました', 'Database has been renamed.' => 'データベースの名前を変えました',
'Database has been renamed.' => 'データベースの名前を変えました', 'Database has been altered.' => 'データベースを変更しました',
'Database has been altered.' => 'データベースを変更しました。',
'Alter database' => 'データベースを変更', 'Alter database' => 'データベースを変更',
'Create database' => 'データベースを作成', 'Create database' => 'データベースを作成',
'SQL command' => 'SQLコマンド', 'SQL command' => 'SQLコマンド',
'Logout' => 'ログアウト', 'Logout' => 'ログアウト',
'database' => 'データベース',
'Use' => '使用', 'Use' => '使用',
'No tables.' => 'テーブルがありません。', 'No tables.' => 'テーブルがありません。',
'select' => '選択', 'select' => '選択',
'Item has been deleted.' => '項目を削除しました', 'Item has been deleted.' => '項目を削除しました',
'Item has been updated.' => '項目を更新しました', 'Item has been updated.' => '項目を更新しました',
'Edit' => '編集', 'Edit' => '編集',
'Insert' => '挿入', 'Insert' => '挿入',
'Save and insert next' => '保存/追加', 'Save and insert next' => '保存/追加',
'Delete' => '削除', 'Delete' => '削除',
'You have no privileges to update this table.' => 'このテーブルを更新する権限がありません。',
'Database' => 'データベース', 'Database' => 'データベース',
'DB' => 'DB',
'Routines' => 'ルーチン', 'Routines' => 'ルーチン',
'Indexes have been altered.' => '索引を変更しました', 'Indexes have been altered.' => '索引を変更しました',
'Indexes' => '索引', 'Indexes' => '索引',
'Alter indexes' => '索引の変更', 'Alter indexes' => '索引の変更',
'Add next' => '追加', 'Add next' => '追加',
@@ -67,46 +54,36 @@ Lang::$translations = array(
'Sort' => 'ソート', 'Sort' => 'ソート',
'descending' => '降順', 'descending' => '降順',
'Limit' => '制約', 'Limit' => '制約',
'Limit rows' => '行数の制約', 'No rows.' => '行がありません',
'No rows.' => '行がありません。',
'Action' => '動作', 'Action' => '動作',
'edit' => '編集', 'edit' => '編集',
'Page' => 'ページ', 'Page' => 'ページ',
'Query executed OK, %d row(s) affected.' => 'クエリーを実行しました。%d 行を変更しました', 'Query executed OK, %d row(s) affected.' => 'クエリーを実行しました。%d 行を変更しました',
'Error in query' => 'クエリーのエラー', 'Error in query' => 'クエリーのエラー',
'Unknown error.' => '不明なエラーです。',
'Warnings' => '警告',
'ATTACH queries are not supported.' => 'ATTACH クエリーは対応していません。',
'Execute' => '実行', 'Execute' => '実行',
'Table' => 'テーブル', 'Table' => 'テーブル',
'Foreign keys' => '外部キー', 'Foreign keys' => '外部キー',
'Triggers' => 'トリガー', 'Triggers' => 'トリガー',
'View' => 'ビュー', 'View' => 'ビュー',
'Materialized view' => 'マテビュー',
'Full table scan' => 'テーブルの全スキャン',
'Unable to select the table' => 'テーブルを選択できません', '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' => 'コメント', 'Comment' => 'コメント',
'Default values' => '規定値', 'Default values' => '規定値',
'%d byte(s)' => '%d バイト', '%d byte(s)' => '%d バイト',
'No commands to execute.' => '実行するコマンドがありません', 'No commands to execute.' => '実行するコマンドがありません',
'Unable to upload a file.' => 'ファイルをアップロードできません', 'Unable to upload a file.' => 'ファイルをアップロードできません',
'File upload' => 'ファイルをアップロード', 'File upload' => 'ファイルをアップロード',
'File uploads are disabled.' => 'ファイルのアップロードが無効です', 'File uploads are disabled.' => 'ファイルのアップロードが無効です',
'Routine has been called, %d row(s) affected.' => 'ルーチンを呼びました。%d 行を変更しました', 'Routine has been called, %d row(s) affected.' => 'ルーチンを呼びました。%d 行を変更しました',
'Call' => '呼出し', 'Call' => '呼出し',
'No extension' => '拡張機能がありません', 'No extension' => '拡張機能がありません',
'None of the supported PHP extensions (%s) are available.' => 'PHPの拡張機能%sがセットアップされていません', 'None of the supported PHP extensions (%s) are available.' => 'PHPの拡張機能%sがセットアップされていません',
'Connecting to privileged ports is not allowed.' => '特権ポートへの接続は許可されていません。', 'Session support must be enabled.' => 'セッションを有効にしてください',
'Disable %s or enable %s or %s extensions.' => '%s を無効にするか、拡張機能 %s または %s を有効にしてください', 'Session expired, please login again.' => 'セッションの期限切れ。ログインし直してください',
'Session support must be enabled.' => 'セッションを有効にしてください。',
'Session expired, please login again.' => 'セッションの期限切れ。ログインし直してください。',
'The action will be performed after successful login with the same credentials.' => '同じアカウントで正しくログインすると作業を実行します。',
'Text length' => '文字列の長さ', 'Text length' => '文字列の長さ',
'Foreign key has been dropped.' => '外部キーを削除しました', 'Foreign key has been dropped.' => '外部キーを削除しました',
'Foreign key has been altered.' => '外部キーを変更しました', 'Foreign key has been altered.' => '外部キーを変更しました',
'Foreign key has been created.' => '外部キーを作成しました', 'Foreign key has been created.' => '外部キーを作成しました',
'Foreign key' => '外キー', 'Foreign key' => '外キー',
'Target table' => 'テーブル', 'Target table' => 'テーブル',
'Change' => '変更', 'Change' => '変更',
@@ -118,53 +95,50 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => '索引の型', 'Index Type' => '索引の型',
'length' => '長さ', 'Column (length)' => '列(長さ',
'View has been dropped.' => 'ビューを削除しました', 'View has been dropped.' => 'ビューを削除しました',
'View has been altered.' => 'ビューを変更しました', 'View has been altered.' => 'ビューを変更しました',
'View has been created.' => 'ビューを作成しました', 'View has been created.' => 'ビューを作成しました',
'Alter view' => 'ビューを変更', 'Alter view' => 'ビューを変更',
'Create view' => 'ビューを作成', 'Create view' => 'ビューを作成',
'Name' => '名称', 'Name' => '名称',
'Process list' => 'プロセス一覧', 'Process list' => 'プロセス一覧',
'%d process(es) have been killed.' => '%d プロセスを強制終了しました', '%d process(es) have been killed.' => '%d プロセスを強制終了しました',
'Kill' => '強制終了', 'Kill' => '強制終了',
'Parameter name' => '参数名', 'Parameter name' => '参数名',
'Database schema' => '構造', 'Database schema' => '構造',
'Create procedure' => 'プロシージャの作成', 'Create procedure' => 'プロシージャの作成',
'Create function' => '関数の作成', 'Create function' => '関数の作成',
'Routine has been dropped.' => 'ルーチンを作成しました。', 'Routine has been dropped.' => 'ルーチンを作成',
'Routine has been altered.' => 'ルーチンを変更しました。', 'Routine has been altered.' => 'ルーチンを変更',
'Routine has been created.' => 'ルーチンを作成しました。', 'Routine has been created.' => 'ルーチンを作成',
'Alter function' => '関数の変更', 'Alter function' => '関数の変更',
'Alter procedure' => 'プロシージャの変更', 'Alter procedure' => 'プロシージャの変更',
'Return type' => '戻り値の型', 'Return type' => '戻り値の型',
'Add trigger' => 'トリガーの追加', 'Add trigger' => 'トリガーの追加',
'Trigger has been dropped.' => 'トリガーを削除しました', 'Trigger has been dropped.' => 'トリガーを削除しました',
'Trigger has been altered.' => 'トリガーを変更しました', 'Trigger has been altered.' => 'トリガーを変更しました',
'Trigger has been created.' => 'トリガーを追加しました', 'Trigger has been created.' => 'トリガーを追加しました',
'Alter trigger' => 'トリガーの変更', 'Alter trigger' => 'トリガーの変更',
'Create trigger' => 'トリガーの作成', 'Create trigger' => 'トリガーの作成',
'Time' => '時間', 'Time' => '時間',
'Event' => 'イベント', 'Event' => 'イベント',
'%s version: %s through PHP extension %s' => '%sバージョン%s、 PHP拡張機能 %s', '%s version: %s through PHP extension %s' => '%sバージョン%s、 PHP拡張機能 %s',
'%d / ' => '%d / ',
'%d row(s)' => '%d 行', '%d row(s)' => '%d 行',
'Remove' => '除外', 'Remove' => '除外',
'Are you sure?' => '実行しますか?', 'Are you sure?' => '実行しますか?',
'Privileges' => '権限', 'Privileges' => '権限',
'Create user' => 'ユーザを作成', 'Create user' => 'ユーザを作成',
'User has been dropped.' => 'ユーザを削除しました。', 'User has been dropped.' => 'ユーザを削除',
'User has been altered.' => 'ユーザを変更しました。', 'User has been altered.' => 'ユーザを変更',
'User has been created.' => 'ユーザを作成しました。', 'User has been created.' => 'ユーザを作成',
'Hashed' => 'Hashed', 'Hashed' => 'Hashed',
'Column' => '列', 'Column' => '列',
'Routine' => 'ルーチン', 'Routine' => 'ルーチン',
'Grant' => '権限の付与', 'Grant' => '権限の付与',
'Revoke' => '権限の取消し', 'Revoke' => '権限の取消し',
'Logged as: %s' => 'ログ:%s', '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 up' => '上',
'Move down' => '下', 'Move down' => '下',
'Export' => 'エクスポート', 'Export' => 'エクスポート',
@@ -176,9 +150,9 @@ Lang::$translations = array(
'Format' => '形式', 'Format' => '形式',
'Functions' => '関数', 'Functions' => '関数',
'Aggregation' => '集合', 'Aggregation' => '集合',
'Event has been dropped.' => 'イベントを削除しました', 'Event has been dropped.' => '削除しました',
'Event has been altered.' => 'イベントを変更しました', 'Event has been altered.' => '変更しました',
'Event has been created.' => 'イベントを作成しました', 'Event has been created.' => '作成しました',
'Alter event' => '変更', 'Alter event' => '変更',
'Create event' => '作成', 'Create event' => '作成',
'Start' => '開始', 'Start' => '開始',
@@ -189,8 +163,8 @@ Lang::$translations = array(
'Events' => 'イベント', 'Events' => 'イベント',
'Schedule' => 'スケジュール', 'Schedule' => 'スケジュール',
'At given time' => '指定時刻', 'At given time' => '指定時刻',
'Tables have been truncated.' => 'テーブルを空にしました', 'Tables have been truncated.' => 'テーブルをtruncateしました',
'Tables have been moved.' => 'テーブルを移動しました', 'Tables have been moved.' => 'テーブルを移動しました',
'Tables and views' => 'テーブルとビュー', 'Tables and views' => 'テーブルとビュー',
'Engine' => 'エンジン', 'Engine' => 'エンジン',
'Collation' => '照合順序', 'Collation' => '照合順序',
@@ -202,7 +176,6 @@ Lang::$translations = array(
'0123456789' => '0123456789', '0123456789' => '0123456789',
'Analyze' => '分析', 'Analyze' => '分析',
'Optimize' => '最適化', 'Optimize' => '最適化',
'Vacuum' => '不要領域の回収',
'Check' => 'チェック', 'Check' => 'チェック',
'Repair' => '修復', 'Repair' => '修復',
'Truncate' => '空にする', 'Truncate' => '空にする',
@@ -210,33 +183,31 @@ Lang::$translations = array(
'Move' => '移動', 'Move' => '移動',
'Save and continue edit' => '保存して継続', 'Save and continue edit' => '保存して継続',
'original' => '元', 'original' => '元',
'%d item(s) have been affected.' => '%d を更新しました', '%d item(s) have been affected.' => '%d を更新しました',
'Whole result' => '全結果', 'Whole result' => '全結果',
'Tables have been dropped.' => 'テーブルを削除しました', 'Tables have been dropped.' => 'テーブルを削除しました',
'Tables have been optimized.' => 'テーブルを最適化しました。',
'Clone' => 'クローン', 'Clone' => 'クローン',
'Maximum number of allowed fields exceeded. Please increase %s.' => '定義可能な最大フィールド数を越えました。%s を増やしてください。', 'Maximum number of allowed fields exceeded. Please increase %s.' => '定義可能な最大フィールド数を越えました。%s を増やしてください。',
'Partition by' => 'パーティション', 'Partition by' => 'パーティション',
'Partitions' => 'パーティション', 'Partitions' => 'パーティション',
'Partition name' => 'パーティション名', 'Partition name' => 'パーティション名',
'Values' => '値', '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' => '構造', 'Show structure' => '構造',
'anywhere' => '任意', 'anywhere' => '任意',
'Import' => 'インポート', 'Import' => 'インポート',
'Stop on error' => 'エラーの場合は停止', 'Stop on error' => 'エラーの場合は停止',
'Select data' => 'データ', 'Select data' => 'データ',
'%.3f s' => '%.3f 秒', '%.3f s' => '%.3f 秒',
'$1-$3-$5' => '$1/$3/$5', '$1-$3-$5' => '$1.$3.$5',
'[yyyy]-mm-dd' => '[yyyy]/mm/dd', '[yyyy]-mm-dd' => '[yyyy].mm.dd',
'History' => '履歴', 'History' => '履歴',
'Variables' => '変数', 'Variables' => '変数',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'ソースとターゲットの列は同じデータ型でなければなりません。ターゲット列に索引があり、データが存在しなければなりません。', 'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'ソースとターゲットの列は同じデータ型でなければなりません。ターゲット列に索引があり、データが存在しなければなりません。',
'Relations' => '関係', 'Relations' => '関係',
'Run file' => 'ファイルを実行', 'Run file' => 'ファイルを実行',
'Clear' => '消去', 'Clear' => '消去',
'Maximum allowed file size is %sB.' => '最大ファイルサイズ %sB です。', 'Maximum allowed file size is %sB.' => '最大ファイルサイズ %sB',
'Numbers' => '数字', 'Numbers' => '数字',
'Date and time' => '日時', 'Date and time' => '日時',
'Strings' => '文字列', 'Strings' => '文字列',
@@ -247,51 +218,49 @@ Lang::$translations = array(
'From' => '差出人', 'From' => '差出人',
'Subject' => '題名', 'Subject' => '題名',
'Send' => '送信', 'Send' => '送信',
'%d e-mail(s) have been sent.' => '%d メールを送信しました', '%d e-mail(s) have been sent.' => '%d メールを送信しました',
'Webserver file %s' => 'Webサーバファイル %s', 'Webserver file %s' => 'Webサーバファイル %s',
'File does not exist.' => 'ファイルは存在しません', 'File does not exist.' => 'ファイルは存在しません',
'%d in total' => '合計 %d', '%d in total' => '合計 %d',
'Permanent login' => '永続的にログイン', 'Permanent login' => '永続的にログイン',
'Databases have been dropped.' => 'データベースを削除しました', 'Databases have been dropped.' => 'データベースを削除しました',
'Search data in tables' => 'データを検索する', 'Search data in tables' => 'データを検索する',
'Schema' => 'スキーマ', 'Schema' => 'スキーマ',
'Alter schema' => 'スキーマ変更', 'Alter schema' => 'スキーマ変更',
'Create schema' => 'スキーマ追加', 'Create schema' => 'スキーマ追加',
'Schema has been dropped.' => 'スキーマを削除しました', 'Schema has been dropped.' => 'スキーマを削除しました',
'Schema has been created.' => 'スキーマを追加しました', 'Schema has been created.' => 'スキーマを追加しました',
'Schema has been altered.' => 'スキーマを変更しました', 'Schema has been altered.' => 'スキーマを変更しました',
'Sequences' => 'シーケンス', 'Sequences' => 'シーケンス',
'Create sequence' => 'シーケンス作成', 'Create sequence' => 'シーケンス作成',
'Alter sequence' => 'シーケンス変更', 'Alter sequence' => 'シーケンス変更',
'Sequence has been dropped.' => 'シーケンスを削除しました', 'Sequence has been dropped.' => 'シーケンスを削除しました',
'Sequence has been created.' => 'シーケンスを追加しました', 'Sequence has been created.' => 'シーケンスを追加しました',
'Sequence has been altered.' => 'シーケンスを変更しました', 'Sequence has been altered.' => 'シーケンスを変更しました',
'User types' => 'ユーザー定義型', 'User types' => 'ユーザー定義型',
'Create type' => 'ユーザー定義型作成', 'Create type' => 'ユーザー定義型作成',
'Alter type' => 'ユーザー定義型変更', 'Alter type' => 'ユーザー定義型変更',
'Type has been dropped.' => 'ユーザー定義型を削除しました', 'Type has been dropped.' => 'ユーザー定義型を削除しました',
'Type has been created.' => 'ユーザー定義型を追加しました', 'Type has been created.' => 'ユーザー定義型を追加しました',
'Ctrl+click on a value to modify it.' => 'Ctrl+クリックで値を修正します。', 'Use edit link to modify this value.' => 'リンクを編集する',
'Use edit link to modify this value.' => 'この値を修正するとリンクを編集します。',
'last' => '最終', 'last' => '最終',
'From server' => 'サーバーから実行', 'From server' => 'サーバーから実行',
'System' => 'データベース種類', 'System' => 'データベース種類',
'empty' => '空', 'empty' => '空',
'Network' => 'ネットワーク型', 'Network' => 'ネットワーク型',
'Geometry' => 'ジオメトリ型', 'Geometry' => 'ジオメトリ型',
'File exists.' => 'ファイルが既に存在します', 'File exists.' => 'ファイルが既に存在します',
'Attachments' => '添付ファイル', 'Attachments' => '添付ファイル',
'Item%s has been inserted.' => '%s項目を挿入しました', 'Item%s has been inserted.' => '%s項目を挿入しました',
'now' => '現在の日時', 'now' => '現在の日時',
'%d query(s) executed OK.' => '%d クエリーを実行しました', '%d query(s) executed OK.' => '%d クエリーを実行しました',
'Show only errors' => 'エラーのみ表示', 'Show only errors' => 'エラーのみ表示',
'Refresh' => 'リフレッシュ', 'Refresh' => 'リフレッシュ',
'Invalid schema.' => '無効なスキーマです。', 'Invalid schema.' => '無効なスキーマ',
'Please use one of the extensions %s.' => '%s のいずれかの拡張機能を使ってください', 'Please use one of the extensions %s.' => 'いずれかの拡張機能を使ってください %s',
'ltr' => 'ltr', 'ltr' => 'ltr',
'Tables have been copied.' => 'テーブルをコピーしました', 'Tables have been copied.' => 'テーブルをコピーしました',
'Copy' => 'コピー', 'Copy' => 'コピー',
'overwrite' => '上書き',
'Permanent link' => 'パーマネントリンク', 'Permanent link' => 'パーマネントリンク',
'Edit all' => 'すべて編集', 'Edit all' => 'すべて編集',
'HH:MM:SS' => '時:分:秒', 'HH:MM:SS' => '時:分:秒',
@@ -306,13 +275,31 @@ Lang::$translations = array(
'no' => 'いいえ', 'no' => 'いいえ',
'Default value' => '既定値', 'Default value' => '既定値',
// Table check constraints 'Drop %s?' => null,
'Checks' => 'チェック', 'Tables have been optimized.' => null,
'Create check' => 'チェックを作成', 'Materialized view' => null,
'Alter check' => 'チェックを変更', 'Vacuum' => null,
'Check has been created.' => 'チェックを作成しました。', 'overwrite' => null,
'Check has been altered.' => 'チェックを変更しました。', 'DB' => null,
'Check has been dropped.' => 'チェックを削除しました。', 'Ctrl+click on a value to modify it.' => null,
'File must be in UTF-8 encoding.' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
); );
// run `php ../../lang.php ja` to update this file

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'შესვლა', 'Login' => 'შესვლა',
'Logout successful.' => 'გამოხვედით სისტემიდან.', 'Logout successful.' => 'გამოხვედით სისტემიდან.',
'Invalid credentials.' => 'არასწორი მომხმარებელი ან პაროლი.', 'Invalid server or credentials.' => null,
'Server' => 'სერვერი', 'Server' => 'სერვერი',
'Username' => 'მომხმარებელი', 'Username' => 'მომხმარებელი',
'Password' => 'პაროლი', 'Password' => 'პაროლი',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'ბაზის შექმნა', 'Create database' => 'ბაზის შექმნა',
'SQL command' => 'SQL-ბრძანება', 'SQL command' => 'SQL-ბრძანება',
'Logout' => 'გასვლა', 'Logout' => 'გასვლა',
'database' => 'ბაზა',
'Use' => 'არჩევა', 'Use' => 'არჩევა',
'No tables.' => 'ბაზაში ცხრილი არაა.', 'No tables.' => 'ბაზაში ცხრილი არაა.',
'select' => 'არჩევა', 'select' => 'არჩევა',
@@ -95,7 +94,7 @@ Lang::$translations = array(
'ON DELETE' => 'წაშლისას', 'ON DELETE' => 'წაშლისას',
'ON UPDATE' => 'განახლებისას', 'ON UPDATE' => 'განახლებისას',
'Index Type' => 'ინდექსის სახეობა', 'Index Type' => 'ინდექსის სახეობა',
'length' => 'სიგრძე', 'Column (length)' => 'ველი (სიგრძე)',
'View has been dropped.' => 'წარმოდგენა წაიშალა.', 'View has been dropped.' => 'წარმოდგენა წაიშალა.',
'View has been altered.' => 'წარმოდგენა შეიცვალა.', 'View has been altered.' => 'წარმოდგენა შეიცვალა.',
'View has been created.' => 'წარმოდგენა შეიქმნა.', 'View has been created.' => 'წარმოდგენა შეიქმნა.',
@@ -301,6 +300,6 @@ Lang::$translations = array(
'Unknown error.' => 'უცნობი შეცდომა.', 'Unknown error.' => 'უცნობი შეცდომა.',
'Database does not support password.' => 'ბაზაში არაა მხარდაჭერილი პაროლი.', 'Database does not support password.' => 'ბაზაში არაა მხარდაჭერილი პაროლი.',
'Disable %s or enable %s or %s extensions.' => 'გათიშეთ %s ან ჩართეთ %s ან %s გაფართოება.', 'Disable %s or enable %s or %s extensions.' => 'გათიშეთ %s ან ჩართეთ %s ან %s გაფართოება.',
);
// run `php ../../lang.php ka` to update this file 'overwrite' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'$1-$3-$5' => '$1-$3-$5', '$1-$3-$5' => '$1-$3-$5',
'%.3f s' => '%.3f 초', '%.3f s' => '%.3f 초',
'%d byte(s)' => '%d 바이트', '%d byte(s)' => '%d 바이트',
@@ -48,7 +46,7 @@ Lang::$translations = array(
'Clone' => '복제', 'Clone' => '복제',
'collation' => '정렬', 'collation' => '정렬',
'Collation' => '정렬', 'Collation' => '정렬',
'length' => '길이', 'Column (length)' => '열 (길이)',
'Column name' => '열 이름', 'Column name' => '열 이름',
'Column' => '열', 'Column' => '열',
'Comment' => '주석', 'Comment' => '주석',
@@ -73,6 +71,7 @@ Lang::$translations = array(
'Database has been dropped.' => '데이터베이스를 삭제했습니다.', 'Database has been dropped.' => '데이터베이스를 삭제했습니다.',
'Database has been renamed.' => '데이터베이스의 이름을 바꾸었습니다.', 'Database has been renamed.' => '데이터베이스의 이름을 바꾸었습니다.',
'Database schema' => '데이터베이스 구조', 'Database schema' => '데이터베이스 구조',
'database' => '데이터베이스',
'Database' => '데이터베이스', 'Database' => '데이터베이스',
'Databases have been dropped.' => '데이터베이스를 삭제했습니다.', 'Databases have been dropped.' => '데이터베이스를 삭제했습니다.',
'Date and time' => '시간', 'Date and time' => '시간',
@@ -122,7 +121,7 @@ Lang::$translations = array(
'Indexes have been altered.' => '색인을 변경했습니다.', 'Indexes have been altered.' => '색인을 변경했습니다.',
'Indexes' => '색인', 'Indexes' => '색인',
'Insert' => '삽입', 'Insert' => '삽입',
'Invalid credentials.' => '잘못된 로그인.', 'Invalid server or credentials.' => null,
'Invalid CSRF token. Send the form again.' => '잘못된 CSRF 토큰입니다. 다시 보내주십시오.', 'Invalid CSRF token. Send the form again.' => '잘못된 CSRF 토큰입니다. 다시 보내주십시오.',
'Invalid database.' => '잘못된 데이터베이스입니다.', 'Invalid database.' => '잘못된 데이터베이스입니다.',
'Invalid schema.' => '잘못된 스키마입니다.', 'Invalid schema.' => '잘못된 스키마입니다.',
@@ -143,7 +142,7 @@ Lang::$translations = array(
'Logout successful.' => '로그아웃을 성공했습니다.', 'Logout successful.' => '로그아웃을 성공했습니다.',
'Logout' => '로그아웃', 'Logout' => '로그아웃',
'ltr' => 'ltr', 'ltr' => 'ltr',
'Maximum allowed file size is %sB.' => '파일의 최대 크기 %sB.', 'Maximum allowed file size is %sB.' => '파일의 최대 크기 %sB',
'Maximum number of allowed fields exceeded. Please increase %s.' => '정의 가능한 최대 필드 수를 초과했습니다. %s(을)를 늘리십시오.', 'Maximum number of allowed fields exceeded. Please increase %s.' => '정의 가능한 최대 필드 수를 초과했습니다. %s(을)를 늘리십시오.',
'Modify' => '수정', 'Modify' => '수정',
'Move down' => '아래로', 'Move down' => '아래로',
@@ -154,7 +153,7 @@ Lang::$translations = array(
'Network' => '네트워크 형', 'Network' => '네트워크 형',
'New item' => '항목 만들기', 'New item' => '항목 만들기',
'No commands to execute.' => '실행할 수 있는 명령이 없습니다.', 'No commands to execute.' => '실행할 수 있는 명령이 없습니다.',
'No extension' => '확장이 없습니다', 'No extension' => '확장이 없습니다.',
'No rows.' => '행이 없습니다.', 'No rows.' => '행이 없습니다.',
'No tables.' => '테이블이 없습니다.', 'No tables.' => '테이블이 없습니다.',
'None of the supported PHP extensions (%s) are available.' => 'PHP 확장(%s)이 설치되어 있지 않습니다.', 'None of the supported PHP extensions (%s) are available.' => 'PHP 확장(%s)이 설치되어 있지 않습니다.',
@@ -206,8 +205,8 @@ Lang::$translations = array(
'Schema' => '스키마', 'Schema' => '스키마',
'Search data in tables' => '테이블 내 데이터 검색', 'Search data in tables' => '테이블 내 데이터 검색',
'Search' => '검색', 'Search' => '검색',
'Select data' => '데이터를 선택하십시오', 'Select data' => '데이터를 선택하십시오.',
'Select database' => '데이터베이스를 선택하십시오', 'Select database' => '데이터베이스를 선택하십시오.',
'Select' => '선택', 'Select' => '선택',
'select' => '선택', 'select' => '선택',
'Selected' => '선택됨', 'Selected' => '선택됨',
@@ -238,7 +237,7 @@ Lang::$translations = array(
'Table name' => '테이블 이름', 'Table name' => '테이블 이름',
'Table' => '테이블', 'Table' => '테이블',
'Tables and views' => '테이블과 뷰', 'Tables and views' => '테이블과 뷰',
'Tables have been copied.' => '테이블을 복사했습니다.', 'Tables have been copied.' => '테이블을 복사했습니다',
'Tables have been dropped.' => '테이블을 삭제했습니다.', 'Tables have been dropped.' => '테이블을 삭제했습니다.',
'Tables have been moved.' => '테이블을 옮겼습니다.', 'Tables have been moved.' => '테이블을 옮겼습니다.',
'Tables have been truncated.' => '테이블의 데이터 내용만 지웠습니다.', 'Tables have been truncated.' => '테이블의 데이터 내용만 지웠습니다.',
@@ -256,7 +255,7 @@ Lang::$translations = array(
'Type has been created.' => '유형을 추가했습니다.', 'Type has been created.' => '유형을 추가했습니다.',
'Type has been dropped.' => '유형을 삭제했습니다.', 'Type has been dropped.' => '유형을 삭제했습니다.',
'Type' => '형', 'Type' => '형',
'Unable to select the table' => '테이블을 선택할 수 없습니다', 'Unable to select the table' => '테이블을 선택할 수 없습니다.',
'Unable to upload a file.' => '파일을 업로드 할 수 없습니다.', 'Unable to upload a file.' => '파일을 업로드 할 수 없습니다.',
'Use edit link to modify this value.' => '이 값을 수정하려면 편집 링크를 사용하십시오.', 'Use edit link to modify this value.' => '이 값을 수정하려면 편집 링크를 사용하십시오.',
'Use' => '사용', 'Use' => '사용',
@@ -278,6 +277,29 @@ Lang::$translations = array(
'You are offline.' => '오프라인입니다.', 'You are offline.' => '오프라인입니다.',
'You can upload a big SQL file via FTP and import it from server.' => '큰 SQL 파일은 FTP를 통하여 업로드하여 서버에서 가져올 수 있습니다.', 'You can upload a big SQL file via FTP and import it from server.' => '큰 SQL 파일은 FTP를 통하여 업로드하여 서버에서 가져올 수 있습니다.',
'You have no privileges to update this table.' => '이 테이블을 업데이트할 권한이 없습니다.', 'You have no privileges to update this table.' => '이 테이블을 업데이트할 권한이 없습니다.',
);
// run `php ../../lang.php ko` to update this file 'Drop %s?' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'User types' => null,
'DB' => null,
'Ctrl+click on a value to modify it.' => null,
'File must be in UTF-8 encoding.' => null,
'ATTACH queries are not supported.' => null,
'%d / ' => array(),
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'no' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistema', 'System' => 'Sistema',
'Server' => 'Serveris', 'Server' => 'Serveris',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Atsijungti', 'Logout' => 'Atsijungti',
'Logged as: %s' => 'Prisijungęs kaip: %s', 'Logged as: %s' => 'Prisijungęs kaip: %s',
'Logout successful.' => 'Jūs atsijungėte nuo sistemos.', 'Logout successful.' => 'Jūs atsijungėte nuo sistemos.',
'Invalid credentials.' => 'Neteisingi prisijungimo duomenys.', 'Invalid server or credentials.' => null,
'Language' => 'Kalba', 'Language' => 'Kalba',
'Invalid CSRF token. Send the form again.' => 'Neteisingas CSRF tokenas. Bandykite siųsti formos duomenis dar kartą.', 'Invalid CSRF token. Send the form again.' => 'Neteisingas CSRF tokenas. Bandykite siųsti formos duomenis dar kartą.',
'No extension' => 'Nėra plėtiio', 'No extension' => 'Nėra plėtiio',
@@ -75,6 +73,7 @@ Lang::$translations = array(
'Data' => 'Duomenys', 'Data' => 'Duomenys',
'Database' => 'Duomenų bazė', 'Database' => 'Duomenų bazė',
'database' => 'duomenų bazė',
'Use' => 'Naudoti', 'Use' => 'Naudoti',
'Select database' => 'Pasirinkti duomenų bazę', 'Select database' => 'Pasirinkti duomenų bazę',
'Invalid database.' => 'Neteisinga duomenų bazė.', 'Invalid database.' => 'Neteisinga duomenų bazė.',
@@ -183,7 +182,7 @@ Lang::$translations = array(
'Alter indexes' => 'Redaguoti indeksus', 'Alter indexes' => 'Redaguoti indeksus',
'Add next' => 'Pridėti kitą', 'Add next' => 'Pridėti kitą',
'Index Type' => 'Indekso tipas', 'Index Type' => 'Indekso tipas',
'length' => 'ilgis', 'Column (length)' => 'Stulpelis (ilgis)',
'Foreign keys' => 'Išoriniai raktai', 'Foreign keys' => 'Išoriniai raktai',
'Foreign key' => 'Išorinis raktas', 'Foreign key' => 'Išorinis raktas',
@@ -310,6 +309,42 @@ Lang::$translations = array(
'Type has been dropped.' => 'Tipas pašalintas.', 'Type has been dropped.' => 'Tipas pašalintas.',
'Type has been created.' => 'Tipas sukurtas.', 'Type has been created.' => 'Tipas sukurtas.',
'Alter type' => 'Keisti tipą', 'Alter type' => 'Keisti tipą',
);
// run `php ../../lang.php lt` to update this file 'Drop %s?' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'overwrite' => null,
'DB' => null,
'Ctrl+click on a value to modify it.' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
);

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Ieiet', 'Login' => 'Ieiet',
'Logout successful.' => 'Jūs veiksmīgi izgājāt no sistēmas.', 'Logout successful.' => 'Jūs veiksmīgi izgājāt no sistēmas.',
'Invalid credentials.' => 'Nepareizs lietotāja vārds vai parole.', 'Invalid server or credentials.' => null,
'Server' => 'Serveris', 'Server' => 'Serveris',
'Username' => 'Lietotājs', 'Username' => 'Lietotājs',
'Password' => 'Parole', 'Password' => 'Parole',
@@ -33,12 +31,13 @@ Lang::$translations = array(
'Create database' => 'Izveidot datubāzi', 'Create database' => 'Izveidot datubāzi',
'SQL command' => 'SQL pieprasījums', 'SQL command' => 'SQL pieprasījums',
'Logout' => 'Iziet', 'Logout' => 'Iziet',
'database' => 'datubāze',
'Use' => 'Lietot', 'Use' => 'Lietot',
'No tables.' => 'Datubāzē nav tabulu.', 'No tables.' => 'Datubāzē nav tabulu.',
'select' => 'izvēlēties', 'select' => 'izvēlēties',
'Item has been deleted.' => 'Ieraksts dzests.', 'Item has been deleted.' => 'Ieraksts dzests.',
'Item has been updated.' => 'Ieraksts atjaunots.', 'Item has been updated.' => 'Ieraksts atjaunots.',
'Item%s has been inserted.' => 'Ieraksti%s tika ievietoti.', 'Item%s has been inserted.' => 'Ieraksti tika ievietoti.',
'Edit' => 'Rediģēt', 'Edit' => 'Rediģēt',
'Insert' => 'Ievietot', 'Insert' => 'Ievietot',
'Save and insert next' => 'Saglabāt un ievietot nākamo', 'Save and insert next' => 'Saglabāt un ievietot nākamo',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'Pie dzēšanas', 'ON DELETE' => 'Pie dzēšanas',
'ON UPDATE' => 'Pie atjaunošanas', 'ON UPDATE' => 'Pie atjaunošanas',
'Index Type' => 'Indeksa tips', 'Index Type' => 'Indeksa tips',
'length' => 'garums', 'Column (length)' => 'Lauks (garums)',
'View has been dropped.' => 'Skats dzēsts.', 'View has been dropped.' => 'Skats dzēsts.',
'View has been altered.' => 'Skats izmainīts.', 'View has been altered.' => 'Skats izmainīts.',
'View has been created.' => 'Skats izveidots.', 'View has been created.' => 'Skats izveidots.',
@@ -243,7 +242,7 @@ Lang::$translations = array(
'Type has been dropped.' => 'Tips dzēsts.', 'Type has been dropped.' => 'Tips dzēsts.',
'Type has been created.' => 'Tips izveidots.', '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.', '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ā', 'last' => 'pēdējā',
'From server' => 'No servera', 'From server' => 'No servera',
'System' => 'Sistēma', 'System' => 'Sistēma',
@@ -301,6 +300,6 @@ Lang::$translations = array(
'There is a space in the input password which might be the cause.' => 'Parole satur atstarpi, kas varētu būt lieka.', 'There is a space in the input password which might be the cause.' => 'Parole satur atstarpi, kas varētu būt lieka.',
'Unknown error.' => 'Nezināma kļūda.', 'Unknown error.' => 'Nezināma kļūda.',
'Database does not support password.' => 'Datubāze neatbalsta paroli.', 'Database does not support password.' => 'Datubāze neatbalsta paroli.',
);
// run `php ../../lang.php lv` to update this file 'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem', 'System' => 'Sistem',
'Server' => 'Pelayan', 'Server' => 'Pelayan',
@@ -13,7 +11,7 @@ Lang::$translations = array(
'Logged as: %s' => 'Log masuk sebagai: %s', 'Logged as: %s' => 'Log masuk sebagai: %s',
'Logout successful.' => 'Log keluar berjaya.', 'Logout successful.' => 'Log keluar berjaya.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Terima kasih kerana menggunakan Adminer, pertimbangkan untuk <a href="https://www.adminer.org/en/donation/">menderma</a>.', 'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Terima kasih kerana menggunakan Adminer, pertimbangkan untuk <a href="https://www.adminer.org/en/donation/">menderma</a>.',
'Invalid credentials.' => 'Akses tidak sah.', 'Invalid server or credentials.' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => 'Terlalu banyak percubaan log masuk yang gagal, sila cuba lagi dalam masa %d minit.', 'Too many unsuccessful logins, try again in %d minute(s).' => 'Terlalu banyak percubaan log masuk yang gagal, sila cuba lagi dalam masa %d minit.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Kata laluan utama telah luput. <a href="https://www.adminer.org/en/extension/"%s>Gunakan</a> cara %s untuk mengekalkannya.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Kata laluan utama telah luput. <a href="https://www.adminer.org/en/extension/"%s>Gunakan</a> cara %s untuk mengekalkannya.',
'Language' => 'Bahasa', 'Language' => 'Bahasa',
@@ -84,6 +82,7 @@ Lang::$translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Pangkalan data', 'Database' => 'Pangkalan data',
'database' => 'pangkalan data',
'Use' => 'Guna', 'Use' => 'Guna',
'Select database' => 'Pilih pangkalan data', 'Select database' => 'Pilih pangkalan data',
'Invalid database.' => 'Pangkalan data tidak sah.', 'Invalid database.' => 'Pangkalan data tidak sah.',
@@ -199,7 +198,7 @@ Lang::$translations = array(
'Alter indexes' => 'Ubah indeks', 'Alter indexes' => 'Ubah indeks',
'Add next' => 'Tambah yang seterusnya', 'Add next' => 'Tambah yang seterusnya',
'Index Type' => 'Jenis Indeks', 'Index Type' => 'Jenis Indeks',
'length' => 'kepanjangan', 'Column (length)' => 'Kolum (kepanjangan)',
'Foreign keys' => 'Kunci asing', 'Foreign keys' => 'Kunci asing',
'Foreign key' => 'Kunci asing', 'Foreign key' => 'Kunci asing',
@@ -338,6 +337,14 @@ Lang::$translations = array(
'Type has been dropped.' => 'Jenis telah dijatuhkan.', 'Type has been dropped.' => 'Jenis telah dijatuhkan.',
'Type has been created.' => 'Jenis telah dibuat.', 'Type has been created.' => 'Jenis telah dibuat.',
'Alter type' => 'Ubah jenis', 'Alter type' => 'Ubah jenis',
);
// run `php ../../lang.php ms` to update this file 'overwrite' => null,
'DB' => null,
'Warnings' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'There is a space in the input password which might be the cause.' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Aanmelden', 'Login' => 'Aanmelden',
'Logout successful.' => 'Successvol afgemeld.', 'Logout successful.' => 'Successvol afgemeld.',
'Invalid credentials.' => 'Ongeldige gebruikersgegevens.', 'Invalid server or credentials.' => null,
'Server' => 'Server', 'Server' => 'Server',
'Username' => 'Gebruikersnaam', 'Username' => 'Gebruikersnaam',
'Password' => 'Wachtwoord', 'Password' => 'Wachtwoord',
@@ -34,6 +32,7 @@ Lang::$translations = array(
'Create database' => 'Database aanmaken', 'Create database' => 'Database aanmaken',
'SQL command' => 'SQL opdracht', 'SQL command' => 'SQL opdracht',
'Logout' => 'Afmelden', 'Logout' => 'Afmelden',
'database' => 'database',
'Use' => 'Gebruik', 'Use' => 'Gebruik',
'No tables.' => 'Geen tabellen.', 'No tables.' => 'Geen tabellen.',
'select' => 'kies', 'select' => 'kies',
@@ -98,7 +97,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Index type', 'Index Type' => 'Index type',
'length' => 'lengte', 'Column (length)' => 'Kolom (lengte)',
'View has been dropped.' => 'View verwijderd.', 'View has been dropped.' => 'View verwijderd.',
'View has been altered.' => 'View aangepast.', 'View has been altered.' => 'View aangepast.',
'View has been created.' => 'View aangemaakt.', 'View has been created.' => 'View aangemaakt.',
@@ -243,7 +242,7 @@ Lang::$translations = array(
'Type has been dropped.' => 'Type verwijderd.', 'Type has been dropped.' => 'Type verwijderd.',
'Type has been created.' => 'Type aangemaakt.', 'Type has been created.' => 'Type aangemaakt.',
'Ctrl+click on a value to modify it.' => 'Ctrl+klik op een waarde om deze te bewerken.', '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', 'last' => 'laatste',
'From server' => 'Van server', 'From server' => 'Van server',
'System' => 'Databasesysteem', 'System' => 'Databasesysteem',
@@ -254,7 +253,7 @@ Lang::$translations = array(
'Geometry' => 'Geometrie', 'Geometry' => 'Geometrie',
'File exists.' => 'Bestand bestaat reeds.', 'File exists.' => 'Bestand bestaat reeds.',
'Attachments' => 'Bijlagen', 'Attachments' => 'Bijlagen',
'%d query(s) executed OK.' => array('%d query succesvol uitgevoerd.', '%d querys succesvol uitgevoerd.'), '%d query(s) executed OK.' => array('%d query succesvol uitgevoerd.', '%d querys succesvol uitgevoerd'),
'Show only errors' => 'Enkel fouten tonen', 'Show only errors' => 'Enkel fouten tonen',
'Refresh' => 'Vernieuwen', 'Refresh' => 'Vernieuwen',
'Invalid schema.' => 'Ongeldig schema.', 'Invalid schema.' => 'Ongeldig schema.',
@@ -266,6 +265,7 @@ Lang::$translations = array(
'Permanent link' => 'Permanente link', 'Permanent link' => 'Permanente link',
'Edit all' => 'Alles bewerken', 'Edit all' => 'Alles bewerken',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
'Drop %s?' => 'Verwijder %s?', 'Drop %s?' => 'Verwijder %s?',
'Tables have been optimized.' => 'Tabellen zijn geoptimaliseerd.', 'Tables have been optimized.' => 'Tabellen zijn geoptimaliseerd.',
'Materialized view' => 'Materialized view', 'Materialized view' => 'Materialized view',
@@ -277,7 +277,7 @@ Lang::$translations = array(
'Modify' => 'Aanpassen', 'Modify' => 'Aanpassen',
'Load more data' => 'Meer data inladen', 'Load more data' => 'Meer data inladen',
'Loading' => 'Aan het laden', 'Loading' => 'Aan het laden',
'ATTACH queries are not supported.' => 'ATTACH queries worden niet ondersteund.', 'ATTACH queries are not supported.' => 'ATTACH queries worden niet ondersteund',
'Warnings' => 'Waarschuwingen', 'Warnings' => 'Waarschuwingen',
'%d / ' => '%d / ', '%d / ' => '%d / ',
'Limit rows' => 'Rijen beperken', 'Limit rows' => 'Rijen beperken',
@@ -285,8 +285,9 @@ Lang::$translations = array(
'Default value' => 'Standaardwaarde', 'Default value' => 'Standaardwaarde',
'Full table scan' => 'Full table scan', 'Full table scan' => 'Full table scan',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Teveel foutieve aanmeldpogingen, probeer opnieuw binnen %d minuut.', 'Teveel foutieve aanmeldpogingen, probeer opnieuw binnen %d minuten.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Teveel foutieve aanmeldpogingen, probeer opnieuw binnen %d minuut.', 'Teveel foutieve aanmeldpogingen, probeer opnieuw binnen %d minuten.'),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master wachtwoord verlopen. <a href="https://www.adminer.org/en/extension/"%s>Implementeer</a> de %s methode om het permanent te maken.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master wachtwoord verlopen. <a href="https://www.adminer.org/en/extension/"%s>Implementeer</a> de %s methode om het permanent te maken.',
'The action will be performed after successful login with the same credentials.' => 'Deze actie zal uitgevoerd worden na het succesvol aanmelden met dezelfde gebruikersgegevens.', 'The action will be performed after successful login with the same credentials.' => 'Deze actie zal uitgevoerd worden na het succesvol aanmelden met dezelfde gebruikersgegevens',
'Connecting to privileged ports is not allowed.' => 'Verbindingen naar geprivilegieerde poorten is niet toegestaan.', 'Connecting to privileged ports is not allowed.' => 'Verbindingen naar geprivilegieerde poorten is niet toegestaan.',
'There is a space in the input password which might be the cause.' => 'Er staat een spatie in het wachtwoord, wat misschien de oorzaak is.', 'There is a space in the input password which might be the cause.' => 'Er staat een spatie in het wachtwoord, wat misschien de oorzaak is.',
'If you did not send this request from Adminer then close this page.' => 'Als u deze actie niet via Adminer hebt gedaan, gelieve deze pagina dan te sluiten.', 'If you did not send this request from Adminer then close this page.' => 'Als u deze actie niet via Adminer hebt gedaan, gelieve deze pagina dan te sluiten.',
@@ -296,11 +297,9 @@ Lang::$translations = array(
'You are offline.' => 'U bent offline.', 'You are offline.' => 'U bent offline.',
'You have no privileges to update this table.' => 'U bent niet gemachtigd om deze tabel aan te passen.', 'You have no privileges to update this table.' => 'U bent niet gemachtigd om deze tabel aan te passen.',
'Saving' => 'Opslaan', 'Saving' => 'Opslaan',
'Unknown error.' => 'Onbekende fout.', 'Unknown error.' => 'Onbekende fout',
'Database does not support password.' => 'Database ondersteunt het wachtwoord niet.', 'Database does not support password.' => 'Database ondersteunt het wachtwoord niet.',
'Disable %s or enable %s or %s extensions.' => 'Schakel %s uit or schakel extensies %s of %s in.', 'Disable %s or enable %s or %s extensions.' => 'Schakel %s uit or schakel extensies %s of %s in.',
'yes' => 'ja', 'yes' => 'ja',
'no' => 'neen', 'no' => 'neen',
); );
// run `php ../../lang.php nl` to update this file

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'System' => 'System', 'System' => 'System',
'Server' => 'Server', 'Server' => 'Server',
'Username' => 'Brukernavn', 'Username' => 'Brukernavn',
@@ -11,7 +9,7 @@ Lang::$translations = array(
'Logout' => 'Logg ut', 'Logout' => 'Logg ut',
'Logged as: %s' => 'Logget inn som: %s', 'Logged as: %s' => 'Logget inn som: %s',
'Logout successful.' => 'Utlogging vellykket.', 'Logout successful.' => 'Utlogging vellykket.',
'Invalid credentials.' => 'Ugylding innloggingsinformasjon.', 'Invalid server or credentials.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-passord er utløpt. <a href="https://www.adminer.org/en/extension/"%s>Implementer</a> en metode for %s for å gjøre det permanent.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-passord er utløpt. <a href="https://www.adminer.org/en/extension/"%s>Implementer</a> en metode for %s for å gjøre det permanent.',
'Language' => 'Språk', 'Language' => 'Språk',
'Invalid CSRF token. Send the form again.' => 'Ugylding CSRF-token - Send inn skjemaet igjen.', 'Invalid CSRF token. Send the form again.' => 'Ugylding CSRF-token - Send inn skjemaet igjen.',
@@ -66,6 +64,7 @@ Lang::$translations = array(
'Format' => 'Format', 'Format' => 'Format',
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Database', 'Database' => 'Database',
'database' => 'database',
'Use' => 'Bruk', 'Use' => 'Bruk',
'Select database' => 'Velg database', 'Select database' => 'Velg database',
'Invalid database.' => 'Ugyldig database.', 'Invalid database.' => 'Ugyldig database.',
@@ -166,7 +165,7 @@ Lang::$translations = array(
'Alter indexes' => 'Endre indekser', 'Alter indexes' => 'Endre indekser',
'Add next' => 'Legg til neste', 'Add next' => 'Legg til neste',
'Index Type' => 'Indekstype', 'Index Type' => 'Indekstype',
'length' => 'lengde', 'Column (length)' => 'Kolonne (lengde)',
'Foreign keys' => 'Fremmednøkler', 'Foreign keys' => 'Fremmednøkler',
'Foreign key' => 'Fremmednøkkel', 'Foreign key' => 'Fremmednøkkel',
'Foreign key has been dropped.' => 'Fremmednøkkelen er slettet.', 'Foreign key has been dropped.' => 'Fremmednøkkelen er slettet.',
@@ -280,6 +279,27 @@ Lang::$translations = array(
'Type has been created.' => 'Type er opprettet.', 'Type has been created.' => 'Type er opprettet.',
'Alter type' => 'Endre type', 'Alter type' => 'Endre type',
'Saving' => 'Lagrer', 'Saving' => 'Lagrer',
);
// run `php ../../lang.php no` to update this file 'Drop %s?' => null,
'Materialized view' => null,
'overwrite' => null,
'DB' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

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

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Entrar', 'Login' => 'Entrar',
'Logout successful.' => 'Saída bem sucedida.', 'Logout successful.' => 'Saída bem sucedida.',
'Invalid credentials.' => 'Identificação inválida.', 'Invalid server or credentials.' => null,
'Server' => 'Servidor', 'Server' => 'Servidor',
'Username' => 'Usuário', 'Username' => 'Usuário',
'Password' => 'Senha', 'Password' => 'Senha',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Criar Base de dados', 'Create database' => 'Criar Base de dados',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Sair', 'Logout' => 'Sair',
'database' => 'base de dados',
'Use' => 'Usar', 'Use' => 'Usar',
'No tables.' => 'Não existem tabelas.', 'No tables.' => 'Não existem tabelas.',
'select' => 'selecionar', 'select' => 'selecionar',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Tipo de índice', 'Index Type' => 'Tipo de índice',
'length' => 'tamanho', 'Column (length)' => 'Coluna (tamanho)',
'View has been dropped.' => 'A Visão foi apagada.', 'View has been dropped.' => 'A Visão foi apagada.',
'View has been altered.' => 'A Visão foi alterada.', 'View has been altered.' => 'A Visão foi alterada.',
'View has been created.' => 'A Visão foi criada.', 'View has been created.' => 'A Visão foi criada.',
@@ -261,6 +260,46 @@ Lang::$translations = array(
'Please use one of the extensions %s.' => 'Por favor use uma das extensões %s.', 'Please use one of the extensions %s.' => 'Por favor use uma das extensões %s.',
'now' => 'agora', 'now' => 'agora',
'ltr' => 'ltr', 'ltr' => 'ltr',
);
// run `php ../../lang.php pt-br` to update this file 'Drop %s?' => null,
'Tables have been copied.' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'Copy' => null,
'overwrite' => null,
'DB' => null,
'Permanent link' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Edit all' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
'HH:MM:SS' => null,
);

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Entrar', 'Login' => 'Entrar',
'Logout successful.' => 'Sessão terminada com sucesso.', 'Logout successful.' => 'Sessão terminada com sucesso.',
'Invalid credentials.' => 'Identificação inválida.', 'Invalid server or credentials.' => null,
'Server' => 'Servidor', 'Server' => 'Servidor',
'Username' => 'Nome de utilizador', 'Username' => 'Nome de utilizador',
'Password' => 'Senha', 'Password' => 'Senha',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Criar Base de dados', 'Create database' => 'Criar Base de dados',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Terminar sessão', 'Logout' => 'Terminar sessão',
'database' => 'base de dados',
'Use' => 'Usar', 'Use' => 'Usar',
'No tables.' => 'Não existem tabelas.', 'No tables.' => 'Não existem tabelas.',
'select' => 'registos', 'select' => 'registos',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Tipo de índice', 'Index Type' => 'Tipo de índice',
'length' => 'tamanho', 'Column (length)' => 'coluna (tamanho)',
'View has been dropped.' => 'Vista eliminada.', 'View has been dropped.' => 'Vista eliminada.',
'View has been altered.' => 'Vista modificada.', 'View has been altered.' => 'Vista modificada.',
'View has been created.' => 'Vista criada.', 'View has been created.' => 'Vista criada.',
@@ -261,6 +260,46 @@ Lang::$translations = array(
'Please use one of the extensions %s.' => 'Por favor use uma das extensões %s.', 'Please use one of the extensions %s.' => 'Por favor use uma das extensões %s.',
'now' => 'agora', 'now' => 'agora',
'ltr' => 'ltr', 'ltr' => 'ltr',
);
// run `php ../../lang.php pt` to update this file 'Drop %s?' => null,
'Tables have been copied.' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'Copy' => null,
'overwrite' => null,
'DB' => null,
'Permanent link' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Edit all' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
'HH:MM:SS' => null,
);

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Intră', 'Login' => 'Intră',
'Logout successful.' => 'Ați ieșit cu succes.', 'Logout successful.' => 'Ați ieșit cu succes.',
'Invalid credentials.' => 'Numele de utilizator sau parola este greșită.', 'Invalid server or credentials.' => null,
'Server' => 'Server', 'Server' => 'Server',
'Username' => 'Nume de utilizator', 'Username' => 'Nume de utilizator',
'Password' => 'Parola', 'Password' => 'Parola',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Crează baza de date', 'Create database' => 'Crează baza de date',
'SQL command' => 'SQL query', 'SQL command' => 'SQL query',
'Logout' => 'Ieșire', 'Logout' => 'Ieșire',
'database' => 'baza de date',
'Use' => 'Alege', 'Use' => 'Alege',
'No tables.' => 'În baza de date nu sunt tabele.', 'No tables.' => 'În baza de date nu sunt tabele.',
'select' => 'selectează', 'select' => 'selectează',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'La ștergere', 'ON DELETE' => 'La ștergere',
'ON UPDATE' => 'La modificare', 'ON UPDATE' => 'La modificare',
'Index Type' => 'Tipul indexului', 'Index Type' => 'Tipul indexului',
'length' => 'lungimea', 'Column (length)' => 'Coloană (lungimea)',
'View has been dropped.' => 'Reprezentarea a fost ștearsă.', 'View has been dropped.' => 'Reprezentarea a fost ștearsă.',
'View has been altered.' => 'Reprezentarea a fost modificată.', 'View has been altered.' => 'Reprezentarea a fost modificată.',
'View has been created.' => 'Reprezentarea a fost creată.', 'View has been created.' => 'Reprezentarea a fost creată.',
@@ -261,11 +260,46 @@ Lang::$translations = array(
'Please use one of the extensions %s.' => 'Folosiți una din următoarele extensii %s.', 'Please use one of the extensions %s.' => 'Folosiți una din următoarele extensii %s.',
'now' => 'acum', 'now' => 'acum',
'ltr' => 'ltr', 'ltr' => 'ltr',
'Tables have been copied.' => 'Tabelele au fost copiate.', 'Tables have been copied.' => 'Tabelele au fost copiate',
'Copy' => 'Copiază', 'Copy' => 'Copiază',
'Permanent link' => 'Adresă permanentă', 'Permanent link' => 'Adresă permanentă',
'Edit all' => 'Editează tot', 'Edit all' => 'Editează tot',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
);
// run `php ../../lang.php ro` to update this file 'Drop %s?' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'overwrite' => null,
'DB' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
);

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Войти', 'Login' => 'Войти',
'Logout successful.' => 'Вы успешно покинули систему.', 'Logout successful.' => 'Вы успешно покинули систему.',
'Invalid credentials.' => 'Неправильное имя пользователя или пароль.', 'Invalid server or credentials.' => null,
'Server' => 'Сервер', 'Server' => 'Сервер',
'Username' => 'Имя пользователя', 'Username' => 'Имя пользователя',
'Password' => 'Пароль', 'Password' => 'Пароль',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Создать базу данных', 'Create database' => 'Создать базу данных',
'SQL command' => 'SQL-запрос', 'SQL command' => 'SQL-запрос',
'Logout' => 'Выйти', 'Logout' => 'Выйти',
'database' => 'база данных',
'Use' => 'Выбрать', 'Use' => 'Выбрать',
'No tables.' => 'В базе данных нет таблиц.', 'No tables.' => 'В базе данных нет таблиц.',
'select' => 'выбрать', 'select' => 'выбрать',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'При стирании', 'ON DELETE' => 'При стирании',
'ON UPDATE' => 'При обновлении', 'ON UPDATE' => 'При обновлении',
'Index Type' => 'Тип индекса', 'Index Type' => 'Тип индекса',
'length' => 'длина', 'Column (length)' => 'Поле (длина)',
'View has been dropped.' => 'Представление было удалено.', 'View has been dropped.' => 'Представление было удалено.',
'View has been altered.' => 'Представление было изменено.', 'View has been altered.' => 'Представление было изменено.',
'View has been created.' => 'Представление было создано.', 'View has been created.' => 'Представление было создано.',
@@ -301,16 +300,6 @@ Lang::$translations = array(
'There is a space in the input password which might be the cause.' => 'В введеном пароле есть пробел, это может быть причиною.', 'There is a space in the input password which might be the cause.' => 'В введеном пароле есть пробел, это может быть причиною.',
'Unknown error.' => 'Неизвестная ошибка.', 'Unknown error.' => 'Неизвестная ошибка.',
'Database does not support password.' => 'База данных не поддерживает пароль.', 'Database does not support password.' => 'База данных не поддерживает пароль.',
'Disable %s or enable %s or %s extensions.' => 'Отключите %s или включите расширения %s или %s.',
'Check has been dropped.' => 'Проверка удалена.',
'Check has been altered.' => 'Проверка изменена.',
'Check has been created.' => 'Проверка создана.',
'Alter check' => 'Изменить проверку',
'Create check' => 'Создать проверку',
'Checks' => 'Проверки',
'Loaded plugins' => 'Загруженные плагины',
'%s must <a%s>return an array</a>.' => '%s должна <a%s>вернуть массив</a>.',
'<a%s>Configure</a> %s in %s.' => '<a%s>Настроить</a> %s в %s.',
);
// run `php ../../lang.php ru` to update this file 'Disable %s or enable %s or %s extensions.' => 'Отключите %s или включите расширения %s или %s.',
);

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'Prihlásiť sa', 'Login' => 'Prihlásiť sa',
'Logout successful.' => 'Odhlásenie prebehlo v poriadku.', 'Logout successful.' => 'Odhlásenie prebehlo v poriadku.',
'Invalid credentials.' => 'Neplatné prihlasovacie údaje.', 'Invalid server or credentials.' => 'Neplatný server alebo prihlasovacie údaje.',
'Server' => 'Server', 'Server' => 'Server',
'Username' => 'Používateľ', 'Username' => 'Používateľ',
'Password' => 'Heslo', 'Password' => 'Heslo',
@@ -34,6 +32,7 @@ Lang::$translations = array(
'Create database' => 'Vytvoriť databázu', 'Create database' => 'Vytvoriť databázu',
'SQL command' => 'SQL príkaz', 'SQL command' => 'SQL príkaz',
'Logout' => 'Odhlásiť', 'Logout' => 'Odhlásiť',
'database' => 'databáza',
'Use' => 'Vybrať', 'Use' => 'Vybrať',
'No tables.' => 'Žiadne tabuľky.', 'No tables.' => 'Žiadne tabuľky.',
'select' => 'vypísať', 'select' => 'vypísať',
@@ -98,7 +97,7 @@ Lang::$translations = array(
'ON DELETE' => 'Pri zmazaní', 'ON DELETE' => 'Pri zmazaní',
'ON UPDATE' => 'Pri aktualizácii', 'ON UPDATE' => 'Pri aktualizácii',
'Index Type' => 'Typ indexu', 'Index Type' => 'Typ indexu',
'length' => 'dĺžka', 'Column (length)' => 'Stĺpec (dĺžka)',
'View has been dropped.' => 'Pohľad bol odstránený.', 'View has been dropped.' => 'Pohľad bol odstránený.',
'View has been altered.' => 'Pohľad bol zmenený.', 'View has been altered.' => 'Pohľad bol zmenený.',
'View has been created.' => 'Pohľad bol vytvorený.', 'View has been created.' => 'Pohľad bol vytvorený.',
@@ -266,6 +265,7 @@ Lang::$translations = array(
'Permanent link' => 'Permanentný odkaz', 'Permanent link' => 'Permanentný odkaz',
'Edit all' => 'Upraviť všetko', 'Edit all' => 'Upraviť všetko',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
'Drop %s?' => 'Odstrániť %s?', 'Drop %s?' => 'Odstrániť %s?',
'Tables have been optimized.' => 'Tabuľky boli optimalizované.', 'Tables have been optimized.' => 'Tabuľky boli optimalizované.',
'Materialized view' => 'Materializovaný pohľad', 'Materialized view' => 'Materializovaný pohľad',
@@ -275,17 +275,17 @@ Lang::$translations = array(
'DB' => 'DB', 'DB' => 'DB',
'File must be in UTF-8 encoding.' => 'Súbor musí byť v kódovaní UTF-8.', 'File must be in UTF-8 encoding.' => 'Súbor musí byť v kódovaní UTF-8.',
'Modify' => 'Zmeniť', 'Modify' => 'Zmeniť',
'Load more data' => 'Načítať ďalšie dáta', 'Load more data' => 'Nahráť ďalšie dáta',
'Loading' => 'Načítava sa', 'Loading' => 'Nahráva sa',
'ATTACH queries are not supported.' => 'Dotazy ATTACH nie sú podporované.', 'ATTACH queries are not supported.' => 'Dotazy ATTACH nie sú podporované.',
'Warnings' => 'Varovania', 'Warnings' => 'Varovania',
'%d / ' => '%d / ', '%d / ' => '%d / ',
'Limit rows' => 'Limit riadkov', 'Limit rows' => 'Limit riadkov',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer nepodporuje prístup k databáze bez hesla, <a href="https://www.adminer.org/sk/password/"%s>viac informácií</a>.', 'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer nepodporuje prístup k databáze bez hesla, <a href="https://www.adminer.org/cs/password/"%s>viac informácií</a>.',
'Default value' => 'Predvolená hodnota', 'Default value' => 'Predvolená hodnota',
'Full table scan' => 'Prechod celej tabuľky', '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.'), '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/sk/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/cs/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.', '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.', '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é.', 'Connecting to privileged ports is not allowed.' => 'Pripojenie k privilegovaným portom nie je povolené.',
@@ -302,12 +302,4 @@ Lang::$translations = array(
'Disable %s or enable %s or %s extensions.' => 'Zakážte %s alebo povoľte rozšírenie %s alebo %s.', 'Disable %s or enable %s or %s extensions.' => 'Zakážte %s alebo povoľte rozšírenie %s alebo %s.',
'yes' => 'áno', 'yes' => 'áno',
'no' => 'nie', '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

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem', 'System' => 'Sistem',
'Server' => 'Strežnik', 'Server' => 'Strežnik',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Odjavi se', 'Logout' => 'Odjavi se',
'Logged as: %s' => 'Prijavljen kot: %s', 'Logged as: %s' => 'Prijavljen kot: %s',
'Logout successful.' => 'Prijava uspešna.', 'Logout successful.' => 'Prijava uspešna.',
'Invalid credentials.' => 'Neveljavne pravice.', 'Invalid server or credentials.' => 'Neveljaven strežnik ali pravice.',
'Language' => 'Jezik', 'Language' => 'Jezik',
'Invalid CSRF token. Send the form again.' => 'Neveljaven token CSRF. Pošljite formular še enkrat.', 'Invalid CSRF token. Send the form again.' => 'Neveljaven token CSRF. Pošljite formular še enkrat.',
'No extension' => 'Brez dodatkov', 'No extension' => 'Brez dodatkov',
@@ -74,6 +72,7 @@ Lang::$translations = array(
'Data' => 'Podatki', 'Data' => 'Podatki',
'Database' => 'Baza', 'Database' => 'Baza',
'database' => 'baza',
'Use' => 'Uporabi', 'Use' => 'Uporabi',
'Select database' => 'Izberi bazo', 'Select database' => 'Izberi bazo',
'Invalid database.' => 'Neveljavna baza.', 'Invalid database.' => 'Neveljavna baza.',
@@ -179,7 +178,7 @@ Lang::$translations = array(
'Alter indexes' => 'Spremeni indekse', 'Alter indexes' => 'Spremeni indekse',
'Add next' => 'Dodaj naslednjega', 'Add next' => 'Dodaj naslednjega',
'Index Type' => 'Tip indeksa', 'Index Type' => 'Tip indeksa',
'length' => 'dolžina', 'Column (length)' => 'Stolpec (dolžina)',
'Foreign keys' => 'Tuji ključi', 'Foreign keys' => 'Tuji ključi',
'Foreign key' => 'Tuj ključ', 'Foreign key' => 'Tuj ključ',
@@ -305,6 +304,44 @@ Lang::$translations = array(
'Type has been dropped.' => 'Tip je zavržen.', 'Type has been dropped.' => 'Tip je zavržen.',
'Type has been created.' => 'Tip je ustvarjen.', 'Type has been created.' => 'Tip je ustvarjen.',
'Alter type' => 'Spremeni tip', 'Alter type' => 'Spremeni tip',
);
// run `php ../../lang.php sl` to update this file 'Drop %s?' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'overwrite' => null,
'DB' => null,
'Permanent link' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Edit all' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
'HH:MM:SS' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Систем', 'System' => 'Систем',
'Server' => 'Сервер', 'Server' => 'Сервер',
@@ -12,11 +10,11 @@ Lang::$translations = array(
'Logout' => 'Одјава', 'Logout' => 'Одјава',
'Logged as: %s' => 'Пријави се као: %s', 'Logged as: %s' => 'Пријави се као: %s',
'Logout successful.' => 'Успешна одјава.', 'Logout successful.' => 'Успешна одјава.',
'Invalid credentials.' => 'Неважеће дозволе.', 'Invalid server or credentials.' => null,
'Language' => 'Језик', 'Language' => 'Језик',
'Invalid CSRF token. Send the form again.' => 'Неважећи CSRF код. Проследите поново форму.', 'Invalid CSRF token. Send the form again.' => 'Неважећи CSRF код. Проследите поново форму.',
'No extension' => 'Без додатака', 'No extension' => 'Без додатака',
'None of the supported PHP extensions (%s) are available.' => 'Ниједан од подржаних PHP додатака (%s) није доступан.', 'None of the supported PHP extensions (%s) are available.' => 'Ниједан од подржаних PHP додатака није доступан.',
'Session support must be enabled.' => 'Морате омогућити подршку за сесије.', 'Session support must be enabled.' => 'Морате омогућити подршку за сесије.',
'Session expired, please login again.' => 'Ваша сесија је истекла, пријавите се поново.', 'Session expired, please login again.' => 'Ваша сесија је истекла, пријавите се поново.',
'%s version: %s through PHP extension %s' => '%s верзија: %s помоћу PHP додатка је %s', '%s version: %s through PHP extension %s' => '%s верзија: %s помоћу PHP додатка је %s',
@@ -75,6 +73,7 @@ Lang::$translations = array(
'Data' => 'Податци', 'Data' => 'Податци',
'Database' => 'База података', 'Database' => 'База података',
'database' => 'база података',
'Use' => 'Користи', 'Use' => 'Користи',
'Select database' => 'Изаберите базу', 'Select database' => 'Изаберите базу',
'Invalid database.' => 'Неисправна база података.', 'Invalid database.' => 'Неисправна база података.',
@@ -184,7 +183,7 @@ Lang::$translations = array(
'Alter indexes' => 'Уреди индексе', 'Alter indexes' => 'Уреди индексе',
'Add next' => 'Додај следећи', 'Add next' => 'Додај следећи',
'Index Type' => 'Тип индекса', 'Index Type' => 'Тип индекса',
'length' => 'дужина', 'Column (length)' => 'Колона (дужина)',
'Foreign keys' => 'Страни кључеви', 'Foreign keys' => 'Страни кључеви',
'Foreign key' => 'Страни кључ', 'Foreign key' => 'Страни кључ',
@@ -317,6 +316,35 @@ Lang::$translations = array(
'Type has been dropped.' => 'Тип је избрисан.', 'Type has been dropped.' => 'Тип је избрисан.',
'Type has been created.' => 'тип је креиран.', 'Type has been created.' => 'тип је креиран.',
'Alter type' => 'Уреди тип', 'Alter type' => 'Уреди тип',
);
// run `php ../../lang.php sr` to update this file 'Drop %s?' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'overwrite' => null,
'DB' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'System', 'System' => 'System',
'Server' => 'Server', 'Server' => 'Server',
@@ -13,7 +11,7 @@ Lang::$translations = array(
'Logged as: %s' => 'Inloggad som: %s', 'Logged as: %s' => 'Inloggad som: %s',
'Logout successful.' => 'Du är nu utloggad.', 'Logout successful.' => 'Du är nu utloggad.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Tack för att du använder Adminer, vänligen fundera över att <a href="https://www.adminer.org/en/donation/">donera</a>.', 'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Tack för att du använder Adminer, vänligen fundera över att <a href="https://www.adminer.org/en/donation/">donera</a>.',
'Invalid credentials.' => 'Ogiltiga inloggningsuppgifter.', 'Invalid server or credentials.' => null,
'There is a space in the input password which might be the cause.' => 'Det finns ett mellanslag i lösenordet, vilket kan vara anledningen.', 'There is a space in the input password which might be the cause.' => 'Det finns ett mellanslag i lösenordet, vilket kan vara anledningen.',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer tillåter inte att ansluta till en databas utan lösenord. <a href="https://www.adminer.org/en/password/"%s>Mer information</a>.', 'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer tillåter inte att ansluta till en databas utan lösenord. <a href="https://www.adminer.org/en/password/"%s>Mer information</a>.',
'Database does not support password.' => 'Databasen stödjer inte lösenord.', 'Database does not support password.' => 'Databasen stödjer inte lösenord.',
@@ -91,6 +89,7 @@ Lang::$translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Databas', 'Database' => 'Databas',
'database' => 'databas',
'DB' => 'DB', 'DB' => 'DB',
'Use' => 'Använd', 'Use' => 'Använd',
'Select database' => 'Välj databas', 'Select database' => 'Välj databas',
@@ -208,7 +207,7 @@ Lang::$translations = array(
'Alter indexes' => 'Ändra index', 'Alter indexes' => 'Ändra index',
'Add next' => 'Lägg till nästa', 'Add next' => 'Lägg till nästa',
'Index Type' => 'Indextyp', 'Index Type' => 'Indextyp',
'length' => 'längd', 'Column (length)' => 'Kolumn (längd)',
'Foreign keys' => 'Främmande nycklar', 'Foreign keys' => 'Främmande nycklar',
'Foreign key' => 'Främmande nyckel', 'Foreign key' => 'Främmande nyckel',
@@ -348,5 +347,3 @@ Lang::$translations = array(
'Type has been created.' => 'Typ har skapats.', 'Type has been created.' => 'Typ har skapats.',
'Alter type' => 'Ändra typ', 'Alter type' => 'Ändra typ',
); );
// run `php ../../lang.php sv` to update this file

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'நுழை', 'Login' => 'நுழை',
'Logout successful.' => 'வெற்றிக‌ர‌மாய் வெளியேறியாயிற்று.', 'Logout successful.' => 'வெற்றிக‌ர‌மாய் வெளியேறியாயிற்று.',
'Invalid credentials.' => 'ச‌ரியான‌ விப‌ர‌ங்க‌ள் இல்லை.', 'Invalid server or credentials.' => null,
'Server' => 'வ‌ழ‌ங்கி (Server)', 'Server' => 'வ‌ழ‌ங்கி (Server)',
'Username' => 'ப‌ய‌னாள‌ர் (User)', 'Username' => 'ப‌ய‌னாள‌ர் (User)',
'Password' => 'க‌ட‌வுச்சொல்', 'Password' => 'க‌ட‌வுச்சொல்',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'த‌க‌வ‌ல்த‌ள‌த்தை உருவாக்கு', 'Create database' => 'த‌க‌வ‌ல்த‌ள‌த்தை உருவாக்கு',
'SQL command' => 'SQL க‌ட்ட‌ளை', 'SQL command' => 'SQL க‌ட்ட‌ளை',
'Logout' => 'வெளியேறு', 'Logout' => 'வெளியேறு',
'database' => 'த‌க‌வ‌ல்த‌ள‌ம்',
'Use' => 'உப‌யோகி', 'Use' => 'உப‌யோகி',
'No tables.' => 'அட்ட‌வ‌ணை இல்லை.', 'No tables.' => 'அட்ட‌வ‌ணை இல்லை.',
'select' => 'தேர்வு செய்', 'select' => 'தேர்வு செய்',
@@ -95,7 +94,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'அக‌வ‌ரிசை வ‌கை (Index Type)', 'Index Type' => 'அக‌வ‌ரிசை வ‌கை (Index Type)',
'length' => 'நீள‌ம்', 'Column (length)' => 'நெடுவ‌ரிசை (நீள‌ம்)',
'View has been dropped.' => 'தோற்ற‌ம் நீக்க‌ப்ப‌ட்ட‌து.', 'View has been dropped.' => 'தோற்ற‌ம் நீக்க‌ப்ப‌ட்ட‌து.',
'View has been altered.' => 'தோற்றம் மாற்றப்ப‌ட்ட‌து.', 'View has been altered.' => 'தோற்றம் மாற்றப்ப‌ட்ட‌து.',
'View has been created.' => 'தோற்ற‌ம் உருவாக்க‌ப்ப‌ட்ட‌து.', 'View has been created.' => 'தோற்ற‌ம் உருவாக்க‌ப்ப‌ட்ட‌து.',
@@ -229,7 +228,7 @@ Lang::$translations = array(
'Create sequence' => 'வ‌ரிசைமுறையை உருவாக்கு', 'Create sequence' => 'வ‌ரிசைமுறையை உருவாக்கு',
'User types' => 'ப‌ய‌னாள‌ர் வ‌கைக‌ள்', 'User types' => 'ப‌ய‌னாள‌ர் வ‌கைக‌ள்',
'Create type' => 'வ‌கையை உருவாக்கு', 'Create type' => 'வ‌கையை உருவாக்கு',
'Item%s has been inserted.' => 'உருப்ப‌டி (Item%s) சேர்க்க‌ப்ப‌ட்ட‌து.', 'Item%s has been inserted.' => 'உருப்ப‌டி (Item) சேர்க்க‌ப்ப‌ட்ட‌து.',
'Schema has been dropped.' => 'அமைப்புமுறை நீக்க‌ப்ப‌ட்ட‌து.', 'Schema has been dropped.' => 'அமைப்புமுறை நீக்க‌ப்ப‌ட்ட‌து.',
'Schema has been created.' => 'அமைப்புமுறை உருவாக்க‌ப்ப‌ட்ட‌து.', 'Schema has been created.' => 'அமைப்புமுறை உருவாக்க‌ப்ப‌ட்ட‌து.',
'Schema has been altered.' => 'அமைப்புமுறை மாற்ற‌ப்ப‌ட்ட‌து.', 'Schema has been altered.' => 'அமைப்புமுறை மாற்ற‌ப்ப‌ட்ட‌து.',
@@ -265,6 +264,42 @@ Lang::$translations = array(
'Permanent link' => 'நிரந்தர இணைப்பு', 'Permanent link' => 'நிரந்தர இணைப்பு',
'Edit all' => 'அனைத்தையும் தொகு', 'Edit all' => 'அனைத்தையும் தொகு',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
);
// run `php ../../lang.php ta` to update this file 'Drop %s?' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'overwrite' => null,
'DB' => null,
'Ctrl+click on a value to modify it.' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
);

View File

@@ -1,10 +1,8 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
'Login' => 'เข้าสู่ระบบ', 'Login' => 'เข้าสู่ระบบ',
'Logout successful.' => 'ออกจากระบบเรียบร้อยแล้ว.', 'Logout successful.' => 'ออกจากระบบเรียบร้อยแล้ว.',
'Invalid credentials.' => 'ข้อมูลไม่ถูกต้อง.', 'Invalid server or credentials.' => null,
'Server' => 'เซอเวอร์', 'Server' => 'เซอเวอร์',
'Username' => 'ชื่อผู้ใช้งาน', 'Username' => 'ชื่อผู้ใช้งาน',
'Password' => 'รหัสผ่าน', 'Password' => 'รหัสผ่าน',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'สร้างฐานข้อมูล', 'Create database' => 'สร้างฐานข้อมูล',
'SQL command' => 'คำสั่ง SQL', 'SQL command' => 'คำสั่ง SQL',
'Logout' => 'ออกจากระบบ', 'Logout' => 'ออกจากระบบ',
'database' => 'ฐานข้อมูล',
'Use' => 'ใช้งาน', 'Use' => 'ใช้งาน',
'No tables.' => 'ไม่พบตาราง.', 'No tables.' => 'ไม่พบตาราง.',
'select' => 'เลือก', 'select' => 'เลือก',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'ชนิดของดัชนี', 'Index Type' => 'ชนิดของดัชนี',
'length' => 'ความยาว', 'Column (length)' => 'คอลัมน์ (ความยาว)',
'View has been dropped.' => 'วิวถูกลบแล้ว.', 'View has been dropped.' => 'วิวถูกลบแล้ว.',
'View has been altered.' => 'วิวถูกเปลี่ยนแปลงแล้ว.', 'View has been altered.' => 'วิวถูกเปลี่ยนแปลงแล้ว.',
'View has been created.' => 'วิวถูกสร้างแล้ว.', 'View has been created.' => 'วิวถูกสร้างแล้ว.',
@@ -266,6 +265,41 @@ Lang::$translations = array(
'Permanent link' => 'ลิงค์ถาวร', 'Permanent link' => 'ลิงค์ถาวร',
'Edit all' => 'แก้ไขทั้งหมด', 'Edit all' => 'แก้ไขทั้งหมด',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
);
// run `php ../../lang.php th` to update this file 'Drop %s?' => null,
'Tables have been optimized.' => null,
'Materialized view' => null,
'Vacuum' => null,
'Selected' => null,
'overwrite' => null,
'DB' => null,
'File must be in UTF-8 encoding.' => null,
'Modify' => null,
'Load more data' => null,
'Loading' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You can upload a big SQL file via FTP and import it from server.' => null,
'Size' => null,
'Compute' => null,
'You are offline.' => null,
'You have no privileges to update this table.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
'yes' => null,
'no' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem', 'System' => 'Sistem',
'Server' => 'Sunucu', 'Server' => 'Sunucu',
@@ -13,7 +11,7 @@ Lang::$translations = array(
'Logged as: %s' => '%s olarak giriş yapıldı.', 'Logged as: %s' => '%s olarak giriş yapıldı.',
'Logout successful.' => 'Oturum başarıyla sonlandı.', 'Logout successful.' => 'Oturum başarıyla sonlandı.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Adminer kullandığınız için teşekkür ederiz <a href="https://www.adminer.org/en/donation/">bağış yapmayı düşünün</a>.', 'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Adminer kullandığınız için teşekkür ederiz <a href="https://www.adminer.org/en/donation/">bağış yapmayı düşünün</a>.',
'Invalid credentials.' => 'Geçersiz kimlik bilgileri.', 'Invalid server or credentials.' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array('Çok fazla oturum açma denemesi yapıldı.', '%d Dakika sonra tekrar deneyiniz.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Çok fazla oturum açma denemesi yapıldı.', '%d Dakika sonra tekrar deneyiniz.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Ana şifrenin süresi doldu. Kalıcı olması için <a href="https://www.adminer.org/en/extension/"%s>%s medodunu</a> kullanın.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Ana şifrenin süresi doldu. Kalıcı olması için <a href="https://www.adminer.org/en/extension/"%s>%s medodunu</a> kullanın.',
'Language' => 'Dil', 'Language' => 'Dil',
@@ -58,7 +56,7 @@ Lang::$translations = array(
'ATTACH queries are not supported.' => 'ATTACH sorguları desteklenmiyor.', 'ATTACH queries are not supported.' => 'ATTACH sorguları desteklenmiyor.',
'Execute' => 'Çalıştır', 'Execute' => 'Çalıştır',
'Stop on error' => 'Hata oluşursa dur', 'Stop on error' => 'Hata oluşursa dur',
'Show only errors' => 'Sadece hataları göster', 'Show only errors' => 'Sadece hataları göster.',
// sprintf() format for time of the command // sprintf() format for time of the command
'%.3f s' => '%.3f s', '%.3f s' => '%.3f s',
'History' => 'Geçmiş', 'History' => 'Geçmiş',
@@ -86,6 +84,7 @@ Lang::$translations = array(
'Data' => 'Veri', 'Data' => 'Veri',
'Database' => 'Veri Tabanı', 'Database' => 'Veri Tabanı',
'database' => 'veri tabanı',
'DB' => 'DB', 'DB' => 'DB',
'Use' => 'Kullan', 'Use' => 'Kullan',
'Select database' => 'Veri tabanı seç', 'Select database' => 'Veri tabanı seç',
@@ -202,7 +201,7 @@ Lang::$translations = array(
'Alter indexes' => 'İndeksleri değiştir', 'Alter indexes' => 'İndeksleri değiştir',
'Add next' => 'Bundan sonra ekle', 'Add next' => 'Bundan sonra ekle',
'Index Type' => 'İndex Türü', 'Index Type' => 'İndex Türü',
'length' => 'uzunluğu', 'Column (length)' => 'Kolon (uzunluğu)',
'Foreign keys' => 'Dış anahtarlar', 'Foreign keys' => 'Dış anahtarlar',
'Foreign key' => 'Dış anahtar', 'Foreign key' => 'Dış anahtar',
@@ -225,7 +224,7 @@ Lang::$translations = array(
'Trigger has been dropped.' => 'Tetik silindi.', 'Trigger has been dropped.' => 'Tetik silindi.',
'Trigger has been altered.' => 'Tetik değiştirildi.', 'Trigger has been altered.' => 'Tetik değiştirildi.',
'Trigger has been created.' => 'Tetik oluşturuldu.', 'Trigger has been created.' => 'Tetik oluşturuldu.',
'Alter trigger' => 'Tetiği değiştir', 'Alter trigger' => 'Tetiği değiştir.',
'Create trigger' => 'Tetik oluştur', 'Create trigger' => 'Tetik oluştur',
'Time' => 'Zaman', 'Time' => 'Zaman',
'Event' => 'Olay', 'Event' => 'Olay',
@@ -307,7 +306,7 @@ Lang::$translations = array(
// date format in Editor: $1 yyyy, $2 yy, $3 mm, $4 m, $5 dd, $6 d // date format in Editor: $1 yyyy, $2 yy, $3 mm, $4 m, $5 dd, $6 d
'$1-$3-$5' => '$6.$4.$1', '$1-$3-$5' => '$6.$4.$1',
// hint for date format - use language equivalents for day, month and year shortcuts // hint for date format - use language equivalents for day, month and year shortcuts
'[yyyy]-mm-dd' => 'g.a.[yyyy]', '[yyyy]-mm-dd' => '[yyyy]-aa-gg',
// hint for time format - use language equivalents for hour, minute and second shortcuts // hint for time format - use language equivalents for hour, minute and second shortcuts
'HH:MM:SS' => 'SS:DD:ss', 'HH:MM:SS' => 'SS:DD:ss',
'now' => 'şimdi', 'now' => 'şimdi',
@@ -341,6 +340,11 @@ Lang::$translations = array(
'Type has been dropped.' => 'Tür silindi.', 'Type has been dropped.' => 'Tür silindi.',
'Type has been created.' => 'Tür oluşturuldu.', 'Type has been created.' => 'Tür oluşturuldu.',
'Alter type' => 'Türü değiştir', 'Alter type' => 'Türü değiştir',
);
// run `php ../../lang.php tr` to update this file 'overwrite' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'There is a space in the input password which might be the cause.' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Система Бази Даних', 'System' => 'Система Бази Даних',
'Server' => 'Сервер', 'Server' => 'Сервер',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Вийти', 'Logout' => 'Вийти',
'Logged as: %s' => 'Ви увійшли як: %s', 'Logged as: %s' => 'Ви увійшли як: %s',
'Logout successful.' => 'Ви вдало вийшли з системи.', 'Logout successful.' => 'Ви вдало вийшли з системи.',
'Invalid credentials.' => 'Неправильні дані входу.', 'Invalid server or credentials.' => null,
'Language' => 'Мова', 'Language' => 'Мова',
'Invalid CSRF token. Send the form again.' => 'Недійсний CSRF токен. Надішліть форму ще раз.', 'Invalid CSRF token. Send the form again.' => 'Недійсний CSRF токен. Надішліть форму ще раз.',
'No extension' => 'Нема розширень', 'No extension' => 'Нема розширень',
@@ -75,6 +73,7 @@ Lang::$translations = array(
'Data' => 'Дані', 'Data' => 'Дані',
'Database' => 'База даних', 'Database' => 'База даних',
'database' => 'база даних',
'Use' => 'Обрати', 'Use' => 'Обрати',
'Select database' => 'Обрати базу даних', 'Select database' => 'Обрати базу даних',
'Invalid database.' => 'Погана база даних.', 'Invalid database.' => 'Погана база даних.',
@@ -184,7 +183,7 @@ Lang::$translations = array(
'Alter indexes' => 'Змінити індексування', 'Alter indexes' => 'Змінити індексування',
'Add next' => 'Додати ще', 'Add next' => 'Додати ще',
'Index Type' => 'Тип індексу', 'Index Type' => 'Тип індексу',
'length' => 'довжина', 'Column (length)' => 'Стовпець (довжина)',
'Foreign keys' => 'Зовнішні ключі', 'Foreign keys' => 'Зовнішні ключі',
'Foreign key' => 'Зовнішній ключ', 'Foreign key' => 'Зовнішній ключ',
@@ -344,18 +343,8 @@ Lang::$translations = array(
'Saving' => 'Збереження', 'Saving' => 'Збереження',
'Unknown error.' => 'Невідома помилка.', 'Unknown error.' => 'Невідома помилка.',
'Database does not support password.' => 'База даних не підтримує пароль.', 'Database does not support password.' => 'База даних не підтримує пароль.',
'Disable %s or enable %s or %s extensions.' => 'Вимкніть %s або увімкніть розширення %s або %s.',
'Check has been dropped.' => 'Перевірку видалено.',
'Check has been altered.' => 'Перевірка змінена.',
'Check has been created.' => 'Перевірку створено.',
'Alter check' => 'Змінити перевірку',
'Create check' => 'Створити перевірку',
'Vacuum' => 'Вакуум',
'%d / ' => '%d / ',
'Checks' => 'Перевірки',
'Loaded plugins' => 'Завантажені плагіни',
'%s must <a%s>return an array</a>.' => '%s має <a%s>повернути масив</a>.',
'<a%s>Configure</a> %s in %s.' => '<a%s>Налаштувати</a> %s у %s.',
);
// run `php ../../lang.php uk` to update this file 'Vacuum' => null,
'%d / ' => array(),
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,365 +0,0 @@
<?php
namespace Adminer;
Lang::$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

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Hệ thống', 'System' => 'Hệ thống',
'Server' => 'Máy chủ', 'Server' => 'Máy chủ',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Thoát', 'Logout' => 'Thoát',
'Logged as: %s' => 'Vào dưới tên: %s', 'Logged as: %s' => 'Vào dưới tên: %s',
'Logout successful.' => 'Đã thoát xong.', 'Logout successful.' => 'Đã thoát xong.',
'Invalid credentials.' => 'Tài khoản sai.', 'Invalid server or credentials.' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => 'Bạn gõ sai tài khoản quá nhiều lần, hãy thử lại sau %d phút nữa.', 'Too many unsuccessful logins, try again in %d minute(s).' => 'Bạn gõ sai tài khoản quá nhiều lần, hãy thử lại sau %d phút nữa.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Mật khẩu đã hết hạn. <a href="https://www.adminer.org/en/extension/"%s>Thử cách làm</a> để giữ cố định.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Mật khẩu đã hết hạn. <a href="https://www.adminer.org/en/extension/"%s>Thử cách làm</a> để giữ cố định.',
'Language' => 'Ngôn ngữ', 'Language' => 'Ngôn ngữ',
@@ -61,7 +59,7 @@ Lang::$translations = array(
'File upload' => 'Tải tệp lên', 'File upload' => 'Tải tệp lên',
'From server' => 'Dùng tệp trên máy chủ', 'From server' => 'Dùng tệp trên máy chủ',
'Webserver file %s' => 'Tệp trên máy chủ %s', 'Webserver file %s' => 'Tệp trên máy chủ',
'Run file' => 'Chạy tệp', 'Run file' => 'Chạy tệp',
'File does not exist.' => 'Tệp không tồn tại.', 'File does not exist.' => 'Tệp không tồn tại.',
'File uploads are disabled.' => 'Chức năng tải tệp lên đã bị cấm.', 'File uploads are disabled.' => 'Chức năng tải tệp lên đã bị cấm.',
@@ -78,6 +76,7 @@ Lang::$translations = array(
'Data' => 'Dữ liệu', 'Data' => 'Dữ liệu',
'Database' => 'Cơ sở dữ liệu', 'Database' => 'Cơ sở dữ liệu',
'database' => 'cơ sở dữ liệu',
'Use' => 'Sử dụng', 'Use' => 'Sử dụng',
'Select database' => 'Chọn CSDL', 'Select database' => 'Chọn CSDL',
'Invalid database.' => 'CSDL sai.', 'Invalid database.' => 'CSDL sai.',
@@ -189,7 +188,7 @@ Lang::$translations = array(
'Alter indexes' => 'Sửa chỉ mục', 'Alter indexes' => 'Sửa chỉ mục',
'Add next' => 'Thêm tiếp', 'Add next' => 'Thêm tiếp',
'Index Type' => 'Loại chỉ mục', 'Index Type' => 'Loại chỉ mục',
'length' => 'độ dài', 'Column (length)' => 'Cột (độ dài)',
'Foreign keys' => 'Các khoá ngoại', 'Foreign keys' => 'Các khoá ngoại',
'Foreign key' => 'Khoá ngoại', 'Foreign key' => 'Khoá ngoại',
@@ -326,6 +325,25 @@ Lang::$translations = array(
'Type has been dropped.' => 'Đã xoá kiểu.', 'Type has been dropped.' => 'Đã xoá kiểu.',
'Type has been created.' => 'Đã tạo kiểu.', 'Type has been created.' => 'Đã tạo kiểu.',
'Alter type' => 'Sửa kiểu dữ liệu', 'Alter type' => 'Sửa kiểu dữ liệu',
);
// run `php ../../lang.php vi` to update this file 'Drop %s?' => null,
'Materialized view' => null,
'overwrite' => null,
'DB' => null,
'ATTACH queries are not supported.' => null,
'Warnings' => null,
'%d / ' => array(),
'Limit rows' => null,
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
'Default value' => null,
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'The action will be performed after successful login with the same credentials.' => null,
'Connecting to privileged ports is not allowed.' => null,
'There is a space in the input password which might be the cause.' => null,
'If you did not send this request from Adminer then close this page.' => null,
'You are offline.' => null,
'Saving' => null,
'Unknown error.' => null,
'Database does not support password.' => null,
'Disable %s or enable %s or %s extensions.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php <?php
namespace Adminer; $translations = array(
Lang::$translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Xx', 'System' => 'Xx',
'Server' => 'Xx', 'Server' => 'Xx',
@@ -13,20 +11,16 @@ Lang::$translations = array(
'Logged as: %s' => 'Xx: %s', 'Logged as: %s' => 'Xx: %s',
'Logout successful.' => 'Xx.', '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>.', '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', 'Invalid server or credentials.' => '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.', '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>.', 'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Xx, <a href="https://www.adminer.org/en/password/"%s>xx</a>.',
'Database does not support password.' => 'Xx.', 'Database does not support password.' => 'Xx.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Xx %d.', 'Xx %d.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Xx %d.', 'Xx %d.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Xx. <a href="https://www.adminer.org/en/extension/"%s>Xx</a> %s xx.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => '<a href="https://www.adminer.org/en/extension/"%s>Xx</a> %s xx.',
'Language' => 'Xx', 'Language' => 'Xx',
'Invalid CSRF token. Send the form again.' => 'Xx.', 'Invalid CSRF token. Send the form again.' => 'Xx.',
'If you did not send this request from Adminer then close this page.' => 'Xx.', 'If you did not send this request from Adminer then close this page.' => 'Xx.',
'No extension' => 'Xx', 'No extension' => 'Xx',
// %s contains the list of the extensions, e.g. 'mysqli, PDO_MySQL'
'None of the supported PHP extensions (%s) are available.' => 'Xx (%s).', 'None of the supported PHP extensions (%s) are available.' => 'Xx (%s).',
'Connecting to privileged ports is not allowed.' => 'Xx.', 'Connecting to privileged ports is not allowed.' => 'Xx.',
'Disable %s or enable %s or %s extensions.' => 'Xx %s xx %s xx %s xx.', 'Disable %s or enable %s or %s extensions.' => 'Xx %s xx %s xx %s xx.',
@@ -37,7 +31,7 @@ Lang::$translations = array(
'Refresh' => 'Xx', 'Refresh' => 'Xx',
// text direction - 'ltr' or 'rtl' // text direction - 'ltr' or 'rtl'
'ltr' => 'ltr', 'ltr' => 'xx',
'Privileges' => 'Xx', 'Privileges' => 'Xx',
'Create user' => 'Xx', 'Create user' => 'Xx',
@@ -95,6 +89,7 @@ Lang::$translations = array(
'Data' => 'Xx', 'Data' => 'Xx',
'Database' => 'Xx', 'Database' => 'Xx',
'database' => 'xx',
'DB' => 'XX', 'DB' => 'XX',
'Use' => 'Xx', 'Use' => 'Xx',
'Select database' => 'Xx', 'Select database' => 'Xx',
@@ -212,7 +207,7 @@ Lang::$translations = array(
'Alter indexes' => 'Xx', 'Alter indexes' => 'Xx',
'Add next' => 'Xx', 'Add next' => 'Xx',
'Index Type' => 'Xx', 'Index Type' => 'Xx',
'length' => 'xx', 'Column (length)' => 'Xx',
'Foreign keys' => 'Xx', 'Foreign keys' => 'Xx',
'Foreign key' => 'Xx', 'Foreign key' => 'Xx',
@@ -258,7 +253,6 @@ Lang::$translations = array(
'Full table scan' => 'Xx', 'Full table scan' => 'Xx',
'Unable to select the table' => 'Xx', 'Unable to select the table' => 'Xx',
'No rows.' => 'Xx.', 'No rows.' => 'Xx.',
// used in SQL query limit and it is followed by another number, e.g. '10 / 50 rows' meaning 10 of 50 rows
'%d / ' => '%d / ', '%d / ' => '%d / ',
'%d row(s)' => array('%d xx', '%d xx'), '%d row(s)' => array('%d xx', '%d xx'),
'Page' => 'Xx', 'Page' => 'Xx',
@@ -277,7 +271,7 @@ Lang::$translations = array(
'Ctrl+click on a value to modify it.' => 'Xx.', 'Ctrl+click on a value to modify it.' => 'Xx.',
'Use edit link to modify this value.' => 'Xx.', 'Use edit link to modify this value.' => 'Xx.',
// %s can contain auto-increment value, e.g. ' 123' // %s can contain auto-increment value
'Item%s has been inserted.' => 'Xx%s.', 'Item%s has been inserted.' => 'Xx%s.',
'Item has been deleted.' => 'Xx.', 'Item has been deleted.' => 'Xx.',
'Item has been updated.' => 'Xx.', 'Item has been updated.' => 'Xx.',
@@ -352,14 +346,4 @@ Lang::$translations = array(
'Type has been dropped.' => 'Xx.', 'Type has been dropped.' => 'Xx.',
'Type has been created.' => 'Xx.', 'Type has been created.' => 'Xx.',
'Alter type' => 'Xx', 'Alter type' => 'Xx',
// Table check constraints
'Checks' => 'Xx',
'Create check' => 'Xx',
'Alter check' => 'Xx',
'Check has been created.' => 'Xx.',
'Check has been altered.' => 'Xx.',
'Check has been dropped.' => 'Xx.',
); );
// run `php ../../lang.php xx` to update this file

View File

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

View File

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

46
adminer/plugin.php Normal file
View File

@@ -0,0 +1,46 @@
<?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 AdminerEditCalendar(script_src("../externals/jquery-ui/jquery-1.4.4.js") . script_src("../externals/jquery-ui/ui/jquery.ui.core.js") . script_src("../externals/jquery-ui/ui/jquery.ui.widget.js") . script_src("../externals/jquery-ui/ui/jquery.ui.datepicker.js") . script_src("../externals/jquery-ui/ui/jquery.ui.mouse.js") . script_src("../externals/jquery-ui/ui/jquery.ui.slider.js") . script_src("../externals/jquery-timepicker/jquery-ui-timepicker-addon.js") . "<link rel='stylesheet' href='../externals/jquery-ui/themes/base/jquery.ui.all.css'>\n<style>\n.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }\n.ui-timepicker-div dl { text-align: left; }\n.ui-timepicker-div dl dt { height: 25px; }\n.ui-timepicker-div dl dd { margin: -25px 0 10px 65px; }\n.ui-timepicker-div td { font-size: 90%; }\n</style>\n", "../externals/jquery-ui/ui/i18n/jquery.ui.datepicker-%s.js"),
//~ new AdminerTinymce("../externals/tinymce/jscripts/tiny_mce/tiny_mce_dev.js"),
//~ new AdminerWymeditor(array("../externals/wymeditor/src/jquery/jquery.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.explorer.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.mozilla.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.opera.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.safari.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";

View File

@@ -1,30 +1,28 @@
<?php <?php
namespace Adminer;
page_header(lang('Privileges')); page_header(lang('Privileges'));
echo '<p class="links"><a href="' . h(ME) . 'user=">' . lang('Create user') . "</a>"; echo '<p class="links"><a href="' . h(ME) . 'user=">' . lang('Create user') . "</a>";
$result = connection()->query("SELECT User, Host FROM mysql." . (DB == "" ? "user" : "db WHERE " . q(DB) . " LIKE Db") . " ORDER BY Host, User"); $result = $connection->query("SELECT User, Host FROM mysql." . (DB == "" ? "user" : "db WHERE " . q(DB) . " LIKE Db") . " ORDER BY Host, User");
$grant = $result; $grant = $result;
if (!$result) { if (!$result) {
// list logged user, information_schema.USER_PRIVILEGES lists just the current user too // list logged user, information_schema.USER_PRIVILEGES lists just the current user too
$result = connection()->query("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', 1) AS User, SUBSTRING_INDEX(CURRENT_USER, '@', -1) AS Host"); $result = $connection->query("SELECT SUBSTRING_INDEX(CURRENT_USER, '@', 1) AS User, SUBSTRING_INDEX(CURRENT_USER, '@', -1) AS Host");
} }
echo "<form action=''><p>\n"; echo "<form action=''><p>\n";
hidden_fields_get(); hidden_fields_get();
echo input_hidden("db", DB); echo "<input type='hidden' name='db' value='" . h(DB) . "'>\n";
echo ($grant ? "" : input_hidden("grant")); echo ($grant ? "" : "<input type='hidden' name='grant' value=''>\n");
echo "<table class='odds'>\n"; echo "<table cellspacing='0'>\n";
echo "<thead><tr><th>" . lang('Username') . "<th>" . lang('Server') . "<th></thead>\n"; echo "<thead><tr><th>" . lang('Username') . "<th>" . lang('Server') . "<th></thead>\n";
while ($row = $result->fetch_assoc()) { while ($row = $result->fetch_assoc()) {
echo '<tr><td>' . h($row["User"]) . "<td>" . h($row["Host"]) . '<td><a href="' . h(ME . 'user=' . urlencode($row["User"]) . '&host=' . urlencode($row["Host"])) . '">' . lang('Edit') . "</a>\n"; echo '<tr' . odd() . '><td>' . h($row["User"]) . "<td>" . h($row["Host"]) . '<td><a href="' . h(ME . 'user=' . urlencode($row["User"]) . '&host=' . urlencode($row["Host"])) . '">' . lang('Edit') . "</a>\n";
} }
if (!$grant || DB != "") { if (!$grant || DB != "") {
echo "<tr><td><input name='user' autocapitalize='off'><td><input name='host' value='localhost' autocapitalize='off'><td><input type='submit' value='" . lang('Edit') . "'>\n"; echo "<tr" . odd() . "><td><input name='user' autocapitalize='off'><td><input name='host' value='localhost' autocapitalize='off'><td><input type='submit' value='" . lang('Edit') . "'>\n";
} }
echo "</table>\n"; echo "</table>\n";

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