1
0
mirror of https://github.com/vrana/adminer.git synced 2025-08-30 17:50:00 +02:00

Compare commits

..

84 Commits

Author SHA1 Message Date
Peter Knut
3f0bc24e01 Release 4.9.2 2024-09-18 09:50:35 +02:00
Peter Knut
4863f48d33 Basic JS code cleanup 2024-09-18 09:39:17 +02:00
Peter Knut
9ea8f44919 Fix undefined property in error message if driver does not support error number 2024-09-18 00:46:34 +02:00
khoazero123
fa791b5461 PostgreSQL: Fix exporting CREATE TABLE with sequence default value 2024-09-18 00:31:15 +02:00
Roy-Orbison
203162b203 Function to retrieve driver name
Plugins cannot access $drivers global after compilation.
2024-09-18 00:27:02 +02:00
Peter Knut
e4e76b6384 PostgreSQL: Allow to set connection's sslmode with AdminerLoginSsl plugin
Thanks to wodka (https://github.com/vrana/adminer/pull/427/files)
2024-09-18 00:27:02 +02:00
Peter Knut
353cd452a3 PostgreSQL: Fix exporting CREATE TABLE query with GENERATED default values
Thanks to GottfriedCP (https://github.com/adminerevo/adminerevo/issues/157)
2024-09-18 00:27:02 +02:00
Peter Knut
5bc4ac6c18 Merge branch 'editor-search-fix' 2024-09-17 15:46:51 +02:00
Peter Knut
aec8275502 Editor: Fix searching in tables
Thanks to ytetsuro (https://github.com/vrana/adminer/pull/473)
2024-09-17 15:46:36 +02:00
Peter Knut
7d5077e687 Cleanup the code for searching 2024-09-17 15:36:02 +02:00
Peter Knut
91d0d8538f MySQL: Do not show 'empty' enum value in strict mode 2024-09-10 23:47:06 +02:00
Peter Knut
2439369143 PostreSQL: Fix search condition for network address types, add macaddr8 type
This fixes issue https://github.com/adminerevo/adminerevo/issues/115
2024-09-10 10:27:59 +02:00
Peter Knut
d5bce9b3e9 PostreSQL: Fix search fields configuration
Regression from 4.9.
2024-09-10 08:28:18 +02:00
Peter Knut
b42762e4dc Remove hardcoded textarea height 2024-09-09 23:54:51 +02:00
Peter Knut
695a720403 Bump version to 4.9.2-dev 2024-09-09 23:53:50 +02:00
Peter Knut
e6fdf2b400 Release 4.9.1 2024-09-09 10:30:14 +02:00
Peter Knut
b542b6613c PostgreSQL: Fix undefined properties on PHP 8
Thanks to FrancoisCapon (https://github.com/vrana/adminer/pull/429)
2024-09-08 23:22:44 +02:00
Peter Knut
374b8ed6a6 PostgreSQL: Fix documentation link for SERIAL type
Thanks to leggiero (https://github.com/vrana/adminer/pull/432)
2024-09-08 23:01:47 +02:00
Michal Paulovic
58cca3f951 MySQL: Add unix_timestamp to functions 2024-09-08 23:01:46 +02:00
caltong
5eecb8e6a3 PostgreSQL: Make data length calculation more accurate 2024-09-08 22:28:06 +02:00
Thomas Daniels
0d0936550c PostgreSQL: Show only accessible databases 2024-09-08 01:02:49 +02:00
Peter Knut
c4ed9500a1 Add support for translations in plugins 2024-09-07 22:54:04 +02:00
Peter Knut
0863766970 Replace deprecated <acronym> with <abbr> 2024-09-07 22:53:18 +02:00
Peter Knut
146a24efad AdminerLoginOtp: Autocomplete hints for OTP input field, code refactoring
Tanks to SGCBB (https://github.com/vrana/adminer/pull/488)
2024-09-07 22:53:08 +02:00
Sneda8
00b9fbda08 PHP 8.3 error suppression
PHP 8.3 has shortened the array access on null error message to "Trying to access array offset on null". This commit changes the regular expression used to circumvent errors.
2024-09-06 00:33:53 +02:00
Peter Knut
8ea329538f Improved displaying of long table names in menu 2024-09-03 00:34:00 +02:00
Peter Knut
a3428cc7ff Fix compiling jush external files 2024-09-02 23:18:44 +02:00
Peter Knut
2a01969c96 Add .editorconfig file
Thanks to cweiske (https://github.com/adminerevo/adminerevo/pull/163).
2024-08-26 00:56:10 +02:00
Peter Knut
9b8d14c3ee Refactor and fix the plugin AdminerEditForeign
Thanks to Amunak (https://github.com/adminerevo/adminerevo/pull/86).
2024-08-25 23:48:02 +02:00
Peter Knut
2ce88d9bdc Fix field selection in Elasticsearch
Thanks to cweiske: https://github.com/adminerevo/adminerevo/pull/159
2024-08-25 22:14:50 +02:00
Peter Knut
593c8e5bcc Bump version to 4.9.1-dev 2024-08-21 00:07:57 +02:00
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
282 changed files with 14953 additions and 16177 deletions

View File

@@ -7,7 +7,7 @@ end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.{php,css,js,xml}]
[*.{php,css,js}]
indent_style = tab
[*.json]

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
custom: ["https://www.paypal.com/donate/?hosted_button_id=6PK5VNUCFT3FG"]
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-dark.css
/editor/adminer.css
/editor/adminer-dark.css
/adminer*.php
/editor*.php
/tests/pdo-*.html
/tests/screenshots/
/tests/cropped/
/vendor/
adminer-plugins/
adminer-plugins.php
/composer.lock
/temp

12
.gitmodules vendored
View File

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

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

View File

@@ -1,9 +1,7 @@
<?php
namespace Adminer;
$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"]);
if ($_POST["drop"]) {
$_GET["db"] = ""; // to save in global history
@@ -46,7 +44,7 @@ if ($_POST) {
$name = $row["name"];
} elseif (DB != "") {
$row["collation"] = db_collation(DB, $collations);
} elseif (JUSH == "sql") {
} elseif ($jush == "sql") {
// propose database name with limited privileges
foreach (get_vals("SHOW GRANTS") as $grant) {
if (preg_match('~ ON (`(([^\\\\`]|``|\\\\.)*)%`\.\*)?~', $grant, $match) && $match[1]) {
@@ -60,22 +58,23 @@ if ($_POST) {
<form action="" method="post">
<p>
<?php
echo ($_POST["add"] || strpos($name, "\n")
? '<textarea autofocus name="name" rows="10" cols="40">' . h($name) . '</textarea><br>'
: '<input name="name" autofocus value="' . h($name) . '" data-maxlength="64" autocapitalize="off">'
echo ($_POST["add_x"] || strpos($name, "\n")
? '<textarea id="name" name="name" rows="10" cols="40">' . h($name) . '</textarea><br>'
: '<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(
'sql' => "charset-charsets.html",
'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'); ?>">
<?php
if (DB != "") {
echo "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm(lang('Drop %s?', DB)) . "\n";
} elseif (!$_POST["add"] && $_GET["db"] == "") {
echo icon("plus", "add[0]", "+", lang('Add next')) . "\n";
} elseif (!$_POST["add_x"] && $_GET["db"] == "") {
echo "<input type='image' class='icon' name='add' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>\n";
}
echo input_token();
?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form>

View File

@@ -1,12 +1,10 @@
<?php
namespace Adminer;
$tables_views = array_merge((array) $_POST["tables"], (array) $_POST["views"]);
if ($tables_views && !$error && !$_POST["search"]) {
$result = true;
$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
}
@@ -29,21 +27,15 @@ if ($tables_views && !$error && !$_POST["search"]) {
$result = drop_tables($_POST["tables"]);
}
$message = lang('Tables have been dropped.');
} elseif (JUSH == "sqlite" && $_POST["check"]) {
foreach ((array) $_POST["tables"] as $table) {
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"
} elseif ($jush != "sql") {
$result = ($jush == "sqlite"
? queries("VACUUM")
: apply_queries("VACUUM" . ($_POST["optimize"] ? "" : " ANALYZE"), $_POST["tables"])
);
$message = lang('Tables have been optimized.');
} elseif (!$_POST["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()) {
$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);
if (adminer()->homepage()) {
if ($adminer->homepage()) {
if ($_GET["ns"] !== "") {
echo "<h3 id='tables-views'>" . lang('Tables and views') . "</h3>\n";
$tables_list = tables_list();
@@ -69,12 +61,12 @@ if (adminer()->homepage()) {
echo " <input type='submit' name='search' value='" . lang('Search') . "'>\n";
echo "</div></fieldset>\n";
if ($_POST["search"] && $_POST["query"] != "") {
$_GET["where"][0]["op"] = driver()->convertOperator("LIKE %%");
$_GET["where"][0]["op"] = $driver->convertOperator("LIKE %%");
search_tables();
}
}
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 '<thead><tr class="wrap">';
echo '<td><input id="check-all" type="checkbox" class="jsonly">' . script("qs('#check-all').onclick = partial(formCheck, /^(tables|views)\[/);", "");
@@ -93,23 +85,21 @@ if (adminer()->homepage()) {
foreach ($tables_list as $name => $type) {
$view = ($type !== null && !preg_match('~table|sequence~i', $type));
$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));
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 align="right"><a href="' . h(ME) . "select=" . urlencode($name) . '" title="' . lang('Select data') . '">?</a>';
} else {
foreach (
array(
"Engine" => array(),
"Collation" => array(),
"Data_length" => array("create", lang('Alter table')),
"Index_length" => array("indexes", lang('Alter indexes')),
"Data_free" => array("edit", lang('New item')),
"Auto_increment" => array("auto_increment=1&create", lang('Alter table')),
"Rows" => array("select", lang('Select data')),
) as $key => $link
) {
foreach (array(
"Engine" => array(),
"Collation" => array(),
"Data_length" => array("create", lang('Alter table')),
"Index_length" => array("indexes", lang('Alter indexes')),
"Data_free" => array("edit", lang('New item')),
"Auto_increment" => array("auto_increment=1&create", lang('Alter table')),
"Rows" => array("select", lang('Select data')),
) as $key => $link) {
$id = " id='$key-" . h($name) . "'";
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>"
@@ -119,45 +109,42 @@ if (adminer()->homepage()) {
$tables++;
}
echo (support("comment") ? "<td id='Comment-" . h($name) . "'>" : "");
echo "\n";
}
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()));
foreach (array("Data_length", "Index_length", "Data_free") as $key) {
echo "<td align='right' id='sum-$key'>";
}
echo "\n";
echo "</table>\n";
echo "</div>\n";
if (!information_schema(DB)) {
echo "<div class='footer'><div>\n";
$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>"
. (JUSH == "sqlite" ? $vacuum . "<input type='submit' name='check' value='" . lang('Check') . "'> " . on_help("'PRAGMA integrity_check'")
: (JUSH == "pgsql" ? $vacuum . $optimize
: (JUSH == "sql" ? "<input type='submit' value='" . lang('Analyze') . "'> " . on_help("'ANALYZE TABLE'")
. $optimize
. ($jush == "sqlite" ? $vacuum
: ($jush == "pgsql" ? $vacuum . $optimize
: ($jush == "sql" ? "<input type='submit' value='" . lang('Analyze') . "'> " . on_help("'ANALYZE TABLE'") . $optimize
. "<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='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";
$databases = (support("scheme") ? adminer()->schemas() : adminer()->databases());
if (count($databases) != 1 && JUSH != "sqlite") {
$databases = (support("scheme") ? $adminer->schemas() : $adminer->databases());
if (count($databases) != 1 && $jush != "sqlite") {
$db = (isset($_POST["target"]) ? $_POST["target"] : (support("scheme") ? $_GET["ns"] : DB));
echo "<p><label>" . 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 "</label> <input type='submit' name='move' value='" . lang('Move') . "'>";
echo " <input type='submit' name='move' value='" . lang('Move') . "'>";
echo (support("copy") ? " <input type='submit' name='copy' value='" . lang('Copy') . "'> " . checkbox("overwrite", 1, $_POST["overwrite"], lang('overwrite')) : "");
echo "\n";
}
echo "<input type='hidden' name='all' value=''>"; // used by trCheck()
echo script("qsl('input').onclick = function () { selectCount('selected', formChecked(this, /^(tables|views)\[/));" . (support("table") ? " selectCount('selected2', formChecked(this, /^tables\[/) || $tables);" : "") . " }");
echo input_token();
echo "<input type='hidden' name='token' value='$token'>\n";
echo "</div></fieldset>\n";
echo "</div></div>\n";
}
@@ -165,18 +152,19 @@ if (adminer()->homepage()) {
echo script("tableCheck();");
}
echo "<p class='links'><a href='" . h(ME) . "create='>" . lang('Create table') . "</a>\n";
echo (support("view") ? "<a href='" . h(ME) . "view='>" . lang('Create view') . "</a>\n" : "");
echo '<p class="links"><a href="' . h(ME) . 'create=">' . lang('Create table') . "</a>\n";
echo (support("view") ? '<a href="' . h(ME) . 'view=">' . lang('Create view') . "</a>\n" : "");
if (support("routine")) {
echo "<h3 id='routines'>" . lang('Routines') . "</h3>\n";
$routines = 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";
odd('');
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
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 '<td>' . h($row["ROUTINE_TYPE"]);
echo '<td>' . h($row["DTD_IDENTIFIER"]);
@@ -194,10 +182,11 @@ if (adminer()->homepage()) {
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");
if ($sequences) {
echo "<table class='odds'>\n";
echo "<table cellspacing='0'>\n";
echo "<thead><tr><th>" . lang('Name') . "</thead>\n";
odd('');
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";
}
@@ -208,10 +197,11 @@ if (adminer()->homepage()) {
echo "<h3 id='user-types'>" . lang('User types') . "</h3>\n";
$user_types = types();
if ($user_types) {
echo "<table class='odds'>\n";
echo "<table cellspacing='0'>\n";
echo "<thead><tr><th>" . lang('Name') . "</thead>\n";
odd('');
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";
}
@@ -222,7 +212,7 @@ if (adminer()->homepage()) {
echo "<h3 id='events'>" . lang('Events') . "</h3>\n";
$rows = get_rows("SHOW EVENTS");
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";
foreach ($rows as $row) {
echo "<tr>";
@@ -232,7 +222,7 @@ if (adminer()->homepage()) {
echo '<td><a href="' . h(ME) . 'event=' . urlencode($row["Name"]) . '">' . lang('Alter') . '</a>';
}
echo "</table>\n";
$event_scheduler = get_val("SELECT @@event_scheduler");
$event_scheduler = $connection->result("SELECT @@event_scheduler");
if ($event_scheduler && $event_scheduler != "ON") {
echo "<p class='error'><code class='jush-sqlset'>event_scheduler</code>: " . h($event_scheduler) . "\n";
}

View File

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

View File

@@ -1,12 +1,10 @@
<?php
namespace Adminer;
$TABLE = $_GET["download"];
$fields = fields($TABLE);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=" . friendly_url("$TABLE-" . implode("_", $_GET["where"])) . "." . friendly_url($_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());
echo driver()->value($row[0], $fields[$_GET["field"]]);
echo $driver->value($row[0], $fields[$_GET["field"]]);
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
*/
namespace Adminer;
add_driver("mssql", "MS SQL");
$drivers["mssql"] = "MS SQL (beta)";
if (isset($_GET["mssql"])) {
define('Adminer\DRIVER', "mssql");
if (extension_loaded("sqlsrv") && $_GET["ext"] != "pdo") {
class Db extends SqlDb {
public $extension = "sqlsrv";
private $link, $result;
define("DRIVER", "mssql");
if (extension_loaded("sqlsrv")) {
class Min_DB {
var $extension = "sqlsrv", $_link, $_result, $server_info, $affected_rows, $errno, $error;
private function get_error() {
function _get_error() {
$this->error = "";
foreach (sqlsrv_errors() as $error) {
$this->errno = $error["code"];
@@ -25,53 +22,46 @@ if (isset($_GET["mssql"])) {
$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");
$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 != "") {
$connection_info["Database"] = $db;
}
$this->link = @sqlsrv_connect(preg_replace('~:~', ',', $server), $connection_info);
if ($this->link) {
$info = sqlsrv_server_info($this->link);
$this->_link = @sqlsrv_connect(preg_replace('~:~', ',', $server), $connection_info);
if ($this->_link) {
$info = sqlsrv_server_info($this->_link);
$this->server_info = $info['SQLServerVersion'];
} else {
$this->get_error();
$this->_get_error();
}
return ($this->link ? '' : $this->error);
return (bool) $this->_link;
}
function quote(string $string): string {
$unicode = strlen($string) != strlen(utf8_decode($string));
return ($unicode ? "N" : "") . "'" . str_replace("'", "''", $string) . "'";
function quote($string) {
return "'" . str_replace("'", "''", $string) . "'";
}
function select_db(string $database) {
return $this->query(use_sql($database));
function select_db($database) {
return $this->query("USE " . idf_escape($database));
}
function query(string $query, bool $unbuffered = false) {
$result = sqlsrv_query($this->link, $query); //! , array(), ($unbuffered ? array() : array("Scrollable" => "keyset"))
function query($query, $unbuffered = false) {
$result = sqlsrv_query($this->_link, $query); //! , array(), ($unbuffered ? array() : array("Scrollable" => "keyset"))
$this->error = "";
if (!$result) {
$this->get_error();
$this->_get_error();
return false;
}
return $this->store_result($result);
}
function multi_query(string $query) {
$this->result = sqlsrv_query($this->link, $query);
function multi_query($query) {
$this->_result = sqlsrv_query($this->_link, $query);
$this->error = "";
if (!$this->result) {
$this->get_error();
if (!$this->_result) {
$this->_get_error();
return false;
}
return true;
@@ -79,33 +69,41 @@ if (isset($_GET["mssql"])) {
function store_result($result = null) {
if (!$result) {
$result = $this->result;
$result = $this->_result;
}
if (!$result) {
return false;
}
if (sqlsrv_field_metadata($result)) {
return new Result($result);
return new Min_Result($result);
}
$this->affected_rows = sqlsrv_rows_affected($result);
return true;
}
function next_result(): bool {
return $this->result ? !!sqlsrv_next_result($this->result) : false;
function next_result() {
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 {
public $num_rows;
private $result, $offset = 0, $fields;
class Min_Result {
var $_result, $_offset = 0, $_fields, $num_rows;
function __construct($result) {
$this->result = $result;
$this->_result = $result;
// $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) {
if (is_a($val, 'DateTime')) {
$row[$key] = $val->format("Y-m-d H:i:s");
@@ -116,174 +114,177 @@ if (isset($_GET["mssql"])) {
}
function fetch_assoc() {
return $this->convert(sqlsrv_fetch_array($this->result, SQLSRV_FETCH_ASSOC));
return $this->_convert(sqlsrv_fetch_array($this->_result, SQLSRV_FETCH_ASSOC));
}
function fetch_row() {
return $this->convert(sqlsrv_fetch_array($this->result, SQLSRV_FETCH_NUMERIC));
return $this->_convert(sqlsrv_fetch_array($this->_result, SQLSRV_FETCH_NUMERIC));
}
function fetch_field(): \stdClass {
if (!$this->fields) {
$this->fields = sqlsrv_field_metadata($this->result);
function fetch_field() {
if (!$this->_fields) {
$this->_fields = sqlsrv_field_metadata($this->_result);
}
$field = $this->fields[$this->offset++];
$return = new \stdClass;
$field = $this->_fields[$this->_offset++];
$return = new stdClass;
$return->name = $field["Name"];
$return->type = ($field["Type"] == 1 ? 254 : 15);
$return->charsetnr = 0;
$return->orgname = $field["Name"];
$return->type = ($field["Type"] == 1 ? 254 : 0);
return $return;
}
function seek($offset) {
for ($i=0; $i < $offset; $i++) {
sqlsrv_fetch($this->result); // SQLSRV_SCROLL_ABSOLUTE added in sqlsrv 1.1
sqlsrv_fetch($this->_result); // SQLSRV_SCROLL_ABSOLUTE added in sqlsrv 1.1
}
}
function __destruct() {
sqlsrv_free_stmt($this->result);
sqlsrv_free_stmt($this->_result);
}
}
function last_id($result) {
return get_val("SELECT SCOPE_IDENTITY()"); // @@IDENTITY can return trigger INSERT
} elseif (extension_loaded("mssql")) {
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 quote($string) {
return "'" . str_replace("'", "''", $string) . "'";
}
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);
}
}
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;
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;
}
function seek($offset) {
mssql_data_seek($this->_result, $offset);
}
function __destruct() {
mssql_free_result($this->_result);
}
}
} else {
abstract class MssqlDb extends PdoDb {
function select_db(string $database) {
} elseif (extension_loaded("pdo_dblib")) {
class Min_DB extends Min_PDO {
var $extension = "PDO_DBLIB";
function connect($server, $username, $password) {
$this->dsn("dblib:charset=utf8;host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\d)~', ';port=\1', $server)), $username, $password);
return true;
}
function select_db($database) {
// database selection is separated from the connection so dbname in DSN can't be used
return $this->query(use_sql($database));
}
function lastInsertId() {
return $this->pdo->lastInsertId();
}
}
function last_id($result) {
return connection()->lastInsertId();
}
function explain($connection, $query) {
}
if (extension_loaded("pdo_sqlsrv")) {
class Db extends MssqlDb {
public $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")) {
class Db extends MssqlDb {
public $extension = "PDO_DBLIB";
function attach(?string $server, string $username, string $password): string {
return $this->dsn("dblib:charset=utf8;host=" . str_replace(":", ";unix_socket=", preg_replace('~:(\d)~', ';port=\1', $server)), $username, $password);
}
return $this->query("USE " . idf_escape($database));
}
}
}
class Driver extends SqlDriver {
static $extensions = array("SQLSRV", "PDO_SQLSRV", "PDO_DBLIB");
static $jush = "mssql";
class Min_Driver extends Min_SQL {
public $insertFunctions = array("date|time" => "getdate");
public $editFunctions = array(
"int|decimal|real|float|money|datetime" => "+/-",
"char|text" => "+",
);
public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL");
public $functions = array("len", "lower", "round", "upper");
public $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
public $generated = array("PERSISTED", "VIRTUAL");
public $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();
$where = array();
$set = reset($rows);
$columns = "c" . implode(", c", range(1, count($set)));
$c = 0;
$insert = array();
foreach ($set as $key => $val) {
$c++;
$name = idf_unescape($key);
if (!$fields[$name]["auto_increment"]) {
$insert[$key] = "c$c";
}
if (isset($primary[$name])) {
$where[] = "$key = c$c";
} else {
$update[] = "$key = c$c";
}
}
$values = array();
function insertUpdate($table, $rows, $primary) {
foreach ($rows as $set) {
$values[] = "(" . implode(", ", $set) . ")";
}
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");
$update = array();
$where = array();
foreach ($set as $key => $val) {
$update[] = "$key = $val";
if (isset($primary[idf_unescape($key)])) {
$where[] = "$key = $val";
}
}
//! can use only one query for all rows
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
. " WHEN MATCHED THEN UPDATE SET " . implode(", ", $update)
. " WHEN NOT MATCHED THEN INSERT (" . implode(", ", array_keys($set)) . ") VALUES (" . implode(", ", $set) . ");" // ; is mandatory
)) {
return false;
}
} else {
$return = queries("INSERT INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ") VALUES\n" . implode(",\n", $values));
}
return $return;
return true;
}
function begin() {
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);
}
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')");
}
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") {
@@ -309,11 +320,17 @@ if (isset($_GET["mssql"])) {
}
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() {
return get_val("SELECT SUSER_NAME()");
global $connection;
return $connection->result("SELECT SUSER_NAME()");
}
function tables_list() {
@@ -321,21 +338,21 @@ if (isset($_GET["mssql"])) {
}
function count_tables($databases) {
global $connection;
$return = array();
foreach ($databases as $db) {
connection()->select_db($db);
$return[$db] = get_val("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES");
$connection->select_db($db);
$return[$db] = $connection->result("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES");
}
return $return;
}
function table_status($name = "") {
$return = array();
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
) {
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) {
if ($name != "") {
return $row;
}
$return[$row["Name"]] = $row;
}
return $return;
@@ -352,53 +369,41 @@ WHERE schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND type IN ('S', 'U', 'V')
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)");
$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, d.definition [default], d.name default_constraint, i.is_primary_key
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]
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
LEFT JOIN sys.default_constraints d ON c.default_object_id = d.object_id
LEFT JOIN sys.index_columns ic ON c.object_id = ic.object_id AND c.column_id = ic.column_id
LEFT JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE c.object_id = " . q($table_id)) as $row
) {
LEFT JOIN sys.default_constraints d ON c.default_object_id = d.parent_column_id
WHERE o.schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND o.type IN ('S', 'U', 'V') AND o.name = " . q($table)
) as $row) {
$type = $row["type"];
$length = (preg_match("~char|binary~", $type)
? intval($row["max_length"]) / ($type[0] == 'n' ? 2 : 1)
: ($type == "decimal" ? "$row[precision],$row[scale]" : "")
);
$length = (preg_match("~char|binary~", $type) ? $row["max_length"] : ($type == "decimal" ? "$row[precision],$row[scale]" : ""));
$return[$row["name"]] = array(
"field" => $row["name"],
"full_type" => $type . ($length ? "($length)" : ""),
"type" => $type,
"length" => $length,
"default" => (preg_match("~^\('(.*)'\)$~", $row["default"], $match) ? str_replace("''", "'", $match[1]) : $row["default"]),
"default_constraint" => $row["default_constraint"],
"default" => $row["default"],
"null" => $row["is_nullable"],
"auto_increment" => $row["is_identity"],
"collation" => $row["collation_name"],
"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"]],
);
}
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;
}
function indexes($table, $connection2 = null) {
$return = array();
// sp_statistics doesn't return information about primary key
foreach (
get_rows("SELECT i.name, key_ordinal, is_unique, is_primary_key, c.name AS column_name, is_descending_key
foreach (get_rows("SELECT i.name, key_ordinal, is_unique, is_primary_key, c.name AS column_name, is_descending_key
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.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"];
$return[$name]["type"] = ($row["is_primary_key"] ? "PRIMARY" : ($row["is_unique"] ? "UNIQUE" : "INDEX"));
$return[$name]["lengths"] = array();
@@ -409,7 +414,8 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
}
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() {
@@ -421,11 +427,12 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
}
function information_schema($db) {
return get_schema() == "INFORMATION_SCHEMA";
return false;
}
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) {
@@ -433,7 +440,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
}
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) {
@@ -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) {
$alter = array();
$comments = array();
$orig_fields = fields($table);
foreach ($fields as $field) {
$column = idf_escape($field[0]);
$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]);
$comments[$field[0]] = $val[5];
unset($val[5]);
if (preg_match('~ AS ~', $val[3])) {
unset($val[1], $val[2]);
}
if ($field[0] == "") {
$alter["ADD"][] = "\n " . implode("", $val) . ($table == "" ? substr($foreign[$val[0]], 16 + strlen($val[0])) : ""); // 16 - strlen(" FOREIGN KEY ()")
} else {
$default = $val[3];
unset($val[3]); // default values are set separately
unset($val[6]); //! identity can't be removed
if ($column != $val[0]) {
queries("EXEC sp_rename " . q(table($table) . ".$column") . ", " . q(idf_unescape($val[0])) . ", 'COLUMN'");
}
$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;
}
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;
}
}
foreach ($comments as $key => $val) {
$comment = substr($val, 9); // 9 - strlen(" COMMENT ")
queries("EXEC sp_dropextendedproperty @name = N'MS_Description', @level0type = N'Schema', @level0name = " . q(get_schema()) . ", @level1type = N'Table', @level1name = " . q($name) . ", @level2type = N'Column', @level2name = " . q($key));
queries("EXEC sp_addextendedproperty
@name = N'MS_Description',
@value = $comment,
@level0type = N'Schema',
@level0name = " . q(get_schema()) . ",
@level1type = N'Table',
@level1name = " . q($name) . ",
@level2type = N'Column',
@level2name = " . q($key))
;
queries("EXEC sp_addextendedproperty @name = N'MS_Description', @value = " . $comment . ", @level0type = N'Schema', @level0name = " . q(get_schema()) . ", @level1type = N'Table', @level1name = " . q($name) . ", @level2type = N'Column', @level2name = " . q($key));
}
return true;
}
@@ -527,12 +510,10 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
} else {
$index[] = idf_escape($val[1]) . " ON " . table($table);
}
} elseif (
!queries(($val[0] != "PRIMARY"
? "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"
) . " (" . implode(", ", $val[2]) . ")")
) {
} elseif (!queries(($val[0] != "PRIMARY"
? "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"
) . " (" . implode(", ", $val[2]) . ")")) {
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 foreign_keys($table) {
$return = array();
$on_actions = array("CASCADE", "NO ACTION", "SET NULL", "SET DEFAULT");
foreach (get_rows("EXEC sp_fkeys @fktable_name = " . q($table) . ", @fktable_owner = " . q(get_schema())) as $row) {
foreach (get_rows("EXEC sp_fkeys @fktable_name = " . q($table)) as $row) {
$foreign_key = &$return[$row["FK_NAME"]];
$foreign_key["db"] = $row["PKTABLE_QUALIFIER"];
$foreign_key["ns"] = $row["PKTABLE_OWNER"];
$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["target"][] = $row["PKCOLUMN_NAME"];
}
@@ -565,23 +554,22 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
}
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) {
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) {
return apply_queries("ALTER SCHEMA " . idf_escape($target) . " TRANSFER", array_merge($tables, $views));
}
function trigger($name, $table) {
function trigger($name) {
if ($name == "") {
return array();
}
$rows = get_rows(
"SELECT s.name [Trigger],
$rows = get_rows("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, 'ExecIsInsteadOfTrigger') = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END [Timing],
c.text
@@ -598,14 +586,13 @@ WHERE s.xtype = 'TR' AND s.name = " . q($name)
function triggers($table) {
$return = array();
foreach (
get_rows("SELECT sys1.name,
foreach (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, 'ExecIsInsteadOfTrigger') = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END [Timing]
FROM sysobjects sys1
JOIN sysobjects sys2 ON sys1.parent_obj = sys2.id
WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)) as $row
) { // triggers are not schema-scoped
WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)
) as $row) { // triggers are not schema-scoped
$return[$row["name"]] = array($row["Timing"], $row["Event"]);
}
return $return;
@@ -624,69 +611,34 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)) as $row
}
function get_schema() {
global $connection;
if ($_GET["ns"] != "") {
return $_GET["ns"];
}
return get_val("SELECT SCHEMA_NAME()");
return $connection->result("SELECT SCHEMA_NAME()");
}
function set_schema($schema) {
$_GET["ns"] = $schema;
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) {
return "USE " . idf_escape($database);
}
function trigger_sql($table) {
$return = "";
foreach (triggers($table) as $name => $trigger) {
$return .= create_trigger(" ON " . table($table), trigger($name, $table)) . ";";
}
return $return;
function show_variables() {
return array();
}
/**
* @return bool
*/
function is_strict_mode() {
return false;
}
function show_status() {
return array();
}
function convert_field($field) {
@@ -697,6 +649,38 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)) as $row
}
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
namespace Adminer;
add_driver("oracle", "Oracle (beta)");
$drivers["oracle"] = "Oracle (beta)";
if (isset($_GET["oracle"])) {
define('Adminer\DRIVER', "oracle");
if (extension_loaded("oci8") && $_GET["ext"] != "pdo") {
class Db extends SqlDb {
public $extension = "oci8";
public $_current_db;
private $link;
define("DRIVER", "oracle");
if (extension_loaded("oci8")) {
class Min_DB {
var $extension = "oci8", $_link, $_result, $server_info, $affected_rows, $errno, $error;
var $_current_db;
function _error($errno, $error) {
if (ini_bool("html_errors")) {
@@ -19,30 +16,31 @@ if (isset($_GET["oracle"])) {
$this->error = $error;
}
function attach(?string $server, string $username, string $password): string {
$this->link = @oci_new_connect($username, $password, $server, "AL32UTF8");
if ($this->link) {
$this->server_info = oci_server_version($this->link);
return '';
function connect($server, $username, $password) {
$this->_link = @oci_new_connect($username, $password, $server, "AL32UTF8");
if ($this->_link) {
$this->server_info = oci_server_version($this->_link);
return true;
}
$error = oci_error();
return $error["message"];
$this->error = $error["message"];
return false;
}
function quote(string $string): string {
function quote($string) {
return "'" . str_replace("'", "''", $string) . "'";
}
function select_db(string $database) {
function select_db($database) {
$this->_current_db = $database;
return true;
}
function query(string $query, bool $unbuffered = false) {
$result = oci_parse($this->link, $query);
function query($query, $unbuffered = false) {
$result = oci_parse($this->_link, $query);
$this->error = "";
if (!$result) {
$error = oci_error($this->link);
$error = oci_error($this->_link);
$this->errno = $error["code"];
$this->error = $error["message"];
return false;
@@ -52,26 +50,45 @@ if (isset($_GET["oracle"])) {
restore_error_handler();
if ($return) {
if (oci_num_fields($result)) {
return new Result($result);
return new Min_Result($result);
}
$this->affected_rows = oci_num_rows($result);
oci_free_statement($result);
}
return $return;
}
}
class Result {
public $num_rows;
private $result, $offset = 1;
function __construct($result) {
$this->result = $result;
function multi_query($query) {
return $this->_result = $this->query($query);
}
private function convert($row) {
function store_result() {
return $this->_result;
}
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) {
$this->_result = $result;
}
function _convert($row) {
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();
}
}
@@ -79,37 +96,39 @@ if (isset($_GET["oracle"])) {
}
function fetch_assoc() {
return $this->convert(oci_fetch_assoc($this->result));
return $this->_convert(oci_fetch_assoc($this->_result));
}
function fetch_row() {
return $this->convert(oci_fetch_row($this->result));
return $this->_convert(oci_fetch_row($this->_result));
}
function fetch_field(): \stdClass {
$column = $this->offset++;
$return = new \stdClass;
$return->name = oci_field_name($this->result, $column);
$return->type = oci_field_type($this->result, $column); //! map to MySQL numbers
function fetch_field() {
$column = $this->_offset++;
$return = new stdClass;
$return->name = oci_field_name($this->_result, $column);
$return->orgname = $return->name;
$return->type = oci_field_type($this->_result, $column);
$return->charsetnr = (preg_match("~raw|blob|bfile~", $return->type) ? 63 : 0); // 63 - binary
return $return;
}
function __destruct() {
oci_free_statement($this->result);
oci_free_statement($this->_result);
}
}
} elseif (extension_loaded("pdo_oci")) {
class Db extends PdoDb {
public $extension = "PDO_OCI";
public $_current_db;
class Min_DB extends Min_PDO {
var $extension = "PDO_OCI";
var $_current_db;
function attach(?string $server, string $username, string $password): string {
return $this->dsn("oci:dbname=//$server;charset=AL32UTF8", $username, $password);
function connect($server, $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;
return true;
}
@@ -119,33 +138,7 @@ if (isset($_GET["oracle"])) {
class Driver extends SqlDriver {
static $extensions = array("OCI8", "PDO_OCI");
static $jush = "oracle";
public $insertFunctions = array( //! no parentheses
"date" => "current_date",
"timestamp" => "current_timestamp",
);
public $editFunctions = array(
"number|float|double" => "+/-",
"date|timestamp" => "+ interval/- interval",
"char|clob" => "||",
);
public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL");
public $functions = array("length", "lower", "round", "upper");
public $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
function __construct(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),
);
}
class Min_Driver extends Min_SQL {
//! support empty $set in insert()
@@ -153,7 +146,8 @@ if (isset($_GET["oracle"])) {
return true; // automatic start
}
function insertUpdate(string $table, array $rows, array $primary) {
function insertUpdate($table, $rows, $primary) {
global $connection;
foreach ($rows as $set) {
$update = array();
$where = array();
@@ -163,22 +157,24 @@ if (isset($_GET["oracle"])) {
$where[] = "$key = $val";
}
}
if (
!(($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) . ")"))
) {
if (!(($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) . ")")
)) {
return false;
}
}
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) {
return '"' . str_replace('"', '""', $idf) . '"';
@@ -188,19 +184,23 @@ if (isset($_GET["oracle"])) {
return idf_escape($idf);
}
function get_databases($flush) {
return get_vals(
"SELECT DISTINCT tablespace_name FROM (
SELECT tablespace_name FROM user_tablespaces
UNION SELECT tablespace_name FROM all_tables WHERE tablespace_name IS NOT NULL
)
ORDER BY 1"
);
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 tablespace_name FROM user_tablespaces ORDER BY 1");
}
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"
: ($limit ? " * FROM (SELECT $query$where) WHERE rownum <= " . ($limit + $offset)
: ($limit !== null ? " * FROM (SELECT $query$where) WHERE rownum <= " . ($limit + $offset)
: " $query$where"
));
}
@@ -210,16 +210,23 @@ ORDER BY 1"
}
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() {
return get_val("SELECT USER FROM DUAL");
global $connection;
return $connection->result("SELECT USER FROM DUAL");
}
function get_current_db() {
$db = connection()->_current_db ?: DB;
unset(connection()->_current_db);
global $connection;
$db = $connection->_current_db ? $connection->_current_db : DB;
unset($connection->_current_db);
return $db;
}
@@ -232,23 +239,23 @@ ORDER BY 1"
function views_table($columns) {
$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() {
$view = views_table("view_name");
$owner = where_owner(" AND ");
return get_key_vals(
"SELECT table_name, 'table' FROM all_tables WHERE tablespace_name = " . q(DB) . "$owner
return get_key_vals("SELECT table_name, 'table' FROM all_tables WHERE tablespace_name = " . q(DB) . "$owner
UNION SELECT view_name, 'view' FROM $view
ORDER BY 1"
); //! views don't have schema
}
function count_tables($databases) {
global $connection;
$return = array();
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;
}
@@ -259,11 +266,13 @@ ORDER BY 1"
$db = get_current_db();
$view = views_table("view_name");
$owner = where_owner(" AND ");
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" : "") . "
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" : "") . "
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 $return;
@@ -306,14 +315,12 @@ ORDER BY 1") as $row
function indexes($table, $connection2 = null) {
$return = array();
$owner = where_owner(" AND ", "aic.table_owner");
foreach (
get_rows("SELECT aic.*, ac.constraint_type, atc.data_default
foreach (get_rows("SELECT aic.*, ac.constraint_type, atc.data_default
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_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
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"];
$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
@@ -336,11 +343,12 @@ ORDER BY ac.constraint_type, aic.column_position", $connection2) as $row
}
function information_schema($db) {
return get_schema() == "INFORMATION_SCHEMA";
return false;
}
function error() {
return h(connection()->error); //! highlight sqltext from offset
global $connection;
return h($connection->error); //! highlight sqltext from offset
}
function explain($connection, $query) {
@@ -452,50 +460,41 @@ AND c_src.TABLE_NAME = " . q($table);
return apply_queries("DROP TABLE", $tables);
}
function last_id($result) {
function last_id() {
return 0; //!
}
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 ($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() {
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) {
global $connection;
if (!$connection2) {
$connection2 = connection();
$connection2 = $connection;
}
return $connection2->query("ALTER SESSION SET CURRENT_SCHEMA = " . idf_escape($scheme));
}
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;
/**
* @return bool
*/
function is_strict_mode() {
return false;
}
function process_list() {
return get_rows('SELECT
sess.process AS "process",
sess.username AS "user",
sess.schemaname AS "schema",
sess.status AS "status",
sess.wait_class AS "wait_class",
sess.seconds_in_wait AS "seconds_in_wait",
sql.sql_text AS "sql_text",
sess.machine AS "machine",
sess.port AS "port"
return get_rows('SELECT sess.process AS "process", sess.username AS "user", sess.schemaname AS "schema", sess.status AS "status", sess.wait_class AS "wait_class", sess.seconds_in_wait AS "seconds_in_wait", sql.sql_text AS "sql_text", sess.machine AS "machine", sess.port AS "port"
FROM v$session sess LEFT OUTER JOIN v$sql sql
ON sql.sql_id = sess.sql_id
WHERE sess.type = \'USER\'
@@ -503,6 +502,11 @@ ORDER BY PROCESS
');
}
function show_status() {
$rows = get_rows('SELECT * FROM v$instance');
return reset($rows);
}
function convert_field($field) {
}
@@ -513,4 +517,38 @@ ORDER BY PROCESS
function support($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,146 +1,216 @@
<?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"])) {
define('Adminer\DRIVER', "sqlite");
if (class_exists("SQLite3") && $_GET["ext"] != "pdo") {
class Min_SQLite {
var $extension = "SQLite3", $server_info, $affected_rows, $errno, $error, $_link;
abstract class SqliteDb extends SqlDb {
public $extension = "SQLite3";
private $link;
function attach(?string $filename, string $username, string $password): string {
$this->link = new \SQLite3($filename);
$version = $this->link->version();
$this->server_info = $version["versionString"];
return '';
}
function query(string $query, bool $unbuffered = false) {
$result = @$this->link->query($query);
$this->error = "";
if (!$result) {
$this->errno = $this->link->lastErrorCode();
$this->error = $this->link->lastErrorMsg();
return false;
} elseif ($result->numColumns()) {
return new Result($result);
function __construct($filename) {
$this->_link = new SQLite3($filename);
$version = $this->_link->version();
$this->server_info = $version["versionString"];
}
function query($query) {
$result = @$this->_link->query($query);
$this->error = "";
if (!$result) {
$this->errno = $this->_link->lastErrorCode();
$this->error = $this->_link->lastErrorMsg();
return false;
} elseif ($result->numColumns()) {
return new Min_Result($result);
}
$this->affected_rows = $this->_link->changes();
return true;
}
function quote($string) {
return (is_utf8($string)
? "'" . $this->_link->escapeString($string) . "'"
: "x'" . reset(unpack('H*', $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->fetchArray();
return $row[$field];
}
$this->affected_rows = $this->link->changes();
return true;
}
function quote(string $string): string {
return (is_utf8($string)
? "'" . $this->link->escapeString($string) . "'"
: "x'" . first(unpack('H*', $string)) . "'"
);
}
}
class Min_Result {
var $_result, $_offset = 0, $num_rows;
class Result {
public $num_rows;
private $result, $offset = 0;
function __construct($result) {
$this->_result = $result;
}
function __construct($result) {
$this->result = $result;
function fetch_assoc() {
return $this->_result->fetchArray(SQLITE3_ASSOC);
}
function fetch_row() {
return $this->_result->fetchArray(SQLITE3_NUM);
}
function fetch_field() {
$column = $this->_offset++;
$type = $this->_result->columnType($column);
return (object) array(
"name" => $this->_result->columnName($column),
"type" => $type,
"charsetnr" => ($type == SQLITE3_BLOB ? 63 : 0), // 63 - binary
);
}
function __desctruct() {
return $this->_result->finalize();
}
}
function fetch_assoc() {
return $this->result->fetchArray(SQLITE3_ASSOC);
} 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];
}
}
function fetch_row() {
return $this->result->fetchArray(SQLITE3_NUM);
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,
);
}
}
function fetch_field(): \stdClass {
$column = $this->offset++;
$type = $this->result->columnType($column);
return (object) array(
"name" => $this->result->columnName($column),
"type" => ($type == SQLITE3_TEXT ? 15 : 0),
"charsetnr" => ($type == SQLITE3_BLOB ? 63 : 0), // 63 - binary
);
}
function __destruct() {
$this->result->finalize();
}
}
} elseif (extension_loaded("pdo_sqlite")) {
abstract class SqliteDb extends PdoDb {
public $extension = "PDO_SQLite";
class Min_SQLite extends Min_PDO {
var $extension = "PDO_SQLite";
function attach(?string $filename, string $username, string $password): string {
function __construct($filename) {
$this->dsn(DRIVER . ":$filename", "", "");
$this->query("PRAGMA foreign_keys = 1");
$this->query("PRAGMA busy_timeout = 500");
return '';
}
}
}
if (class_exists('Adminer\SqliteDb')) {
class Db extends SqliteDb {
function attach(?string $filename, string $username, string $password): string {
parent::attach($filename, $username, $password);
if (class_exists("Min_SQLite")) {
class Min_DB extends Min_SQLite {
function __construct() {
parent::__construct(":memory:");
$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, '', '');
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 busy_timeout = 500");
return true;
}
return false;
}
function multi_query($query) {
return $this->_result = $this->query($query);
}
function next_result() {
return false;
}
}
}
class Driver extends SqlDriver {
static $extensions = array("SQLite3", "PDO_SQLite");
static $jush = "sqlite";
class Min_Driver extends Min_SQL {
protected $types = array(array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0));
public $insertFunctions = array(); // "text" => "date('now')/time('now')/datetime('now')",
public $editFunctions = array(
"integer|real|numeric" => "+/-",
// "text" => "date/time/datetime",
"text" => "||",
);
public $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"); // REGEXP can be user defined function
public $functions = array("hex", "length", "lower", "round", "unixepoch", "upper");
public $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
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) {
function insertUpdate($table, $rows, $primary) {
$values = array();
foreach ($rows as $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));
}
function tableHelp(string $name, bool $is_view = false) {
function tableHelp($name) {
if ($name == "sqlite_sequence") {
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);
}
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();
}
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") {
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)
: " $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) {
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() {
@@ -215,15 +286,16 @@ if (isset($_GET["sqlite"])) {
}
function table_status($name = "") {
global $connection;
$return = array();
foreach (get_rows("SELECT name AS Name, type AS Engine, 'rowid' AS Oid, '' AS Auto_increment FROM sqlite_master WHERE type IN ('table', 'view') " . ($name != "" ? "AND name = " . q($name) : "ORDER BY name")) as $row) {
$row["Rows"] = get_val("SELECT COUNT(*) FROM " . idf_escape($row["Name"]));
$row["Rows"] = $connection->result("SELECT COUNT(*) FROM " . idf_escape($row["Name"]));
$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 $return;
return ($name != "" ? $return[$name] : $return);
}
function is_view($table_status) {
@@ -231,13 +303,15 @@ if (isset($_GET["sqlite"])) {
}
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) {
global $connection;
$return = array();
$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"];
$type = strtolower($row["type"]);
$default = $row["dflt_value"];
@@ -245,7 +319,7 @@ if (isset($_GET["sqlite"])) {
"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")))),
"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"],
"privileges" => array("select" => 1, "insert" => 1, "update" => 1, "where" => 1, "order" => 1),
"primary" => $row["pk"],
@@ -259,28 +333,24 @@ if (isset($_GET["sqlite"])) {
$primary = $name;
}
}
$sql = get_val("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table));
$idf = '(("[^"]*+")+|[a-z0-9_]+)';
preg_match_all('~' . $idf . '\s+text\s+COLLATE\s+(\'[^\']+\'|\S+)~i', $sql, $matches, PREG_SET_ORDER);
$sql = $connection->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table));
preg_match_all('~(("[^"]*+")+|[a-z0-9_]+)\s+text\s+COLLATE\s+(\'[^\']+\'|\S+)~i', $sql, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$name = str_replace('""', '"', preg_replace('~^"|"$~', '', $match[1]));
if ($return[$name]) {
$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;
}
function indexes($table, $connection2 = null) {
$connection2 = connection($connection2);
global $connection;
if (!is_object($connection2)) {
$connection2 = $connection;
}
$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)) {
$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);
@@ -325,6 +395,7 @@ if (isset($_GET["sqlite"])) {
$return = array();
foreach (get_rows("PRAGMA foreign_key_list(" . table($table) . ")") as $row) {
$foreign_key = &$return[$row["id"]];
//! idf_unescape in SQLite2
if (!$foreign_key) {
$foreign_key = $row;
}
@@ -335,7 +406,8 @@ if (isset($_GET["sqlite"])) {
}
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() {
@@ -347,32 +419,34 @@ if (isset($_GET["sqlite"])) {
}
function error() {
return h(connection()->error);
global $connection;
return h($connection->error);
}
function check_sqlite_name($name) {
// avoid creating PHP files on unsecured servers
global $connection;
$extensions = "db|sdb|sqlite";
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 true;
}
function create_database($db, $collation) {
global $connection;
if (file_exists($db)) {
connection()->error = lang('File exists.');
$connection->error = lang('File exists.');
return false;
}
if (!check_sqlite_name($db)) {
return false;
}
try {
$link = new Db();
$link->attach($db, '', '');
} catch (\Exception $ex) {
connection()->error = $ex->getMessage();
$link = new Min_SQLite($db);
} catch (Exception $ex) {
$connection->error = $ex->getMessage();
return false;
}
$link->query('PRAGMA encoding = "UTF-8"');
@@ -382,10 +456,11 @@ if (isset($_GET["sqlite"])) {
}
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) {
if (!@unlink($db)) {
connection()->error = lang('File exists.');
$connection->error = lang('File exists.');
return false;
}
}
@@ -393,19 +468,21 @@ if (isset($_GET["sqlite"])) {
}
function rename_database($name, $collation) {
global $connection;
if (!check_sqlite_name($name)) {
return false;
}
connection()->attach(":memory:", '', '');
connection()->error = lang('File exists.');
$connection->__construct(":memory:");
$connection->error = lang('File exists.');
return @rename(DB, $name);
}
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) {
global $connection;
$use_all_fields = ($table == "" || $foreign);
foreach ($fields as $field) {
if ($field[0] != "" || !$field[1] || $field[2]) {
@@ -438,7 +515,7 @@ if (isset($_GET["sqlite"])) {
if ($auto_increment) {
queries("BEGIN");
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("COMMIT");
@@ -446,18 +523,8 @@ if (isset($_GET["sqlite"])) {
return true;
}
/** Recreate table
* @param string $table original name
* @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 {
function recreate_table($table, $name, $fields, $originals, $foreign, $auto_increment, $indexes = array()) {
global $connection;
if ($table != "") {
if (!$fields) {
foreach (fields($table) as $key => $field) {
@@ -514,39 +581,26 @@ if (isset($_GET["sqlite"])) {
}
queries("BEGIN");
}
$changes = array();
foreach ($fields as $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)";
foreach ($fields as $key => $field) {
$fields[$key] = " " . implode($field);
}
$fields = array_merge($fields, array_filter($foreign));
$temp_name = ($table == $name ? "adminer_$name" : $name);
if (!queries("CREATE TABLE " . table($temp_name) . " (\n" . implode(",\n", $changes) . "\n)")) {
// implicit ROLLBACK to not overwrite connection()->error
if (!queries("CREATE TABLE " . table($temp_name) . " (\n" . implode(",\n", $fields) . "\n)")) {
// implicit ROLLBACK to not overwrite $connection->error
return false;
}
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;
}
$triggers = array();
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]";
}
$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
if (
!queries("DROP TABLE " . table($table)) // drop before creating indexes and triggers to allow using old names
$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 (!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)))
|| !alter_indexes($name, $indexes)
) {
@@ -576,15 +630,14 @@ if (isset($_GET["sqlite"])) {
function alter_indexes($table, $alter) {
foreach ($alter as $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) {
if (
!queries($val[2] == "DROP"
if (!queries($val[2] == "DROP"
? "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;
}
}
@@ -607,7 +660,8 @@ if (isset($_GET["sqlite"])) {
return false;
}
function trigger($name, $table) {
function trigger($name) {
global $connection;
if ($name == "") {
return array("Statement" => "BEGIN\n\t;\nEND");
}
@@ -615,7 +669,7 @@ if (isset($_GET["sqlite"])) {
$trigger_options = trigger_options();
preg_match(
"~^CREATE\\s+TRIGGER\\s*$idf\\s*(" . implode("|", $trigger_options["Timing"]) . ")\\s+([a-z]+)(?:\\s+OF\\s+($idf))?\\s+ON\\s*$idf\\s*(?:FOR\\s+EACH\\s+ROW\\s)?(.*)~is",
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
);
$of = $match[3];
@@ -650,8 +704,9 @@ if (isset($_GET["sqlite"])) {
return queries("BEGIN");
}
function last_id($result) {
return get_val("SELECT LAST_INSERT_ROWID()");
function last_id() {
global $connection;
return $connection->result("SELECT LAST_INSERT_ROWID()");
}
function explain($connection, $query) {
@@ -661,17 +716,30 @@ if (isset($_GET["sqlite"])) {
function found_rows($table_status, $where) {
}
function types(): array {
function types() {
return array();
}
function schemas() {
return array();
}
function get_schema() {
return "";
}
function set_schema($scheme) {
return true;
}
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) {
if ($name == '') {
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;
}
@@ -688,23 +756,26 @@ if (isset($_GET["sqlite"])) {
}
function show_variables() {
global $connection;
$return = array();
foreach (get_rows("PRAGMA pragma_list") as $row) {
$name = $row["name"];
if ($name != "pragma_list" && $name != "compile_options") {
$return[$name] = array($name, '');
foreach (get_rows("PRAGMA $name") as $row) {
$return[$name][1] .= implode(", ", $row) . "\n";
}
}
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) {
$return[$key] = $connection->result("PRAGMA $key");
}
return $return;
}
/**
* @return bool
*/
function is_strict_mode() {
return false;
}
function show_status() {
$return = array();
foreach (get_vals("PRAGMA compile_options") as $option) {
$return[] = explode("=", $option, 2) + array('', '');
list($key, $val) = explode("=", $option, 2);
$return[$key] = $val;
}
return $return;
}
@@ -717,6 +788,29 @@ if (isset($_GET["sqlite"])) {
}
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
namespace Adminer;
$TABLE = $_GET["dump"];
if ($_POST && !$error) {
save_settings(
array_intersect_key($_POST, array_flip(array("output", "format", "db_style", "types", "routines", "events", "table_style", "auto_increment", "triggers", "data_style"))),
"adminer_export"
);
$cookie = "";
foreach (array("output", "format", "db_style", "routines", "events", "table_style", "auto_increment", "triggers", "data_style") as $key) {
$cookie .= "&$key=" . urlencode($_POST[$key]);
}
cookie("adminer_export", substr($cookie, 1));
$tables = array_flip((array) $_POST["tables"]) + array_flip((array) $_POST["data"]);
$ext = dump_headers(
(count($tables) == 1 ? key($tables) : DB),
(DB == "" || count($tables) > 1)
);
(DB == "" || count($tables) > 1));
$is_sql = preg_match('~sql~', $_POST["format"]);
if ($is_sql) {
echo "-- Adminer " . VERSION . " " . get_driver(DRIVER) . " " . str_replace("\n", " ", connection()->server_info) . " dump\n\n";
if (JUSH == "sql") {
echo "-- Adminer $VERSION " . $drivers[DRIVER] . " " . str_replace("\n", " ", $connection->server_info) . " dump\n\n";
if ($jush == "sql") {
echo "SET NAMES utf8;
SET time_zone = '+00:00';
SET foreign_key_checks = 0;
" . ($_POST["data_style"] ? "SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
" : "") . "
";
connection()->query("SET time_zone = '+00:00'");
connection()->query("SET sql_mode = ''");
$connection->query("SET time_zone = '+00:00'");
$connection->query("SET sql_mode = ''");
}
}
@@ -39,9 +37,9 @@ SET foreign_key_checks = 0;
}
foreach ((array) $databases as $db) {
adminer()->dumpDatabase($db);
if (connection()->select_db($db)) {
if ($is_sql && preg_match('~CREATE~', $style) && ($create = get_val("SHOW CREATE DATABASE " . idf_escape($db), 1))) {
$adminer->dumpDatabase($db);
if ($connection->select_db($db)) {
if ($is_sql && preg_match('~CREATE~', $style) && ($create = $connection->result("SHOW CREATE DATABASE " . idf_escape($db), 1))) {
set_utf8mb4($create);
if ($style == "DROP+CREATE") {
echo "DROP DATABASE IF EXISTS " . idf_escape($db) . ";\n";
@@ -54,37 +52,27 @@ SET foreign_key_checks = 0;
}
$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"]) {
foreach (routines() as $row) {
$name = $row["ROUTINE_NAME"];
$routine = $row["ROUTINE_TYPE"];
$create = create_routine($routine, array("name" => $name) + routine($row["SPECIFIC_NAME"], $routine));
set_utf8mb4($create);
$out .= ($style != 'DROP+CREATE' ? "DROP $routine IF EXISTS " . idf_escape($name) . ";;\n" : "") . "$create;\n\n";
foreach (array("FUNCTION", "PROCEDURE") as $routine) {
foreach (get_rows("SHOW $routine STATUS WHERE Db = " . q($db), null, "-- ") as $row) {
$create = remove_definer($connection->result("SHOW CREATE $routine " . idf_escape($row["Name"]), 2));
set_utf8mb4($create);
$out .= ($style != 'DROP+CREATE' ? "DROP $routine IF EXISTS " . idf_escape($row["Name"]) . ";;\n" : "") . "$create;;\n\n";
}
}
}
if ($_POST["events"]) {
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);
$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"]) {
@@ -93,18 +81,17 @@ SET foreign_key_checks = 0;
$table = (DB == "" || in_array($name, (array) $_POST["tables"]));
$data = (DB == "" || in_array($name, (array) $_POST["data"]));
if ($table || $data) {
$tmp_file = null;
if ($ext == "tar") {
$tmp_file = new TmpFile;
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)) {
$views[] = $name;
} elseif ($data) {
$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))) {
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)
if (function_exists('Adminer\foreign_keys_sql')) {
if (function_exists('foreign_keys_sql')) {
foreach (table_status('', true) as $name => $table_status) {
$table = (DB == "" || in_array($name, (array) $_POST["tables"]));
if ($table && !is_view($table_status)) {
@@ -130,7 +117,7 @@ SET foreign_key_checks = 0;
}
foreach ($views as $view) {
adminer()->dumpTable($view, $_POST["table_style"], 1);
$adminer->dumpTable($view, $_POST["table_style"], 1);
}
if ($ext == "tar") {
@@ -140,7 +127,9 @@ SET foreign_key_checks = 0;
}
}
adminer()->dumpFooter();
if ($is_sql) {
echo "-- " . $connection->result("SELECT NOW()") . "\n";
}
exit;
}
@@ -148,29 +137,26 @@ page_header(lang('Export'), $error, ($_GET["export"] != "" ? array("table" => $_
?>
<form action="" method="post">
<table class="layout">
<table cellspacing="0" class="layout">
<?php
$db_style = array('', 'USE', 'DROP+CREATE', 'CREATE');
$table_style = array('', 'DROP+CREATE', 'CREATE');
$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';
}
$row = get_settings("adminer_export");
parse_str($_COOKIE["adminer_export"], $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
$row["routines"] = $row["events"] = ($_GET["dump"] == "");
$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"])
. (support("type") ? checkbox("types", 1, $row["types"], lang('User types')) : "")
echo ($jush == "sqlite" ? "" : "<tr><th>" . lang('Database') . "<td>" . html_select('db_style', $db_style, $row["db_style"])
. (support("routine") ? checkbox("routines", 1, $row["routines"], lang('Routines')) : "")
. (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('Output') . "<td>" . html_select("output", $adminer->dumpOutput(), $row["output"], false) . "\n"; // false = radio
?>
</table>
<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
echo script("qsl('table').onclick = dumpClick;");
$prefixes = array();
@@ -221,7 +210,7 @@ if (DB != "") {
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 "</thead>\n";
$databases = adminer()->databases();
$databases = $adminer->databases();
if ($databases) {
foreach ($databases as $db) {
if (!information_schema($db)) {

View File

@@ -1,15 +1,10 @@
<?php
namespace Adminer;
$TABLE = $_GET["edit"];
$fields = fields($TABLE);
$where = (isset($_GET["select"])
? ($_POST["check"] && count($_POST["check"]) == 1 ? where_check($_POST["check"][0], $fields) : "")
: where($_GET, $fields)
);
$where = (isset($_GET["select"]) ? ($_POST["check"] && count($_POST["check"]) == 1 ? where_check($_POST["check"][0], $fields) : "") : where($_GET, $fields));
$update = (isset($_GET["select"]) ? $_POST["edit"] : $where);
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]);
}
}
@@ -30,7 +25,7 @@ if ($_POST && !$error && !isset($_GET["select"])) {
queries_redirect(
$location,
lang('Item has been deleted.'),
driver()->delete($TABLE, $query_where, $unique_array ? 0 : 1)
$driver->delete($TABLE, $query_where, !$unique_array)
);
} else {
@@ -49,7 +44,7 @@ if ($_POST && !$error && !isset($_GET["select"])) {
queries_redirect(
$location,
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()) {
page_headers();
@@ -57,8 +52,8 @@ if ($_POST && !$error && !isset($_GET["select"])) {
exit;
}
} else {
$result = driver()->insert($TABLE, $set);
$last_id = ($result ? last_id($result) : 0);
$result = $driver->insert($TABLE, $set);
$last_id = ($result ? last_id() : 0);
queries_redirect($location, lang('Item%s has been inserted.', ($last_id ? " $last_id" : "")), $result); //! link
}
}
@@ -71,7 +66,13 @@ if ($_POST["save"]) {
$select = array();
foreach ($fields as $name => $field) {
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);
}
}
@@ -80,7 +81,7 @@ if ($_POST["save"]) {
$select = array("*");
}
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) {
$error = error();
} else {
@@ -95,12 +96,12 @@ if ($_POST["save"]) {
}
}
if (!support("table") && !$fields) { // used by Mongo and SimpleDB
if (!support("table") && !$fields) {
if (!$where) { // insert
$result = driver()->select($TABLE, array("*"), array(), array("*"));
$result = $driver->select($TABLE, array("*"), $where, array("*"));
$row = ($result ? $result->fetch_assoc() : false);
if (!$row) {
$row = array(driver()->primary => "");
$row = array($driver->primary => "");
}
}
if ($row) {
@@ -108,9 +109,9 @@ if (!support("table") && !$fields) { // used by Mongo and SimpleDB
if (!$where) {
$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
// To create Adminer just for Elasticsearch, run `../compile.php elastic`.
function adminer_object() {
include_once "../plugins/plugin.php";
include_once "../plugins/login-password-less.php";
include_once "../plugins/drivers/elastic.php";
return new Adminer\Plugins(array(
// TODO: inline the result of password_hash() so that the password is not visible in source codes
new AdminerLoginPasswordLess(password_hash("YOUR_PASSWORD_HERE", PASSWORD_DEFAULT)),
));
include_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
new AdminerLoginPasswordLess(password_hash("YOUR_PASSWORD_HERE", PASSWORD_DEFAULT)),
]);
}
include "./index.php";

View File

@@ -1,6 +1,4 @@
<?php
namespace Adminer;
$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");
$statuses = array("ENABLED" => "ENABLE", "DISABLED" => "DISABLE", "SLAVESIDE_DISABLED" => "DISABLE ON SLAVE");
@@ -17,18 +15,14 @@ if ($_POST && !$error) {
: "AT " . q($row["STARTS"])
) . " ON COMPLETION" . ($row["ON_COMPLETION"] ? "" : " NOT") . " PRESERVE"
;
queries_redirect(
substr(ME, 0, -1),
($EVENT != "" ? lang('Event has been altered.') : lang('Event has been created.')),
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
) . "\n" . $statuses[$row["STATUS"]] . " COMMENT " . q($row["EVENT_COMMENT"])
. rtrim(" DO\n$row[EVENT_DEFINITION]", ";") . ";"
)
);
queries_redirect(substr(ME, 0, -1), ($EVENT != "" ? lang('Event has been altered.') : lang('Event has been created.')), 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
) . "\n" . $statuses[$row["STATUS"]] . " COMMENT " . q($row["EVENT_COMMENT"])
. rtrim(" DO\n$row[EVENT_DEFINITION]", ";") . ";"
));
}
}
@@ -41,7 +35,7 @@ if (!$row && $EVENT != "") {
?>
<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 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"]); ?>">
@@ -53,8 +47,6 @@ if (!$row && $EVENT != "") {
<p><?php textarea("EVENT_DEFINITION", $row["EVENT_DEFINITION"]); ?>
<p>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php if ($EVENT != "") { ?>
<input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $EVENT)); ?>
<?php } ?>
<?php echo input_token(); ?>
<?php if ($EVENT != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $EVENT)); ?><?php } ?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form>

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,11 @@
<?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();
if ($_COOKIE["adminer_permanent"]) {
@@ -9,18 +15,74 @@ if ($_COOKIE["adminer_permanent"]) {
}
}
function add_invalid_login(): void {
$base = get_temp_dir() . "/adminer.invalid";
// adminer.invalid may not be writable by us, try the files with random suffixes
foreach (glob("$base*") ?: array($base) as $filename) {
$fp = file_open_lock($filename);
if ($fp) {
break;
}
function validate_server_input() {
if (SERVER == "") {
return;
}
if (!$fp) {
$fp = file_open_lock("$base-" . rand_string());
$parts = parse_url(SERVER);
if (!$parts) {
auth_error(lang('Invalid server or credentials.'));
}
// 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) {
return;
}
@@ -33,7 +95,7 @@ function add_invalid_login(): void {
}
}
}
$invalid = &$invalids[adminer()->bruteForceKey()];
$invalid = &$invalids[$adminer->bruteForceKey()];
if (!$invalid) {
$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));
}
/** @param string[] $permanent */
function check_invalid_login(array &$permanent): void {
$invalids = array();
foreach (glob(get_temp_dir() . "/adminer.invalid*") as $filename) {
$fp = file_open_lock($filename);
if ($fp) {
$invalids = unserialize(stream_get_contents($fp));
file_unlock($fp);
break;
}
}
/** @var array{int, int} */
$invalid = idx($invalids, adminer()->bruteForceKey(), array());
function check_invalid_login() {
global $adminer;
$invalids = unserialize(@file_get_contents(get_temp_dir() . "/adminer.invalid")); // @ - may not exist
$invalid = ($invalids ? $invalids[$adminer->bruteForceKey()] : array());
$next_attempt = ($invalid[1] > 29 ? $invalid[0] - time() : 0); // allow 30 invalid attempts
if ($next_attempt > 0) { //! do the same with permanent login
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) {
session_regenerate_id(); // defense against session fixation
$vendor = $auth["driver"];
$server = $auth["server"];
$server = trim($auth["server"]);
$username = $auth["username"];
$password = (string) $auth["password"];
$db = $auth["db"];
set_password($vendor, $server, $username, $password);
$_SESSION["db"][$vendor][$server][$username][$db] = true;
if ($auth["permanent"]) {
$key = implode("-", array_map('base64_encode', array($vendor, $server, $username, $db)));
$private = adminer()->permanentLogin(true);
$key = base64_encode($vendor) . "-" . base64_encode($server) . "-" . base64_encode($username) . "-" . base64_encode($db);
$private = $adminer->permanentLogin(true);
$permanent[$key] = "$key:" . base64_encode($private ? encrypt_string($password, $private) : "");
cookie("adminer_permanent", implode(" ", $permanent));
}
if (
count($_POST) == 1 // 1 - auth
if (count($_POST) == 1 // 1 - auth
|| DRIVER != $vendor
|| SERVER != $server
|| $_GET["username"] !== $username // "0" == "00"
@@ -86,16 +138,16 @@ if ($auth) {
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) {
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>.'));
} elseif ($permanent && !$_SESSION["pwds"]) {
session_regenerate_id();
$private = adminer()->permanentLogin();
$private = $adminer->permanentLogin();
foreach ($permanent as $key => $val) {
list(, $cipher) = explode(":", $val);
list($vendor, $server, $username, $db) = array_map('base64_decode', explode("-", $key));
@@ -104,10 +156,8 @@ if ($auth) {
}
}
/** Remove credentials from permanent login
* @param string[] $permanent
*/
function unset_permanent(array &$permanent): void {
function unset_permanent() {
global $permanent;
foreach ($permanent as $key => $val) {
list($vendor, $server, $username, $db) = array_map('base64_decode', explode("-", $key));
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));
}
/** Render an error message and a login form
* @param string $error plain text
* @param string[] $permanent
* @return never
/** Renders an error message and a login form
* @param string plain text
* @return null exits
*/
function auth_error(string $error, array &$permanent) {
function auth_error($error) {
global $adminer, $has_token;
$session_name = session_name();
if (isset($_GET["username"])) {
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.');
} else {
restart_session();
@@ -138,17 +188,14 @@ function auth_error(string $error, array &$permanent) {
}
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")) {
$error = lang('Session support must be enabled.');
}
$params = session_get_cookie_params();
cookie("adminer_key", ($_COOKIE["adminer_key"] ?: rand_string()), $params["lifetime"]);
if (!$_SESSION["token"]) {
$_SESSION["token"] = rand(1, 1e6); // this is for next attempt
}
cookie("adminer_key", ($_COOKIE["adminer_key"] ? $_COOKIE["adminer_key"] : rand_string()), $params["lifetime"]);
page_header(lang('Login'), $error, null);
echo "<form action='' method='post'>\n";
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 "</div>\n";
adminer()->loginForm();
$adminer->loginForm();
echo "</form>\n";
page_footer("auth");
exit;
}
if (isset($_GET["username"]) && !class_exists('Adminer\Db')) {
if (isset($_GET["username"]) && !class_exists("Min_DB")) {
unset($_SESSION["pwds"][DRIVER]);
unset_permanent($permanent);
page_header(lang('No extension'), lang('None of the supported PHP extensions (%s) are available.', implode(", ", Driver::$extensions)), false);
unset_permanent();
page_header(lang('No extension'), lang('None of the supported PHP extensions (%s) are available.', implode(", ", $possible_drivers)), false);
page_footer("auth");
exit;
}
$connection = '';
stop_session(true);
if (isset($_GET["username"]) && is_string(get_password())) {
list($host, $port) = explode(":", SERVER, 2);
if (preg_match('~^\s*([-+]?\d+)~', $port, $match) && ($match[1] < 1024 || $match[1] > 65535)) { // is_numeric('80#') would still connect to port 80
auth_error(lang('Connecting to privileged ports is not allowed.'), $permanent);
}
check_invalid_login($permanent);
$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)));
}
}
validate_server_input();
check_invalid_login();
$connection = connect();
$driver = new Min_Driver($connection);
}
$login = null;
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.')))
. (preg_match('~^ | $~', get_password()) ? '<br>' . lang('There is a space in the input password which might be the cause.') : '');
auth_error($error, $permanent);
if (!is_object($connection) || ($login = $adminer->login($_GET["username"], get_password())) !== true) {
$error = (is_string($connection) ? h($connection) : (is_string($login) ? $login : lang('Invalid server or credentials.')));
auth_error($error . (preg_match('~^ | $~', get_password()) ? '<br>' . lang('There is a space in the input password which might be the cause.') : ''));
}
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_footer("db");
exit;
}
if (!$_SESSION["token"]) {
$_SESSION["token"] = rand(1, 1e6); // defense against cross-site request forgery
}
stop_session(true);
if ($auth && $_POST["token"]) {
$_POST["token"] = get_token(); // reset token after explicit login
$_POST["token"] = $token; // reset token after explicit login
}
$error = ''; ///< @var string

View File

@@ -1,9 +1,11 @@
<?php
namespace Adminer;
function adminer_errors($errno, $errstr) {
return (bool)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";
// disable filter.default
@@ -22,7 +24,6 @@ if (function_exists("mb_internal_encoding")) {
}
include "../adminer/include/functions.inc.php";
include "../adminer/include/html.inc.php";
// used only in compiled file
if (isset($_GET["file"])) {
@@ -30,16 +31,14 @@ if (isset($_GET["file"])) {
}
if ($_GET["script"] == "version") {
$filename = get_temp_dir() . "/adminer.version";
@unlink($filename); // it may not be writable by us, @ - it may not exist
$fp = file_open_lock($filename);
$fp = file_open_lock(get_temp_dir() . "/adminer.version");
if ($fp) {
file_write_unlock($fp, serialize(array("signature" => $_POST["signature"], "version" => $_POST["version"])));
}
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
$_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"]) {
$_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")) {
session_cache_limiter(""); // to allow restarting session
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();
}
@@ -66,45 +69,50 @@ if (function_exists("get_magic_quotes_runtime") && get_magic_quotes_runtime()) {
set_magic_quotes_runtime(false);
}
@set_time_limit(0); // @ - can be disabled
@ini_set("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/lang/" . LANG . ".inc.php";
include "../adminer/include/db.inc.php";
include "../adminer/lang/$LANG.inc.php";
include "../adminer/include/pdo.inc.php";
include "../adminer/include/driver.inc.php";
include "../adminer/drivers/sqlite.inc.php";
include "../adminer/drivers/pgsql.inc.php";
include "../adminer/drivers/oracle.inc.php";
include "../adminer/drivers/mssql.inc.php";
include "../adminer/drivers/mongo.inc.php";
include "./include/adminer.inc.php";
include "../adminer/include/plugins.inc.php";
include "../adminer/include/plugin.inc.php";
Adminer::$instance =
(function_exists('adminer_object') ? adminer_object() :
(is_dir("adminer-plugins") || file_exists("adminer-plugins.php") ? new Plugins(null) :
new Adminer
));
// this is matched by compile.php
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver
define('Adminer\JUSH', Driver::$jush);
define('Adminer\SERVER', $_GET[DRIVER]); // read from pgsql=localhost, '' means default server, null means no server
define('Adminer\DB', $_GET["db"]); // for the sake of speed and size
define(
'Adminer\ME',
preg_replace('~\?.*~', '', relative_uri()) . '?'
. (sid() ? SID . '&' : '')
. (SERVER !== null ? DRIVER . "=" . urlencode(SERVER) . '&' : '')
. ($_GET["ext"] ? "ext=" . urlencode($_GET["ext"]) . '&' : '')
. (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '')
. (DB != "" ? 'db=' . urlencode(DB) . '&' . (isset($_GET["ns"]) ? "ns=" . urlencode($_GET["ns"]) . "&" : "") : '')
$config = driver_config();
$possible_drivers = $config['possible_drivers'];
$jush = $config['jush'];
$types = $config['types'];
$structured_types = $config['structured_types'];
$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 . '&' : '')
. (SERVER !== null ? DRIVER . "=" . urlencode(SERVER) . '&' : '')
. (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '')
. (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/xxtea.inc.php";
include "../adminer/include/auth.inc.php";
include "./include/editing.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,5 +1,77 @@
<?php
namespace Adminer;
function connect_error() {
global $adminer, $connection, $token, $error, $drivers;
if (DB != "") {
header("HTTP/1.1 404 Not Found");
page_header(lang('Database') . ": " . h(DB), lang('Invalid database.'), true);
} else {
if ($_POST["db"] && !$error) {
queries_redirect(substr(ME, 0, -1), lang('Databases have been dropped.'), drop_databases($_POST["db"]));
}
page_header(lang('Select database'), $error, false);
echo "<p class='links'>\n";
foreach (array(
'database' => lang('Create database'),
'privileges' => lang('Privileges'),
'processlist' => lang('Process list'),
'variables' => lang('Variables'),
'status' => lang('Status'),
) as $key => $val) {
if (support($key)) {
echo "<a href='" . h(ME) . "$key='>$val</a>\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";
$databases = $adminer->databases();
if ($databases) {
$scheme = support("scheme");
$collations = collations();
echo "<form action='' method='post'>\n";
echo "<table cellspacing='0' class='checkable'>\n";
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
echo "<thead><tr>"
. (support("database") ? "<td>" : "")
. "<th>" . lang('Database') . " - <a href='" . h(ME) . "refresh=1'>" . lang('Refresh') . "</a>"
. "<td>" . lang('Collation')
. "<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');", "")
. "</thead>\n"
;
$databases = ($_GET["dbsize"] ? count_tables($databases) : array_flip($databases));
foreach ($databases as $db => $tables) {
$root = h(ME) . "db=" . urlencode($db);
$id = h("Db-" . $db);
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>";
$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 align='right'><a href='$root&amp;schema=' id='tables-" . h($db) . "' title='" . lang('Database schema') . "'>" . ($_GET["dbsize"] ? $tables : "?") . "</a>";
echo "<td align='right' id='size-" . h($db) . "'>" . ($_GET["dbsize"] ? db_size($db) : "?");
echo "\n";
}
echo "</table>\n";
echo (support("database")
? "<div class='footer'><div>\n"
. "<fieldset><legend>" . lang('Selected') . " <span id='selected'></span></legend><div>\n"
. "<input type='hidden' name='all' value=''>" . script("qsl('input').onclick = function () { selectCount('selected', formChecked(this, /^db/)); };") // used by trCheck()
. "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm() . "\n"
. "</div></fieldset>\n"
. "</div></div>\n"
: ""
);
echo "<input type='hidden' name='token' value='$token'>\n";
echo "</form>\n";
echo script("tableCheck();");
}
}
page_footer("db");
}
if (isset($_GET["status"])) {
$_GET["variables"] = $_GET["status"];
@@ -8,100 +80,12 @@ if (isset($_GET["import"])) {
$_GET["sql"] = $_GET["import"];
}
if (
!(DB != ""
? connection()->select_db(DB)
: isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]) || isset($_GET["variables"])
|| $_GET["script"] == "connect" || $_GET["script"] == "kill"
)
) {
if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]) || isset($_GET["variables"]) || $_GET["script"] == "connect" || $_GET["script"] == "kill")) {
if (DB != "" || $_GET["refresh"]) {
restart_session();
set_session("dbs", null);
}
if (DB != "") {
header("HTTP/1.1 404 Not Found");
page_header(lang('Database') . ": " . h(DB), lang('Invalid database.'), true);
} else {
if ($_POST["db"] && !$error) {
queries_redirect(substr(ME, 0, -1), lang('Databases have been dropped.'), drop_databases($_POST["db"]));
}
page_header(lang('Select database'), $error, false);
echo "<p class='links'>\n";
foreach (
array(
'database' => lang('Create database'),
'privileges' => lang('Privileges'),
'processlist' => lang('Process list'),
'variables' => lang('Variables'),
'status' => lang('Status'),
) as $key => $val
) {
if (support($key)) {
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('Logged as: %s', "<b>" . h(logged_user()) . "</b>") . "\n";
$databases = adminer()->databases();
if ($databases) {
$scheme = support("scheme");
$collations = collations();
echo "<form action='' method='post'>\n";
echo "<table class='checkable odds'>\n";
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
echo "<thead><tr>"
. (support("database") ? "<td>" : "")
. "<th>" . lang('Database') . (get_session("dbs") !== null ? " - <a href='" . h(ME) . "refresh=1'>" . lang('Refresh') . "</a>" : "")
. "<td>" . lang('Collation')
. "<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');", "")
. "</thead>\n"
;
$databases = ($_GET["dbsize"] ? count_tables($databases) : array_flip($databases));
foreach ($databases as $db => $tables) {
$root = h(ME) . "db=" . urlencode($db);
$id = h("Db-" . $db);
echo "<tr>" . (support("database") ? "<td>" . checkbox("db[]", $db, in_array($db, (array) $_POST["db"]), "", "", "", $id) : "");
echo "<th><a href='$root' id='$id'>" . h($db) . "</a>";
$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 align='right'><a href='$root&amp;schema=' id='tables-" . h($db) . "' title='" . lang('Database schema') . "'>" . ($_GET["dbsize"] ? $tables : "?") . "</a>";
echo "<td align='right' id='size-" . h($db) . "'>" . ($_GET["dbsize"] ? db_size($db) : "?");
echo "\n";
}
echo "</table>\n";
echo (support("database")
? "<div class='footer'><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='submit' name='drop' value='" . lang('Drop') . "'>" . confirm() . "\n"
. "</div></fieldset>\n"
. "</div></div>\n"
: ""
);
echo input_token();
echo "</form>\n";
echo script("tableCheck();");
}
if (isset(adminer()->plugins) && is_array(adminer()->plugins)) {
echo "<div class='plugins'>\n";
echo "<h3>" . lang('Loaded plugins') . "</h3>\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";
echo "</div>\n";
}
}
page_footer("db");
connect_error(); // separate function to catch SQLite error
exit;
}

View File

@@ -1,14 +1,12 @@
<?php
namespace Adminer;
// coverage is used in tests and removed in compilation
if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer.coverage")) {
function save_coverage(): void {
$coverage_filename = sys_get_temp_dir() . "/adminer.coverage";
if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer_coverage.ser")) {
function save_coverage() {
$coverage_filename = sys_get_temp_dir() . "/adminer_coverage.ser";
$coverage = unserialize(file_get_contents($coverage_filename));
foreach (xdebug_get_code_coverage() as $filename => $lines) {
foreach ($lines as $l => $val) {
if (!idx($coverage[$filename], $l) || $val > 0) {
if (!$coverage[$filename][$l] || $val > 0) {
$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);
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;
/** @var string */ public $extension; // extension name
/** @var string */ public $flavor = ''; // different vendor with the same API, e.g. MariaDB; usually stays empty
/** @var string */ public $server_info; // server version
/** @var int */ public $affected_rows = 0; // number of affected rows
/** @var string */ public $info = ''; // see https://php.net/mysql_info
/** @var int */ public $errno = 0; // last error code
/** @var string */ public $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
namespace Adminer;
/** Print HTML header
* @param string $title 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 $title2 used after colon in title and heading, should be HTML escaped
* @param string used in title, breadcrumb and heading, should be HTML escaped
* @param string
* @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();
if (is_ajax() && $error) {
page_messages($error);
exit;
}
if (!ob_get_level()) {
ob_start('ob_gzhandler', 4096);
}
$title_all = $title . ($title2 != "" ? ": $title2" : "");
$title_page = strip_tags($title_all . (SERVER != "" && SERVER != "localhost" ? h(" - " . SERVER) : "") . " - " . adminer()->name());
// initial-scale=1 is the default but Chrome 134 on iOS is not able to zoom out without it
$title_page = strip_tags($title_all . (SERVER != "" && SERVER != "localhost" ? h(" - " . SERVER) : "") . " - " . $adminer->name());
?>
<!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 name="robots" content="noindex">
<meta name="viewport" content="width=device-width,initial-scale=1">
<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
$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='icon' href='data:image/gif;base64,R0lGODlhEAAQAJEAAAQCBPz+/PwCBAROZCH5BAEAAAAALAAAAAAQABAAAAI2hI+pGO1rmghihiUdvUBnZ3XBQA7f05mOak1RWXrNq5nQWHMKvuoJ37BhVEEfYxQzHjWQ5qIAADs='>\n";
echo "<link rel='apple-touch-icon' href='../adminer/static/logo.png'>\n";
}
foreach ($css as $val) {
echo "<link rel='stylesheet'" . (preg_match('~-dark\.~', $val) && !$dark ? $media : "") . " href='" . h($val) . "'>\n";
}
echo "\n<body class='" . lang('ltr') . " nojs'>\n";
$filename = get_temp_dir() . "/adminer.version";
if (!$_COOKIE["adminer_version"] && function_exists('openssl_verify') && file_exists($filename) && filemtime($filename) + 86400 > time()) { // 86400 - 1 day in seconds
$version = unserialize(file_get_contents($filename));
@@ -75,38 +51,42 @@ fQIDAQAB
$_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() . "')")
. "});
document.body.classList.replace('nojs', 'js');
const offlineMessage = '" . js_escape(lang('You are offline.')) . "';
const thousandsSeparator = '" . js_escape(lang(',')) . "';")
;
echo "<div id='help' class='jush-" . JUSH . " jsonly hidden'></div>\n";
echo script("mixin(qs('#help'), {onmouseover: () => { helpOpen = 1; }, onmouseout: helpMouseout});");
echo "<div id='content'>\n";
echo "<span id='menuopen' class='jsonly'>" . icon("move", "", "menu", "") . "</span>" . script("qs('#menuopen').onclick = event => { qs('#foot').classList.toggle('foot'); event.stopPropagation(); }");
?>
<script<?php echo nonce(); ?>>
mixin(document.body, {onkeydown: bodyKeydown, onclick: bodyClick<?php
echo (isset($_COOKIE["adminer_version"]) ? "" : ", onload: partial(verifyVersion, '$VERSION', '" . js_escape(ME) . "', '" . get_token() . "')"); // $token may be empty in auth.inc.php
?>});
document.body.className = document.body.className.replace(/ nojs/, ' js');
var offlineMessage = '<?php echo js_escape(lang('You are offline.')); ?>';
var thousandsSeparator = '<?php echo js_escape(lang(',')); ?>';
</script>
<div id="help" class="jush-<?php echo $jush; ?> jsonly hidden"></div>
<?php echo script("mixin(qs('#help'), {onmouseover: function () { helpOpen = 1; }, onmouseout: helpMouseout});"); ?>
<div id="content">
<?php
if ($breadcrumb !== null) {
$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);
$server = adminer()->serverName(SERVER);
$server = $adminer->serverName(SERVER);
$server = ($server != "" ? $server : lang('Server'));
if ($breadcrumb === false) {
echo "$server\n";
} 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))) {
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 ($_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) {
$desc = (is_array($val) ? $val[1] : h($val));
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;
}
stop_session();
define('Adminer\PAGE_HEADER', 1);
define("PAGE_HEADER", 1);
}
/** Send HTTP headers */
function page_headers(): void {
/** Send HTTP headers
* @return null
*/
function page_headers() {
global $adminer;
header("Content-Type: text/html; charset=utf-8");
header("Cache-Control: no-cache");
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-Content-Type-Options: nosniff");
header("Referrer-Policy: origin-when-cross-origin");
foreach (adminer()->csp(csp()) as $csp) {
foreach ($adminer->csp() as $csp) {
$header = array();
foreach ($csp as $key => $val) {
$header[] = "$key $val";
}
header("Content-Security-Policy: " . implode("; ", $header));
}
adminer()->headers();
$adminer->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(
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-'
@@ -162,7 +145,7 @@ function csp(): array {
/** Get a CSP nonce
* @return string Base64 value
*/
function get_nonce(): string {
function get_nonce() {
static $nonce;
if (!$nonce) {
$nonce = base64_encode(rand_string());
@@ -170,10 +153,13 @@ function get_nonce(): string {
return $nonce;
}
/** Print flash and error messages */
function page_messages(string $error): void {
/** Print flash and error messages
* @param string
* @return null
*/
function page_messages($error) {
$uri = preg_replace('~^[^?]*~', '', $_SERVER["REQUEST_URI"]);
$messages = idx($_SESSION["messages"], $uri);
$messages = $_SESSION["messages"][$uri];
if ($messages) {
echo "<div class='message'>" . implode("</div>\n<div class='message'>", $messages) . "</div>" . script("messagesPrint();");
unset($_SESSION["messages"][$uri]);
@@ -181,28 +167,29 @@ function page_messages(string $error): void {
if ($error) {
echo "<div class='error'>$error</div>\n";
}
if (adminer()->error) { // separate <div>
echo "<div class='error'>" . adminer()->error . "</div>\n";
}
}
/** Print HTML footer
* @param ''|'auth'|'db'|'ns' $missing
* @param string "auth", "db", "ns"
* @return null
*/
function page_footer(string $missing = ""): void {
echo "</div>\n\n<div id='foot' class='foot'>\n<div id='menu'>\n";
adminer()->navigation($missing);
echo "</div>\n";
if ($missing != "auth") {
?>
function page_footer($missing = "") {
global $adminer, $token;
?>
</div>
<?php switch_lang(); ?>
<?php if ($missing != "auth") { ?>
<form action="" method="post">
<p class="logout">
<span><?php echo h($_GET["username"]) . "\n"; ?></span>
<input type="submit" name="logout" value="<?php echo lang('Logout'); ?>" id="logout">
<?php echo input_token(); ?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</p>
</form>
<?php } ?>
<div id="menu">
<?php $adminer->navigation($missing); ?>
</div>
<?php
}
echo "</div>\n\n";
echo script("setupSubmitHighlight(document);");
}

View File

@@ -1,123 +1,87 @@
<?php
namespace Adminer;
$drivers = array();
/** Add or overwrite a driver */
function add_driver(string $id, string $name): void {
SqlDriver::$drivers[$id] = $name;
/** Add a driver
* @param string
* @param string
* @return null
*/
function add_driver($id, $name) {
global $drivers;
$drivers[$id] = $name;
}
/** Get driver name */
function get_driver(string $id): string {
return SqlDriver::$drivers[$id];
/** Get driver name
* @param string
* @return string
*/
function get_driver($id) {
global $drivers;
return $drivers[$id];
}
abstract class SqlDriver {
/** @var Driver */ static $instance;
/** @var string[] */ static $drivers = array(); // all available drivers
/** @var list<string> */ static $extensions = array(); // possible extensions in the current driver
/** @var string */ static $jush; // JUSH identifier
/*abstract*/ class Min_SQL {
var $_conn;
/** @var Db */ protected $conn;
/** @var int[][] */ protected $types = array(); // [$group => [$type => $maximum_unsigned_length, ...], ...]
/** @var string[] */ public $insertFunctions = array(); // ["$type|$type2" => "$function/$function2"] functions used in edit and insert
/** @var string[] */ public $editFunctions = array(); // ["$type|$type2" => "$function/$function2"] functions used in edit only
/** @var list<string> */ public $unsigned = array(); // number variants
/** @var list<string> */ public $operators = array(); // operators used in select
/** @var list<string> */ public $functions = array(); // functions used in select
/** @var list<string> */ public $grouping = array(); // grouping functions used in select
/** @var string */ public $onActions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; // used in foreign_keys()
/** @var string */ public $inout = "IN|OUT|INOUT"; // used in routines
/** @var string */ public $enumLength = "'(?:''|[^'\\\\]|\\\\.)*'"; // regular expression for parsing enum lengths
/** @var list<string> */ public $generated = array(); // allowed types of generated columns
/** Connect to the database
* @return Db|string string for error
/** Create object for performing database operations
* @param Min_DB
*/
static function connect(?string $server, string $username, string $password) {
$connection = new Db;
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) {
function __construct($connection) {
$this->_conn = $connection;
}
/** Select data from table
* @param list<string> $select result of adminer()->selectColumnsProcess()[0]
* @param list<string> $where result of adminer()->selectSearchProcess()
* @param list<string> $group result of adminer()->selectColumnsProcess()[1]
* @param list<string> $order result of adminer()->selectOrderProcess()
* @param int $limit result of adminer()->selectLimitProcess()
* @param int $page index of page starting at zero
* @param bool $print whether to print the query
* @return Result|false
* @param string
* @param array result of $adminer->selectColumnsProcess()[0]
* @param array result of $adminer->selectSearchProcess()
* @param array result of $adminer->selectColumnsProcess()[1]
* @param array result of $adminer->selectOrderProcess()
* @param int result of $adminer->selectLimitProcess()
* @param int index of page starting at zero
* @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));
$query = adminer()->selectQueryBuild($select, $where, $group, $order, $limit, $page);
$query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page);
if (!$query) {
$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) : ""),
$limit,
($limit != "" ? +$limit : null),
($page ? $limit * $page : 0),
"\n"
);
}
$start = microtime(true);
$return = $this->conn->query($query);
$return = $this->_conn->query($query);
if ($print) {
echo adminer()->selectQuery($query, $start, !$return);
echo $adminer->selectQuery($query, $start, !$return);
}
return $return;
}
/** Delete data from table
* @param string $queryWhere " WHERE ..."
* @param int $limit 0 or 1
* @return Result|bool
* @param string
* @param string " WHERE ..."
* @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);
return queries("DELETE" . ($limit ? limit1($table, $query, $queryWhere) : " $query$queryWhere"));
}
/** Update data in table
* @param string[] $set escaped columns in keys, quoted data in values
* @param string $queryWhere " WHERE ..."
* @param int $limit 0 or 1
* @return Result|bool
* @param string
* @param array escaped columns in keys, quoted data in values
* @param string " WHERE ..."
* @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();
foreach ($set as $key => $val) {
$values[] = "$key = $val";
@@ -127,143 +91,106 @@ abstract class SqlDriver {
}
/** Insert data into table
* @param string[] $set escaped columns in keys, quoted data in values
* @return Result|bool
* @param string
* @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
? " (" . implode(", ", array_keys($set)) . ")\nVALUES (" . implode(", ", $set) . ")"
: " 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
* @param list<string[]> $rows of arrays with escaped columns in keys and quoted data in values
* @param int[] $primary column names in keys
* @return Result|bool
* @param string
* @param array
* @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;
}
/** Begin transaction
* @return Result|bool
* @return bool
*/
function begin() {
return queries("BEGIN");
}
/** Commit transaction
* @return Result|bool
* @return bool
*/
function commit() {
return queries("COMMIT");
}
/** Rollback transaction
* @return Result|bool
* @return bool
*/
function rollback() {
return queries("ROLLBACK");
}
/** Return query with a timeout
* @param int $timeout seconds
* @return string|void null if the driver doesn't support query timeouts
* @param string
* @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
* @param string $idf escaped column name
* @param array{op:string, val:string} $val
* @param Field $field
* @param string escaped column name
* @param array array("op" => , "val" => )
* @param array
* @return string
*/
function convertSearch(string $idf, array $val, array $field): string {
function convertSearch($idf, array $where, array $field) {
return $idf;
}
/** Convert operator so it can be used in search */
function convertOperator(string $operator): string {
/** Convert operator so it can be used in search
* @param string $operator
* @return string
*/
function convertOperator($operator) {
return $operator;
}
/** Convert value returned by database to actual value
* @param Field $field
* @param string
* @param array
* @return string
*/
function value(?string $val, array $field): ?string {
return (method_exists($this->conn, 'value')
? $this->conn->value($val, $field)
function value($val, $field) {
return (method_exists($this->_conn, 'value')
? $this->_conn->value($val, $field)
: (is_resource($val) ? stream_get_contents($val) : $val)
);
}
/** Quote binary string */
function quoteBinary(string $s): string {
/** Quote binary string
* @param string
* @return string
*/
function quoteBinary($s) {
return q($s);
}
/** Get warnings about the last command
* @return string|void HTML
* @return string HTML
*/
function warnings() {
return '';
}
/** 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
namespace Adminer;
// This file is not used in Adminer Editor.
/** Print select result
* @param Result $result
* @param string[] $orgtables
* @param int|numeric-string $limit
* @return string[] $orgtables
* @param Min_Result
* @param Min_DB connection to examine indexes
* @param array
* @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
$indexes = array(); // orgtable => array(column => colno) - primary keys
$columns = array(); // orgtable => array(column => ) - not selected columns in primary key
$blobs = array(); // colno => bool - display bytes for blobs
$types = array(); // colno => type - display char in <code>
$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++) {
if (!$i) {
echo "<div class='scrollable'>\n";
echo "<table class='nowrap odds'>\n";
echo "<table cellspacing='0' class='nowrap'>\n";
echo "<thead><tr>";
for ($j=0; $j < count($row); $j++) {
$field = $result->fetch_field();
$name = $field->name;
$orgtable = (isset($field->orgtable) ? $field->orgtable : "");
$orgname = (isset($field->orgname) ? $field->orgname : $name);
if ($orgtables && JUSH == "sql") { // MySQL EXPLAIN
$field = (array)$result->fetch_field();
$name = $field["name"];
$orgtable = $field["orgtable"];
$orgname = $field["orgname"];
$return[$field["table"]] = $orgtable;
if ($orgtables && $jush == "sql") { // MySQL EXPLAIN
$links[$j] = ($name == "table" ? "table=" : ($name == "possible_keys" ? "indexes=" : null));
} elseif ($orgtable != "") {
if (isset($field->table)) {
$return[$field->table] = $orgtable;
}
if (!isset($indexes[$orgtable])) {
// find primary key in each table
$indexes[$orgtable] = array();
@@ -49,11 +46,11 @@ function print_select_result($result, ?Db $connection2 = null, array $orgtables
$links[$j] = $orgtable;
}
}
if ($field->charsetnr == 63) { // 63 - binary
if ($field["charsetnr"] == 63) { // 63 - binary
$blobs[$j] = true;
}
$types[$j] = $field->type;
echo "<th" . ($orgtable != "" || $field->name != $orgname ? " title='" . h(($orgtable != "" ? "$orgtable." : "") . $orgname) . "'" : "") . ">" . h($name)
$types[$j] = $field["type"];
echo "<th" . ($orgtable != "" || $field["name"] != $orgname ? " title='" . h(($orgtable != "" ? "$orgtable." : "") . $orgname) . "'" : "") . ">" . h($name)
. ($orgtables ? doc_link(array(
'sql' => "explain-output.html#explain_" . strtolower($name),
'mariadb' => "explain/#the-columns-in-explain-select",
@@ -62,11 +59,11 @@ function print_select_result($result, ?Db $connection2 = null, array $orgtables
}
echo "</thead>\n";
}
echo "<tr>";
echo "<tr" . odd() . ">";
foreach ($row as $key => $val) {
$link = "";
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)];
$link = ME . $links[$key] . urlencode($orgtables[$table] != "" ? $orgtables[$table] : $table);
} else {
@@ -75,7 +72,7 @@ function print_select_result($result, ?Db $connection2 = null, array $orgtables
$link .= "&where" . urlencode("[" . bracket_escape($col) . "]") . "=" . urlencode($row[$j]);
}
}
} elseif (is_url($val)) {
} elseif (is_web_url($val)) {
$link = $val;
}
if ($val === null) {
@@ -89,10 +86,9 @@ function print_select_result($result, ?Db $connection2 = null, array $orgtables
}
}
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" . ($types[$key] <= 9 || $types[$key] == 246 ? " class='number'" : "") . ">$val";
echo "<td>$val";
}
}
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
* @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
foreach (table_status('', true) as $table_name => $table) {
if ($table_name != $self && fk_support($table)) {
@@ -120,11 +117,41 @@ function referencable_primary(string $self): array {
return $return;
}
/** Print SQL <textarea> tag
* @param string|list<array{string}> $value
/** Get settings stored in a cookie
* @return array
*/
function textarea(string $name, $value, int $rows = 10, int $cols = 80): void {
echo "<textarea name='" . h($name) . "' rows='$rows' cols='$cols' class='sqlarea jush-" . JUSH . "' spellcheck='false' wrap='off'>";
function adminer_settings() {
parse_str($_COOKIE["adminer_settings"], $settings);
return $settings;
}
/** Get setting stored in a cookie
* @param string
* @return array
*/
function adminer_setting($key) {
$settings = adminer_settings();
return $settings[$key];
}
/** Store settings to a cookie
* @param array
* @return bool
*/
function set_adminer_settings($settings) {
return cookie("adminer_settings", http_build_query($settings + adminer_settings()));
}
/** Print SQL <textarea> tag
* @param string
* @param string or array in which case [0] of every element is used
* @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)) {
foreach ($value as $val) { // not implode() to save memory
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>";
}
/** 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
* @param Field $field
* @param list<string> $collations
* @param string[] $foreign_keys
* @param list<string> $extra_types extra types to prepend
* @param string
* @param array
* @param array
* @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"];
echo "<td><select name='" . h($key) . "[type]' class='type' aria-labelledby='label-type'>";
if ($type && !array_key_exists($type, driver()->types()) && !isset($foreign_keys[$type]) && !in_array($type, $extra_types)) {
$extra_types[] = $type;
}
$structured_types = driver()->structuredTypes();
if ($foreign_keys) {
$structured_types[lang('Foreign keys')] = $foreign_keys;
}
echo optionlist(array_merge($extra_types, $structured_types), $type);
echo "</select><td>";
echo "<input name='" . h($key) . "[length]' value='" . h($field["length"]) . "' size='3'"
. (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : "") //! type="number" with enabled JavaScript
. " aria-labelledby='label-length'>";
echo "<td class='options'>";
echo ($collations
? "<input list='collations' name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . " value='" . h($field["collation"]) . "' placeholder='(" . lang('collation') . ")'>"
: ''
);
echo (driver()->unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist(driver()->unsigned, $field["unsigned"]) . '</select>' : '');
echo (isset($field['on_update']) ? "<select name='" . h($key) . "[on_update]'" . (preg_match('~timestamp|datetime~', $type) ? "" : " class='hidden'") . '>'
. optionlist(array("" => "(" . lang('ON UPDATE') . ")", "CURRENT_TIMESTAMP"), (preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"]) ? "CURRENT_TIMESTAMP" : $field["on_update"]))
. '</select>' : ''
);
echo ($foreign_keys
? "<select name='" . h($key) . "[on_delete]'" . (preg_match("~`~", $type) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", driver()->onActions), $field["on_delete"]) . "</select> "
: " " // space for IE
);
?>
<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;
}
if ($foreign_keys) {
$structured_types[lang('Foreign keys')] = $foreign_keys;
}
echo optionlist(array_merge($extra_types, $structured_types), $type);
?></select><td><input name="<?php echo h($key); ?>[length]" value="<?php echo h($field["length"]); ?>" size="3"<?php echo (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : ""); //! type="number" with enabled JavaScript ?> aria-labelledby="label-length"><td class="options"><?php
echo "<select name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>';
echo ($unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist($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("|", $on_actions), $field["on_delete"]) . "</select> " : " "); // space for IE
}
/** Get partition info
* @return array{partition_by:string, partition:string, partitions:string, partition_names:list<string>, partition_values:list<string>}
/** Filter length value including enums
* @param string
* @return string
*/
function get_partitions_info(string $table): array {
$from = "FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = " . q(DB) . " AND TABLE_NAME = " . q($table);
$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;
function process_length($length) {
global $enum_length;
return (preg_match("~^\\s*\\(?\\s*$enum_length(?:\\s*,\\s*$enum_length)*+\\s*\\)?\\s*\$~", $length) && preg_match_all("~$enum_length~", $length, $matches)
? "(" . implode(",", $matches[0]) . ")"
: 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
* @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]"
. process_length($field["length"])
. (preg_match(number_type(), $field["type"]) && in_array($field["unsigned"], driver()->unsigned) ? " $field[unsigned]" : "")
. (preg_match('~char|text|enum|set~', $field["type"]) && $field["collation"] ? " $collate " . (JUSH == "mssql" ? $field["collation"] : q($field["collation"])) : "")
. (preg_match(number_type(), $field["type"]) && in_array($field["unsigned"], $unsigned) ? " $field[unsigned]" : "")
. (preg_match('~char|text|enum|set~', $field["type"]) && $field["collation"] ? " $collate " . q($field["collation"]) : "")
;
}
/** Create SQL string from field
* @param Field $field basic field information
* @param Field $type_field information about field type
* @return list<string> ["field", "type", "NULL", "DEFAULT", "ON UPDATE", "COMMENT", "AUTO_INCREMENT"]
* @param array basic field information
* @param array information about field type
* @return array array("field", "type", "NULL", "DEFAULT", "ON UPDATE", "COMMENT", "AUTO_INCREMENT")
*/
function process_field(array $field, array $type_field): array {
// MariaDB exports CURRENT_TIMESTAMP as a function.
if ($field["on_update"]) {
$field["on_update"] = str_ireplace("current_timestamp()", "CURRENT_TIMESTAMP", $field["on_update"]);
}
function process_field($field, $type_field) {
return array(
idf_escape(trim($field["field"])),
process_type($type_field),
@@ -257,32 +233,33 @@ function process_field(array $field, array $type_field): array {
}
/** Get default value clause
* @param Field $field
* @param array
* @return string
*/
function default_value(array $field): string {
function default_value($field) {
$default = $field["default"];
$generated = $field["generated"];
return ($default === null ? "" : (in_array($generated, driver()->generated)
? (JUSH == "mssql" ? " AS ($default)" . ($generated == "VIRTUAL" ? "" : " $generated") . "" : " GENERATED ALWAYS AS ($default) $generated")
: " DEFAULT " . (!preg_match('~^GENERATED ~i', $default) && (preg_match('~char|binary|text|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))
)
));
if ($default === null) return "";
if (preg_match('~^GENERATED ~i', $default)) {
return " $default";
}
$quote = preg_match('~char|binary|text|enum|set~', $field["type"]) || preg_match('~^(?![a-z])~i', $default);
return " DEFAULT " . ($quote ? q($default) : $default);
}
/** Get type class to use in CSS
* @return string|void class=''
* @param string
* @return string class=''
*/
function type_class(string $type) {
foreach (
array(
'char' => 'text',
'date' => 'time|year',
'binary' => 'blob',
'enum' => 'set',
) as $key => $val
) {
function type_class($type) {
foreach (array(
'char' => 'text',
'date' => 'time|year',
'binary' => 'blob',
'enum' => 'set',
) as $key => $val) {
if (preg_match("~$key|$val~", $type)) {
return " class='$key'";
}
@@ -290,72 +267,71 @@ function type_class(string $type) {
}
/** Print table interior for fields editing
* @param (Field|RoutineField)[] $fields
* @param list<string> $collations
* @param 'TABLE'|'PROCEDURE' $type
* @param string[] $foreign_keys
* @param array
* @param array
* @param string TABLE or PROCEDURE
* @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);
$default_class = (($_POST ? $_POST["defaults"] : get_setting("defaults")) ? "" : " class='hidden'");
$comment_class = (($_POST ? $_POST["comments"] : get_setting("comments")) ? "" : " class='hidden'");
echo "<thead><tr>\n";
echo ($type == "PROCEDURE" ? "<td>" : "");
echo "<th id='label-name'>" . ($type == "TABLE" ? lang('Column name') : lang('Parameter name'));
echo "<td id='label-type'>" . lang('Type') . "<textarea id='enum-edit' rows='4' cols='12' wrap='off' style='display: none;'></textarea>" . script("qs('#enum-edit').onblur = editingLengthBlur;");
echo "<td id='label-length'>" . lang('Length');
echo "<td>" . lang('Options'); // no label required, options have their own label
if ($type == "TABLE") {
echo "<td id='label-null'>NULL\n";
echo "<td><input type='radio' name='auto_increment_col' value=''><abbr id='label-ai' title='" . lang('Auto Increment') . "'>AI</abbr>";
echo doc_link(array(
'sql' => "example-auto-increment.html",
'mariadb' => "auto_increment/",
'sqlite' => "autoinc.html",
'pgsql' => "datatype-numeric.html#DATATYPE-SERIAL",
'mssql' => "t-sql/statements/create-table-transact-sql-identity-property",
));
echo "<td id='label-default'$default_class>" . lang('Default value');
echo (support("comment") ? "<td id='label-comment'$comment_class>" . lang('Comment') : "");
}
echo "<td>" . icon("plus", "add[" . (support("move_col") ? 0 : count($fields)) . "]", "+", lang('Add next'));
echo "</thead>\n<tbody>\n";
$default_class = (($_POST ? $_POST["defaults"] : adminer_setting("defaults")) ? "" : " class='hidden'");
$comment_class = (($_POST ? $_POST["comments"] : adminer_setting("comments")) ? "" : " class='hidden'");
?>
<thead><tr>
<?php if ($type == "PROCEDURE") { ?><td><?php } ?>
<th id="label-name"><?php echo ($type == "TABLE" ? lang('Column name') : lang('Parameter name')); ?>
<td id="label-type"><?php echo lang('Type'); ?><textarea id="enum-edit" rows="4" cols="12" wrap="off" style="display: none;"></textarea><?php echo script("qs('#enum-edit').onblur = editingLengthBlur;"); ?>
<td id="label-length"><?php echo lang('Length'); ?>
<td><?php echo lang('Options'); /* no label required, options have their own label */ ?>
<?php if ($type == "TABLE") { ?>
<td id="label-null">NULL
<td><input type="radio" name="auto_increment_col" value=""><abbr id="label-ai" title="<?php echo lang('Auto Increment'); ?>">AI</abbr><?php echo doc_link(array(
'sql' => "example-auto-increment.html",
'mariadb' => "auto_increment/",
'sqlite' => "autoinc.html",
'pgsql' => "datatype-numeric.html#DATATYPE-SERIAL",
'mssql' => "ms186775.aspx",
)); ?>
<td id="label-default"<?php echo $default_class; ?>><?php echo lang('Default value'); ?>
<?php echo (support("comment") ? "<td id='label-comment'$comment_class>" . lang('Comment') : ""); ?>
<?php } ?>
<td><?php echo "<input type='image' class='icon' name='add[" . (support("move_col") ? 0 : count($fields)) . "]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>" . script("row_count = " . count($fields) . ";"); ?>
</thead>
<tbody>
<?php
echo script("mixin(qsl('tbody'), {onclick: editingClick, onkeydown: editingKeydown, oninput: editingInput});");
foreach ($fields as $i => $field) {
$i++;
$orig = $field[($_POST ? "orig" : "field")];
$display = (isset($_POST["add"][$i-1]) || (isset($field["field"]) && !idx($_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>";
if ($display) {
echo "<input name='fields[$i][field]' value='" . h($field["field"]) . "' data-maxlength='64' autocapitalize='off' aria-labelledby='label-name'>";
}
echo input_hidden("fields[$i][orig]", $orig);
edit_type("fields[$i]", $field, $collations, $foreign_keys);
if ($type == "TABLE") {
echo "<td>" . checkbox("fields[$i][null]", 1, $field["null"], "", "", "block", "label-null");
echo "<td><label class='block'><input type='radio' name='auto_increment_col' value='$i'" . ($field["auto_increment"] ? " checked" : "") . " aria-labelledby='label-ai'></label>";
echo "<td$default_class>" . (driver()->generated
? html_select("fields[$i][generated]", array_merge(array("", "DEFAULT"), driver()->generated), $field["generated"]) . " "
: checkbox("fields[$i][generated]", 1, $field["generated"], "", "", "", "label-default")
);
echo "<input name='fields[$i][default]' value='" . h($field["default"]) . "' aria-labelledby='label-default'>";
$display = (isset($_POST["add"][$i-1]) || (isset($field["field"]) && !$_POST["drop_col"][$i])) && (support("drop_col") || $orig == "");
?>
<tr<?php echo ($display ? "" : " style='display: none;'"); ?>>
<?php echo ($type == "PROCEDURE" ? "<td>" . html_select("fields[$i][inout]", explode("|", $inout), $field["inout"]) : ""); ?>
<th><?php if ($display) { ?><input name="fields[<?php echo $i; ?>][field]" value="<?php echo h($field["field"]); ?>" data-maxlength="64" autocapitalize="off" aria-labelledby="label-name"><?php } ?>
<input type="hidden" name="fields[<?php echo $i; ?>][orig]" value="<?php echo h($orig); ?>"><?php edit_type("fields[$i]", $field, $collations, $foreign_keys); ?>
<?php if ($type == "TABLE") { ?>
<td><?php echo checkbox("fields[$i][null]", 1, $field["null"], "", "", "block", "label-null"); ?>
<td><label class="block"><input type="radio" name="auto_increment_col" value="<?php echo $i; ?>"<?php if ($field["auto_increment"]) { ?> checked<?php } ?> aria-labelledby="label-ai"></label><td<?php echo $default_class; ?>><?php
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 (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 (support("move_col") ?
icon("plus", "add[$i]", "+", lang('Add next')) . " "
. icon("up", "up[$i]", "", lang('Move up')) . " "
. icon("down", "down[$i]", "", lang('Move down')) . " "
"<input type='image' class='icon' name='add[$i]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'> "
. "<input type='image' class='icon' name='up[$i]' src='../adminer/static/up.gif' alt='↑' title='" . lang('Move up') . "'> "
. "<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
* @param Field[] $fields
* @param array
* @return bool
*/
function process_fields(array &$fields): bool {
function process_fields(&$fields) {
$offset = 0;
if ($_POST["up"]) {
$last = 0;
@@ -393,19 +369,21 @@ function process_fields(array &$fields): bool {
}
/** Callback used in routine()
* @param list<string> $match
* @param array
* @return string
*/
function normalize_enum(array $match): string {
$val = $match[0];
return "'" . str_replace("'", "''", addcslashes(stripcslashes(str_replace($val[0] . $val[0], $val[0], substr($val, 1, -1))), '\\')) . "'";
function normalize_enum($match) {
return "'" . str_replace("'", "''", addcslashes(stripcslashes(str_replace($match[0][0] . $match[0][0], $match[0][0], substr($match[0], 1, -1))), '\\')) . "'";
}
/** Issue grant or revoke commands
* @param 'GRANT'|'REVOKE' $grant
* @param list<string> $privileges
* @return Result|bool
* @param string GRANT or REVOKE
* @param array
* @param string
* @param string
* @return bool
*/
function grant(string $grant, array $privileges, ?string $columns, string $on) {
function grant($grant, $privileges, $columns, $on) {
if (!$privileges) {
return true;
}
@@ -420,14 +398,20 @@ function grant(string $grant, array $privileges, ?string $columns, string $on) {
}
/** Drop old object and create a new one
* @param string $drop drop old object query
* @param string $create create new object query
* @param string $drop_created drop new object query
* @param string $test create test object query
* @param string $drop_test drop test object query
* @return void redirect on success
* @param string drop old object query
* @param string create new object query
* @param string drop new object query
* @param string create test object query
* @param string drop test object query
* @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"]) {
query_redirect($drop, $location, $message_drop);
} elseif ($old_name == "") {
@@ -448,67 +432,78 @@ function drop_create(string $drop, string $create, string $drop_created, string
}
/** 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
return "CREATE 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]", ";")
. ";"
;
}
/** Generate SQL query for creating routine
* @param 'PROCEDURE'|'FUNCTION' $routine
* @param Routine $row
* @param string "PROCEDURE" or "FUNCTION"
* @param array result of routine()
* @return string
*/
function create_routine($routine, array $row): string {
function create_routine($routine, $row) {
global $inout, $jush;
$set = array();
$fields = (array) $row["fields"];
ksort($fields); // enforce fields order
foreach ($fields as $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 "
. idf_escape(trim($row["name"]))
. " (" . 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]" : "")
. (JUSH == "pgsql" ? " AS " . q($definition) : "\n$definition;")
. ($jush == "pgsql" ? " AS " . q($definition) : "$definition;")
;
}
/** Remove current user definer from SQL command */
function remove_definer(string $query): string {
/** Remove current user definer from SQL command
* @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
}
/** 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"];
$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) . "." : "")
. ($ns != "" && $ns != $_GET["ns"] ? idf_escape($ns) . "." : "")
. idf_escape($foreign_key["table"])
. " (" . implode(", ", array_map('Adminer\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("~^(driver()->onActions)\$~", $foreign_key["on_update"]) ? " ON UPDATE $foreign_key[on_update]" : "")
. table($foreign_key["table"])
. " (" . implode(", ", array_map('idf_escape', $foreign_key["target"])) . ")" //! reuse $name - check in older MySQL versions
. (preg_match("~^($on_actions)\$~", $foreign_key["on_delete"]) ? " ON DELETE $foreign_key[on_delete]" : "")
. (preg_match("~^($on_actions)\$~", $foreign_key["on_update"]) ? " ON UPDATE $foreign_key[on_update]" : "")
;
}
/** Add a file to TAR
* @param TmpFile $tmp_file
* @return void prints the output
* @param string
* @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()));
$checksum = 8*32; // space for checksum itself
for ($i=0; $i < strlen($return); $i++) {
@@ -521,47 +516,59 @@ function tar_file(string $filename, $tmp_file): void {
echo str_repeat("\0", 511 - ($tmp_file->size + 511) % 512);
}
/** Get INI bytes value */
function ini_bytes(string $ini): int {
/** Get INI bytes value
* @param string
* @return int
*/
function ini_bytes($ini) {
$val = ini_get($ini);
switch (strtolower(substr($val, -1))) {
case 'g':
$val = (int) $val * 1024; // no break
case 'm':
$val = (int) $val * 1024; // no break
case 'k':
$val = (int) $val * 1024;
case 'g': $val *= 1024; // no break
case 'm': $val *= 1024; // no break
case 'k': $val *= 1024;
}
return $val;
}
/** Create link to database documentation
* @param string[] $paths JUSH => $path
* @param string $text HTML code
* @param array $jush => $path
* @param string HTML code
* @return string HTML code
*/
function doc_link(array $paths, string $text = "<sup>?</sup>"): string {
$server_info = connection()->server_info;
function doc_link($paths, $text = "<sup>?</sup>") {
global $jush, $connection;
$server_info = $connection->server_info;
$version = preg_replace('~^(\d\.?\d).*~s', '\1', $server_info); // two most significant digits
$urls = array(
'sql' => "https://dev.mysql.com/doc/refman/$version/en/",
'sqlite' => "https://www.sqlite.org/",
'pgsql' => "https://www.postgresql.org/docs/" . (connection()->flavor == 'cockroach' ? "current" : $version) . "/",
'mssql' => "https://learn.microsoft.com/en-us/sql/",
'pgsql' => "https://www.postgresql.org/docs/$version/",
'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=",
);
if (connection()->flavor == 'maria') {
$urls['sql'] = "https://mariadb.com/kb/en/";
if (preg_match('~MariaDB~', $server_info)) {
$urls['sql'] = "https://mariadb.com/kb/en/library/";
$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
* @param string
* @return string formatted
*/
function db_size(string $db): string {
if (!connection()->select_db($db)) {
function db_size($db) {
global $connection;
if (!$connection->select_db($db)) {
return "?";
}
$return = 0;
@@ -571,11 +578,15 @@ function db_size(string $db): string {
return format_number($return);
}
/** Print SET NAMES if utf8mb4 might be needed */
function set_utf8mb4(string $create): void {
/** Print SET NAMES if utf8mb4 might be needed
* @param string
* @return null
*/
function set_utf8mb4($create) {
global $connection;
static $set = false;
if (!$set && preg_match('~\butf8mb4~i', $create)) { // possible false positive
$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,486 +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, bool $defer = false): string {
return "<script src='" . h($url) . "'" . nonce() . ($defer ? " defer" : "") . "></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 {
static $label = 0;
$label_option = "";
if (!$labelled_by && substr($options[""], 0, 1) == "(") {
$label++;
$labelled_by = "label-$label";
$label_option = "<option value='' id='$labelled_by'>" . h($options[""]);
unset($options[""]);
}
return "<select name='" . h($name) . "'"
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
. ">" . $label_option . 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 $separator = ""): string {
$return = "";
foreach ($options as $key => $val) {
$return .= "<label><input type='radio' name='" . h($name) . "' value='" . h($key) . "'" . ($key == $value ? " checked" : "") . ">" . h($val) . "</label>$separator";
}
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,37 +1,81 @@
<?php
namespace Adminer;
// not used in a single language version
/** Translate string
* @param literal-string $idf
* @param float|string $number
$langs = array(
'en' => 'English', // Jakub Vrána - https://www.vrana.cz
'ar' => 'العربية', // Y.M Amine - Algeria - nbr7@live.fr
'bg' => 'Български', // Deyan Delchev
'bn' => 'বাংলা', // Dipak Kumar - dipak.ndc@gmail.com | Hossain Ahmed Saiman - hossain.ahmed@altscope.com
'bs' => 'Bosanski', // Emir Kurtovic
'ca' => 'Català', // Joan Llosas
'cs' => 'Čeština', // Jakub Vrána - https://www.vrana.cz
'da' => 'Dansk', // Jarne W. Beutnagel - jarne@beutnagel.dk
'de' => 'Deutsch', // Klemens Häckel - http://clickdimension.wordpress.com
'el' => 'Ελληνικά', // Dimitrios T. Tanis - jtanis@tanisfood.gr
'es' => 'Español', // Klemens Häckel - http://clickdimension.wordpress.com
'et' => 'Eesti', // Priit Kallas
'fa' => 'فارسی', // mojtaba barghbani - Iran - mbarghbani@gmail.com, Nima Amini - http://nimlog.com
'fi' => 'Suomi', // Finnish - Kari Eveli - http://www.lexitec.fi/
'fr' => 'Français', // Francis Gagné, Aurélien Royer
'gl' => 'Galego', // Eduardo Penabad Ramos
'he' => 'עברית', // Binyamin Yawitz - https://stuff-group.com/
'hu' => 'Magyar', // Borsos Szilárd (Borsosfi) - http://www.borsosfi.hu, info@borsosfi.hu
'id' => 'Bahasa Indonesia', // Ivan Lanin - http://ivan.lanin.org
'it' => 'Italiano', // Alessandro Fiorotto, Paolo Asperti
'ja' => '日本語', // Hitoshi Ozawa - http://sourceforge.jp/projects/oss-ja-jpn/releases/
'ka' => 'ქართული', // Saba Khmaladze skhmaladze@uglt.org
'ko' => '한국어', // dalli - skcha67@gmail.com
'lv' => 'Latviešu', // Kristaps Lediņš - https://krysits.com
'lt' => 'Lietuvių', // Paulius Leščinskas - http://www.lescinskas.lt
'ms' => 'Bahasa Melayu', // Pisyek
'nl' => 'Nederlands', // Maarten Balliauw - http://blog.maartenballiauw.be
'no' => 'Norsk', // Iver Odin Kvello, mupublishing.com
'pl' => 'Polski', // Radosław Kowalewski - http://srsbiz.pl/
'pt' => 'Português', // André Dias
'pt-br' => 'Português (Brazil)', // Gian Live - gian@live.com, Davi Alexandre davi@davialexandre.com.br, RobertoPC - http://www.robertopc.com.br
'ro' => 'Limba Română', // .nick .messing - dot.nick.dot.messing@gmail.com
'ru' => 'Русский', // Maksim Izmaylov; Andre Polykanine - https://github.com/Oire/
'sk' => 'Slovenčina', // Ivan Suchy - http://www.ivansuchy.com, Juraj Krivda - http://www.jstudio.cz
'sl' => 'Slovenski', // Matej Ferlan - www.itdinamik.com, matej.ferlan@itdinamik.com
'sr' => 'Српски', // Nikola Radovanović - cobisimo@gmail.com
'sv' => 'Svenska', // rasmusolle - https://github.com/rasmusolle
'ta' => 'த‌மிழ்', // G. Sampath Kumar, Chennai, India, sampathkumar11@gmail.com
'th' => 'ภาษาไทย', // Panya Saraphi, elect.tu@gmail.com - http://www.opencart2u.com/
'tr' => 'Türkçe', // Bilgehan Korkmaz - turktron.com
'uk' => 'Українська', // Valerii Kryzhov
'vi' => 'Tiếng Việt', // Giang Manh @ manhgd google mail
'zh' => '简体中文', // Mr. Lodar, vea - urn2.net - vea.urn2@gmail.com
'zh-tw' => '繁體中文', // http://tzangms.com
);
/** Get current language
* @return string
*/
function lang(string $idf, $number = null): string {
$args = func_get_args();
// this is matched by compile.php
$args[0] = Lang::$translations[$idf] ?: $idf;
return call_user_func_array('Adminer\lang_format', $args);
function get_lang() {
global $LANG;
return $LANG;
}
/** Format translation, usable also by plugins
* @param string|list<string> $translation
* @param float|string $number
/** Translate string
* @param string
* @param int
* @return string
*/
function lang_format($translation, $number = null): string {
function lang($idf, $number = null) {
global $LANG, $translations;
$translation = ($translations[$idf] ? $translations[$idf] : $idf);
if (is_array($translation)) {
// this is matched by compile.php
$pos = ($number == 1 ? 0
: (LANG == 'cs' || LANG == 'sk' ? ($number && $number < 5 ? 1 : 2) // different forms for 1, 2-4, other
: (LANG == 'fr' ? (!$number ? 0 : 1) // different forms for 0-1, other
: (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 == '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
: (in_array(LANG, array('bs', 'ru', 'sr', 'uk')) ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1 except 11, 2-4 except 12-14, other
: 1)))))))) // different forms for 1, other
; // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
: ($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 == '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 == '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 == 'bs' || $LANG == 'ru' || $LANG == 'sr' || $LANG == 'uk' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1 except 11, 2-4 except 12-14, other
: 1 // different forms for 1, other
))))))); // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
$translation = $translation[$pos];
}
$translation = str_replace("'", '', $translation); // translations can contain HTML or be used in optionlist (we couldn't escape them here) but they can also be used e.g. in title='' //! escape plaintext translations
$args = func_get_args();
array_shift($args);
$format = str_replace("%d", "%s", $translation);
@@ -41,81 +85,27 @@ function lang_format($translation, $number = null): string {
return vsprintf($format, $args);
}
// this is matched by compile.php
// not used in a single language version from here
/** Get available languages
* @return string[]
*/
function langs(): array {
return array(
'en' => 'English', // Jakub Vrána - https://www.vrana.cz
'ar' => 'العربية', // Y.M Amine - Algeria - nbr7@live.fr
'bg' => 'Български', // Deyan Delchev
'bn' => 'বাংলা', // Dipak Kumar - dipak.ndc@gmail.com, Hossain Ahmed Saiman - hossain.ahmed@altscope.com
'bs' => 'Bosanski', // Emir Kurtovic
'ca' => 'Català', // Joan Llosas
'cs' => 'Čeština', // Jakub Vrána - https://www.vrana.cz
'da' => 'Dansk', // Jarne W. Beutnagel - jarne@beutnagel.dk
'de' => 'Deutsch', // Klemens Häckel - http://clickdimension.wordpress.com
'el' => 'Ελληνικά', // Dimitrios T. Tanis - jtanis@tanisfood.gr
'es' => 'Español', // Klemens Häckel - http://clickdimension.wordpress.com
'et' => 'Eesti', // Priit Kallas
'fa' => 'فارسی', // mojtaba barghbani - Iran - mbarghbani@gmail.com, Nima Amini - http://nimlog.com
'fi' => 'Suomi', // Finnish - Kari Eveli - http://www.lexitec.fi/
'fr' => 'Français', // Francis Gagné, Aurélien Royer
'gl' => 'Galego', // Eduardo Penabad Ramos
'he' => 'עברית', // Binyamin Yawitz - https://stuff-group.com/
'hu' => 'Magyar', // Borsos Szilárd (Borsosfi) - http://www.borsosfi.hu, info@borsosfi.hu
'id' => 'Bahasa Indonesia', // Ivan Lanin - http://ivan.lanin.org
'it' => 'Italiano', // Alessandro Fiorotto, Paolo Asperti
'ja' => '日本語', // Hitoshi Ozawa - http://sourceforge.jp/projects/oss-ja-jpn/releases/
'ka' => 'ქართული', // Saba Khmaladze skhmaladze@uglt.org
'ko' => '한국어', // dalli - skcha67@gmail.com
'lt' => 'Lietuvių', // Paulius Leščinskas - http://www.lescinskas.lt
'lv' => 'Latviešu', // Kristaps Lediņš - https://krysits.com
'ms' => 'Bahasa Melayu', // Pisyek
'nl' => 'Nederlands', // Maarten Balliauw - http://blog.maartenballiauw.be
'no' => 'Norsk', // Iver Odin Kvello, mupublishing.com
'pl' => 'Polski', // Radosław Kowalewski - http://srsbiz.pl/
'pt' => 'Português', // André Dias
'pt-br' => 'Português (Brazil)', // Gian Live - gian@live.com, Davi Alexandre davi@davialexandre.com.br, RobertoPC - http://www.robertopc.com.br
'ro' => 'Limba Română', // .nick .messing - dot.nick.dot.messing@gmail.com
'ru' => 'Русский', // Maksim Izmaylov; Andre Polykanine - https://github.com/Oire/
'sk' => 'Slovenčina', // Ivan Suchy - http://www.ivansuchy.com, Juraj Krivda - http://www.jstudio.cz
'sl' => 'Slovenski', // Matej Ferlan - www.itdinamik.com, matej.ferlan@itdinamik.com
'sr' => 'Српски', // Nikola Radovanović - cobisimo@gmail.com
'sv' => 'Svenska', // rasmusolle - https://github.com/rasmusolle
'ta' => 'த‌மிழ்', // G. Sampath Kumar, Chennai, India, sampathkumar11@gmail.com
'th' => 'ภาษาไทย', // Panya Saraphi, elect.tu@gmail.com - http://www.opencart2u.com/
'tr' => 'Türkçe', // Bilgehan Korkmaz - turktron.com
'uk' => 'Українська', // Valerii Kryzhov
'uz' => 'Oʻzbekcha', // Junaydullaev Inoyatullokhon - https://av.uz/
'vi' => 'Tiếng Việt', // Giang Manh @ manhgd google mail
'zh' => '简体中文', // Mr. Lodar, vea - urn2.net - vea.urn2@gmail.com
'zh-tw' => '繁體中文', // http://tzangms.com
);
}
function switch_lang(): void {
function switch_lang() {
global $LANG, $langs;
echo "<form action='' method='post'>\n<div id='lang'>";
echo "<label>" . lang('Language') . ": " . html_select("lang", langs(), LANG, "this.form.submit();") . "</label>";
echo lang('Language') . ": " . html_select("lang", $langs, $LANG, "this.form.submit();");
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";
}
if (isset($_POST["lang"]) && verify_token()) { // $error not yet available
cookie("adminer_lang", $_POST["lang"]);
$_SESSION["lang"] = $_POST["lang"]; // cookies may be disabled
$_SESSION["translations"] = array(); // used in compiled version
redirect(remove_from_uri());
}
$LANG = "en";
if (idx(langs(), $_COOKIE["adminer_lang"])) {
if (isset($langs[$_COOKIE["adminer_lang"]])) {
cookie("adminer_lang", $_COOKIE["adminer_lang"]);
$LANG = $_COOKIE["adminer_lang"];
} elseif (idx(langs(), $_SESSION["lang"])) {
} elseif (isset($langs[$_SESSION["lang"]])) {
$LANG = $_SESSION["lang"];
} else {
$accept_language = array();
@@ -125,20 +115,14 @@ if (idx(langs(), $_COOKIE["adminer_lang"])) {
}
arsort($accept_language);
foreach ($accept_language as $key => $q) {
if (idx(langs(), $key)) {
if (isset($langs[$key])) {
$LANG = $key;
break;
}
$key = preg_replace('~-.*~', '', $key);
if (!isset($accept_language[$key]) && idx(langs(), $key)) {
if (!isset($accept_language[$key]) && isset($langs[$key])) {
$LANG = $key;
break;
}
}
}
define('Adminer\LANG', $LANG);
class Lang {
/** @var array<literal-string, string|list<string>> */ static array $translations;
}

View File

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

View File

@@ -1,16 +0,0 @@
<?php
namespace Adminer;
abstract class Plugin {
/** @var array<literal-string, string|list<string>>[] */ protected static $translations = array(); // key is language code
/** Translate a string from static::$translations; use Adminer\lang() for strings used by Adminer
* @param literal-string $idf
* @param float|string $number
*/
protected function lang(string $idf, $number = null) {
$args = func_get_args();
$args[0] = idx(static::$translations[LANG], $idf) ?: $idf;
return call_user_func_array('Adminer\lang_format', $args);
}
}

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

View File

@@ -1,4 +1,2 @@
<?php
namespace Adminer;
const VERSION = "5.2.0-dev";
$VERSION = "4.9.2";

View File

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

View File

@@ -6,17 +6,16 @@
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/
// this is matched by compile.php
namespace Adminer;
include "./include/bootstrap.inc.php";
include "./include/tmpfile.inc.php";
$enum_length = "'(?:''|[^'\\\\]|\\\\.)*'";
$inout = "IN|OUT|INOUT";
if (isset($_GET["select"]) && ($_POST["edit"] || $_POST["clone"]) && !$_POST["save"]) {
$_GET["edit"] = $_GET["select"];
}
// this is matched by compile.php
if (isset($_GET["callf"])) {
$_GET["call"] = $_GET["callf"];
}
@@ -60,8 +59,6 @@ if (isset($_GET["download"])) {
include "./sequence.inc.php";
} elseif (isset($_GET["type"])) {
include "./type.inc.php";
} elseif (isset($_GET["check"])) {
include "./check.inc.php";
} elseif (isset($_GET["trigger"])) {
include "./trigger.inc.php";
} elseif (isset($_GET["user"])) {

View File

@@ -1,9 +1,7 @@
<?php
namespace Adminer;
$TABLE = $_GET["indexes"];
$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"])) {
$index_types[] = "FULLTEXT";
}
@@ -12,15 +10,13 @@ if (preg_match('~MyISAM|M?aria' . (min_version(5.7, '10.2.2') ? '|InnoDB' : '')
}
$indexes = indexes($TABLE);
$primary = array();
if (JUSH == "mongo") { // doesn't support primary key
if ($jush == "mongo") { // doesn't support primary key
$primary = $indexes["_id_"];
unset($index_types[0]);
unset($indexes["_id_"]);
}
$row = $_POST;
if ($row) {
save_settings(array("index_options" => $row["options"]));
}
if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) {
$alter = array();
foreach ($row["indexes"] as $index) {
@@ -33,32 +29,31 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) {
ksort($index["columns"]);
foreach ($index["columns"] as $key => $column) {
if ($column != "") {
$length = idx($index["lengths"], $key);
$desc = idx($index["descs"], $key);
$length = $index["lengths"][$key];
$desc = $index["descs"][$key];
$set[] = idf_escape($column) . ($length ? "(" . (+$length) . ")" : "") . ($desc ? " DESC" : "");
$columns[] = $column;
$lengths[] = ($length ?: null);
$lengths[] = ($length ? $length : null);
$descs[] = $desc;
}
}
$existing = $indexes[$name];
if ($existing) {
ksort($existing["columns"]);
ksort($existing["lengths"]);
ksort($existing["descs"]);
if (
$index["type"] == $existing["type"]
&& array_values($existing["columns"]) === $columns
&& (!$existing["lengths"] || array_values($existing["lengths"]) === $lengths)
&& array_values($existing["descs"]) === $descs
) {
// skip existing index
unset($indexes[$name]);
continue;
}
}
if ($columns) {
$existing = $indexes[$name];
if ($existing) {
ksort($existing["columns"]);
ksort($existing["lengths"]);
ksort($existing["descs"]);
if ($index["type"] == $existing["type"]
&& array_values($existing["columns"]) === $columns
&& (!$existing["lengths"] || array_values($existing["lengths"]) === $lengths)
&& array_values($existing["descs"]) === $descs
) {
// skip existing index
unset($indexes[$name]);
continue;
}
}
$alter[] = array($index["type"], $name, $set);
}
}
@@ -96,23 +91,16 @@ if (!$row) {
$indexes[] = array("columns" => array(1 => ""));
$row["indexes"] = $indexes;
}
$lengths = (JUSH == "sql" || JUSH == "mssql");
$show_options = ($_POST ? $_POST["options"] : get_setting("index_options"));
?>
<form action="" method="post">
<div class="scrollable">
<table class="nowrap">
<table cellspacing="0" class="nowrap">
<thead><tr>
<th id="label-type"><?php echo lang('Index Type'); ?>
<th><input type="submit" class="wayoff"><?php
echo lang('Columns') . ($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><input type="submit" class="wayoff"><?php echo lang('Column (length)'); ?>
<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>
<?php
if ($primary) {
@@ -126,7 +114,7 @@ if ($primary) {
$j = 1;
foreach ($row["indexes"] as $index) {
if (!$_POST["drop_col"] || $j != key($_POST["drop_col"])) {
echo "<tr><td>" . html_select("indexes[$j][type]", array(-1 => "") + $index_types, $index["type"], ($j == count($row["indexes"]) ? "indexesAddRow.call(this);" : ""), "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>";
ksort($index["columns"]);
@@ -136,17 +124,16 @@ foreach ($row["indexes"] as $index) {
" name='indexes[$j][columns][$i]' title='" . lang('Column') . "'",
($fields ? array_combine($fields, $fields) : $fields),
$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 ($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, idx($index["descs"], $key), lang('descending')) : "");
echo "</span> </span>";
echo ($jush == "sql" || $jush == "mssql" ? "<input type='number' name='indexes[$j][lengths][$i]' class='size' value='" . h($index["lengths"][$key]) . "' title='" . lang('Length') . "'>" : "");
echo (support("descidx") ? checkbox("indexes[$j][descs][$i]", 1, $index["descs"][$key], lang('descending')) : "");
echo " </span>";
$i++;
}
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++;
}
@@ -155,5 +142,5 @@ foreach ($row["indexes"] as $index) {
</div>
<p>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php echo input_token(); ?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form>

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'تسجيل الدخول',
'Logout successful.' => 'تم تسجيل الخروج بنجاح.',
'Invalid credentials.' => 'بيانات الدخول غير صالحة.',
'Invalid server or credentials.' => null,
'Server' => 'الخادم',
'Username' => 'اسم المستخدم',
'Password' => 'كلمة المرور',
@@ -32,6 +30,7 @@ Lang::$translations = array(
'Create database' => 'إنشاء قاعدة بيانات',
'SQL command' => 'استعلام SQL',
'Logout' => 'تسجيل الخروج',
'database' => 'قاعدة بيانات',
'Use' => 'استعمال',
'No tables.' => 'لا توجد جداول.',
'select' => 'تحديد',
@@ -77,7 +76,7 @@ Lang::$translations = array(
'Routine has been called, %d row(s) affected.' => 'تم استدعاء الروتين, عدد الأسطر المعدلة %d.',
'Call' => 'استدعاء',
'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 expired, please login again.' => 'إنتهت الجلسة، من فضلك أعد تسجيل الدخول.',
'Text length' => 'طول النص',
@@ -95,7 +94,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'نوع المؤشر',
'length' => 'الطول',
'Column (length)' => 'العمود (الطول)',
'View has been dropped.' => 'تم مسح العرض.',
'View has been altered.' => 'تم تعديل العرض.',
'View has been created.' => 'تم إنشاء العرض.',
@@ -171,8 +170,8 @@ Lang::$translations = array(
'Tables and views' => 'الجداول و العروض',
'Engine' => 'المحرك',
'Collation' => 'ترتيب',
'Data Length' => 'طول المعطيات',
'Index Length' => 'طول المؤشر',
'Data Length' => 'طول المعطيات.',
'Index Length' => 'طول المؤشر.',
'Data Free' => 'المساحة الحرة',
'Rows' => 'الأسطر',
',' => ',',
@@ -192,7 +191,7 @@ Lang::$translations = array(
'Partitions' => 'التقسيمات',
'Partition name' => 'اسم التقسيم',
'Values' => 'القيم',
'%d row(s) have been imported.' => 'تم استيراد %d سطرا.',
'%d row(s) have been imported.' => 'تم استيراد %d سطرا',
'anywhere' => 'في اي مكان',
'Import' => 'استيراد',
'Stop on error' => 'أوقف في حالة حدوث خطأ',
@@ -212,6 +211,11 @@ Lang::$translations = array(
'Binary' => 'ثنائية',
'Lists' => 'قوائم',
'Editor' => 'المحرر',
'E-mail' => 'البريد الإلكتروني',
'From' => 'من',
'Subject' => 'الموضوع',
'Send' => 'إرسال',
'%d e-mail(s) have been sent.' => 'تم إرسال %d رسالة.',
'Webserver file %s' => 'ملف %s من خادم الويب',
'File does not exist.' => 'الملف غير موجود.',
'%d in total' => '%d في المجموع',
@@ -246,7 +250,8 @@ Lang::$translations = array(
'Network' => 'شبكة',
'Geometry' => 'هندسة',
'File exists.' => 'الملف موجود.',
'Item%s has been inserted.' => '%sتم إدراج العنصر.',
'Attachments' => 'ملفات مرفقة.',
'Item%s has been inserted.' => 'تم إدراج العنصر.',
'now' => 'الآن',
'%d query(s) executed OK.' => array('تم تنفيذ الاستعلام %d بنجاح.', 'تم تنفيذ الاستعلامات %d بنجاح.'),
'Show only errors' => 'إظهار الأخطاء فقط',
@@ -259,6 +264,50 @@ Lang::$translations = array(
'Permanent link' => 'رابط دائم',
'Edit all' => 'تعديل الكل',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Система',
'Server' => 'Сървър',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Изход',
'Logged as: %s' => 'Текущ потребител: %s',
'Logout successful.' => 'Излизането е успешно.',
'Invalid credentials.' => 'Невалидни потребителски данни.',
'Invalid server or credentials.' => null,
'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 метод, за да я направите постоянна.',
'Language' => 'Език',
@@ -80,6 +78,7 @@ Lang::$translations = array(
'Data' => 'Данни',
'Database' => 'База данни',
'database' => 'база данни',
'Use' => 'Избор',
'Select database' => 'Избор на база данни',
'Invalid database.' => 'Невалидна база данни.',
@@ -194,7 +193,7 @@ Lang::$translations = array(
'Alter indexes' => 'Промяна на индекси',
'Add next' => 'Добавяне на следващ',
'Index Type' => 'Вид на индекса',
'length' => 'дължина',
'Column (length)' => 'Колона (дължина)',
'Foreign keys' => 'Препратки',
'Foreign key' => 'Препратка',
@@ -256,7 +255,7 @@ Lang::$translations = array(
// in-place editing in select
'Modify' => 'Промяна',
'Ctrl+click on a value to modify it.' => 'Ctrl+щракване в стойността, за да я промените.',
'Use edit link to modify this value.' => 'Използвайте \'редакция\' за промяна на данните.',
'Use edit link to modify this value.' => 'Използвайте "редакция" за промяна на данните.',
// %s can contain auto-increment value
'Item%s has been inserted.' => 'Елементи%s бяха вмъкнати.',
@@ -279,6 +278,13 @@ Lang::$translations = array(
'Delete' => 'Изтриване',
'You have no privileges to update this table.' => 'Нямате праве за обновяване на таблицата.',
'E-mail' => 'E-mail',
'From' => 'От',
'Subject' => 'Тема',
'Attachments' => 'Прикачени',
'Send' => 'Изпращане',
'%d e-mail(s) have been sent.' => array('%d писмо беше изпратено.', '%d писма бяха изпратени.'),
// data type descriptions
'Numbers' => 'Числа',
'Date and time' => 'Дата и час',
@@ -327,6 +333,26 @@ Lang::$translations = array(
'Type has been dropped.' => 'Вида беше пермахнат.',
'Type has been created.' => 'Вида беше създаден.',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Да',
'No' => 'Не',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'লগইন',
'Logout successful.' => 'সফলভাবে লগআউট হয়েছে।',
'Invalid credentials.' => 'ভুল পাসওয়ার্ড।',
'Invalid server or credentials.' => null,
'Server' => 'সার্ভার',
'Username' => 'ইউজারের নাম',
'Password' => 'পাসওয়ার্ড',
@@ -33,12 +31,13 @@ Lang::$translations = array(
'Create database' => 'ডাটাবেজ তৈরী করুন',
'SQL command' => 'SQL-কমান্ড',
'Logout' => 'লগআউট',
'database' => 'ডাটাবেজ',
'Use' => 'ব্যবহার',
'No tables.' => 'কোন টেবিল নাই।',
'select' => 'নির্বাচন',
'Item has been deleted.' => 'বিষয়বস্তু মুছে ফেলা হয়েছে।',
'Item has been updated.' => 'বিষয়বস্তু হালনাগাদ করা হয়েছে।',
'Item%s has been inserted.' => 'বিষয়বস্তুসমূহ%s সংযোজন করা হয়েছে।',
'Item%s has been inserted.' => 'বিষয়বস্তুসমূহ সংযোজন করা হয়েছে।',
'Edit' => 'সম্পাদনা',
'Insert' => 'সংযোজন',
'Save and insert next' => 'সংরক্ষন ও পরবর্তী সংযোজন করুন',
@@ -61,7 +60,7 @@ Lang::$translations = array(
'edit' => 'সম্পাদনা',
'Page' => 'পৃষ্ঠা',
'Query executed OK, %d row(s) affected.' => array('কোয়্যারী সম্পাদন হয়েছে, %d সারি প্রভাবিত হয়েছে।', 'কোয়্যারী সম্পাদন হয়েছে, %d সারি প্রভাবিত হয়েছে।'),
'Error in query' => 'অনুসন্ধানে ভুল আছে',
'Error in query' => 'অনুসন্ধানে ভুল আছে',
'Execute' => 'সম্পাদন করো',
'Table' => 'টেবিল',
'Foreign keys' => 'ফরেন কী',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'অন ডিলিট',
'ON UPDATE' => 'অন আপডেট',
'Index Type' => 'সূচী-ধরণ',
'length' => 'দৈর্ঘ্য',
'Column (length)' => 'কলাম (দৈর্ঘ্য)',
'View has been dropped.' => 'ভিউ মুছে ফেলা হয়েছে।',
'View has been altered.' => 'ভিউ পরিবর্তন করা হয়েছে।',
'View has been created.' => 'ভিউ তৈরী করা হয়েছে।',
@@ -139,7 +138,7 @@ Lang::$translations = array(
'Routine' => 'রুটিন',
'Grant' => 'অনুমতি',
'Revoke' => 'প্রত্যাহার',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'খুব বড় POST ডাটা। ডাটা সংক্ষিপ্ত করো অথবা %s কনফিগারেশন নির্দেশ বৃদ্ধি করো',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'খুব বড় POST ডাটা। ডাটা সংক্ষিপ্ত করো অথবা %s কনফিগারেশন নির্দেশ বৃদ্ধি করো',
'Logged as: %s' => '%s হিসাবে লগড',
'Move up' => 'উপরে স্থানান্তর',
'Move down' => 'নীচে স্থানান্তর',
@@ -175,7 +174,7 @@ Lang::$translations = array(
'Check' => 'পরীক্ষা',
'Repair' => 'মেরামত',
'Truncate' => 'ছাঁটাই',
'Tables have been truncated.' => 'টেবিল ছাঁটাই করা হয়েছে',
'Tables have been truncated.' => 'টেবিল ছাঁটাই করা হয়েছে',
'Rows' => 'সারিসমূহ',
',' => ',',
'0123456789' => '০১২৩৪৫৬৭৮৯',
@@ -186,7 +185,7 @@ Lang::$translations = array(
'Save and continue edit' => 'সংরক্ষণ করুন এবং সম্পাদনা চালিয়ে যান',
'original' => 'প্রকৃত',
'Tables have been dropped.' => 'টেবিলসমূহ মুছে ফেলা হয়েছে।',
'%d item(s) have been affected.' => '%d টি বিষয়বস্তু প্রভাবিত হয়েছে',
'%d item(s) have been affected.' => '%d টি বিষয়বস্তু প্রভাবিত হয়েছে',
'Whole result' => 'সম্পূর্ণ ফলাফল',
'Clone' => 'ক্লোন',
'Maximum number of allowed fields exceeded. Please increase %s.' => 'অনুমোদিত ফিল্ড এর সর্বাধিক সংখ্যা অতিক্রম করে গেছে। অনুগ্রহপূর্বক %s বৃদ্ধি করুন।',
@@ -207,13 +206,18 @@ Lang::$translations = array(
'Relations' => 'সম্পর্ক',
'Run file' => 'ফাইল চালাও',
'Clear' => 'সাফ করো',
'Maximum allowed file size is %sB.' => 'সর্বাধিক অনুমোদিত ফাইল সাইজ %sB',
'Maximum allowed file size is %sB.' => 'সর্বাধিক অনুমোদিত ফাইল সাইজ %sB.',
'Numbers' => 'সংখ্যা',
'Date and time' => 'তারিখ এবং সময়',
'Strings' => 'স্ট্রিং',
'Binary' => 'বাইনারি',
'Lists' => 'তালিকা',
'Editor' => 'সম্পাদক',
'E-mail' => '​​ই-মেইল',
'From' => 'থেকে',
'Subject' => 'বিষয়',
'Send' => 'পাঠান',
'%d e-mail(s) have been sent.' => array('%d ইমেইল(গুলি) পাঠানো হয়েছে।', '%d ইমেইল(গুলি) পাঠানো হয়েছে।'),
'Webserver file %s' => 'ওয়েবসার্ভার ফাইল %s',
'File does not exist.' => 'ফাইলটির কোন অস্তিত্ব নেই।',
'%d in total' => 'সর্বমোটঃ %d টি',
@@ -247,7 +251,8 @@ Lang::$translations = array(
'Network' => 'নেটওয়ার্ক',
'Geometry' => 'জ্যামিতি',
'File exists.' => 'ফাইল রয়েছে।',
'%d query(s) executed OK.' => array('SQL-অনুসন্ধান সফলভাবে সম্পন্ন হয়েছে।', '%d SQL-অনুসন্ধানসমূহ সফলভাবে সম্পন্ন হয়েছে।'),
'Attachments' => 'সংযুক্তিগুলো',
'%d query(s) executed OK.' => array('SQL-অনুসন্ধান সফলভাবে সম্পন্ন হয়েছে', '%d SQL-অনুসন্ধানসমূহ সফলভাবে সম্পন্ন হয়েছে'),
'Show only errors' => 'শুধুমাত্র ত্রুটিগুলো দেখান',
'Refresh' => 'রিফ্রেশ',
'Invalid schema.' => 'অবৈধ স্কিমা।',
@@ -259,6 +264,50 @@ Lang::$translations = array(
'Permanent link' => 'স্থায়ী লিংক',
'Edit all' => 'সবগুলো সম্পাদনা করুন',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem',
'Server' => 'Server',
@@ -12,11 +10,11 @@ Lang::$translations = array(
'Logout' => 'Odjava',
'Logged as: %s' => 'Prijavi se kao: %s',
'Logout successful.' => 'Uspešna odjava.',
'Invalid credentials.' => 'Nevažeće dozvole.',
'Invalid server or credentials.' => null,
'Language' => 'Jezik',
'Invalid CSRF token. Send the form again.' => 'Nevažeći CSRF kod. Proslijedite ponovo formu.',
'No extension' => 'Bez dodataka',
'None of the supported PHP extensions (%s) are available.' => 'Nijedan od podržanih PHP dodataka (%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 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',
@@ -75,6 +73,7 @@ Lang::$translations = array(
'Data' => 'Podaci',
'Database' => 'Baza podataka',
'database' => 'baza podataka',
'Use' => 'Koristi',
'Select database' => 'Izaberite bazu',
'Invalid database.' => 'Neispravna baza podataka.',
@@ -184,7 +183,7 @@ Lang::$translations = array(
'Alter indexes' => 'Ažuriraj indekse',
'Add next' => 'Dodaj slijedeći',
'Index Type' => 'Tip indeksa',
'length' => 'dužina',
'Column (length)' => 'kolumna (dužina)',
'Foreign keys' => 'Strani ključevi',
'Foreign key' => 'Strani ključ',
@@ -264,6 +263,13 @@ Lang::$translations = array(
'Delete' => 'Izbriši',
'Modify' => 'Izmjene',
'E-mail' => 'El. pošta',
'From' => 'Od',
'Subject' => 'Naslov',
'Attachments' => 'Prilozi',
'Send' => 'Pošalji',
'%d e-mail(s) have been sent.' => array('%d poruka el. pošte je poslata.', '%d poruke el. pošte su poslate.', '%d poruka el. pošte je poslato.'),
// data type descriptions
'Numbers' => 'Broj',
'Date and time' => 'Datum i vrijeme',
@@ -312,6 +318,41 @@ Lang::$translations = array(
'Type has been dropped.' => 'Tip je izbrisan.',
'Type has been created.' => 'tip je spašen.',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Da',
'No' => 'Ne',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Inicia la sessió',
'Logout successful.' => 'Desconnexió correcta.',
'Invalid credentials.' => 'Credencials invàlides.',
'Invalid server or credentials.' => null,
'Server' => 'Servidor',
'Username' => 'Nom d\'usuari',
'Password' => 'Contrasenya',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Crea una base de dades',
'SQL command' => 'Ordre SQL',
'Logout' => 'Desconnecta',
'database' => 'base de dades',
'Use' => 'Utilitza',
'No tables.' => 'No hi ha cap taula.',
'select' => 'registres',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Tipus d\'índex',
'length' => 'longitud',
'Column (length)' => 'Columna (longitud)',
'View has been dropped.' => 'S\'ha suprimit la vista.',
'View has been altered.' => 'S\'ha modificat la vista.',
'View has been created.' => 'S\'ha creat la vista.',
@@ -206,6 +205,11 @@ Lang::$translations = array(
'History' => 'Història',
'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.' => 'Les columnes d\'origen i de destinació han de ser del mateix tipus, la columna de destinació ha d\'estar indexada i les dades referenciades han d\'existir.',
'E-mail' => 'Correu electrònic',
'From' => 'De',
'Subject' => 'Assumpte',
'Send' => 'Envia',
'%d e-mail(s) have been sent.' => array('S\'ha enviat %d correu electrònic.', 'S\'han enviat %d correus electrònics.'),
'Run file' => 'Executa el fitxer',
'Numbers' => 'Nombres',
'Date and time' => 'Data i hora',
@@ -220,6 +224,7 @@ Lang::$translations = array(
'File does not exist.' => 'El fitxer no existeix.',
'Permanent login' => 'Sessió permanent',
'%d in total' => '%d en total',
'Attachments' => 'Adjuncions',
'System' => 'Sistema',
'last' => 'darrera',
'Network' => 'Xarxa',
@@ -260,6 +265,49 @@ Lang::$translations = array(
'Permanent link' => 'Enllaç permanent',
'Edit all' => 'Edita-ho tot',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Systém',
'Server' => 'Server',
@@ -13,10 +11,7 @@ Lang::$translations = array(
'Logged as: %s' => 'Přihlášen jako: %s',
'Logout successful.' => 'Odhlášení proběhlo v pořádku.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Díky za použití Admineru, <a href="https://www.adminer.org/cs/donation/">přispějte</a> na vývoj.',
'Loaded plugins' => 'Nahrané pluginy',
'%s must <a%s>return an array</a>.' => '%s musí <a%s>vracet pole</a>.',
'<a%s>Configure</a> %s in %s.' => '<a%s>Nakonfigurujte</a> %s v %s.',
'Invalid credentials.' => 'Neplatné přihlašovací údaje.',
'Invalid server or credentials.' => 'Neplatný server nebo přihlašovací údaje.',
'There is a space in the input password which might be the cause.' => 'Problém může být, že je v zadaném hesle mezera.',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer nepodporuje přístup k databázi bez hesla, <a href="https://www.adminer.org/cs/password/"%s>více informací</a>.',
'Database does not support password.' => 'Databáze nepodporuje heslo.',
@@ -45,7 +40,6 @@ Lang::$translations = array(
'User has been created.' => 'Uživatel byl vytvořen.',
'Hashed' => 'Zahašované',
'Column' => 'Sloupec',
'Columns' => 'Sloupce',
'Routine' => 'Procedura',
'Grant' => 'Povolit',
'Revoke' => 'Zakázat',
@@ -94,6 +88,7 @@ Lang::$translations = array(
'Data' => 'Data',
'Database' => 'Databáze',
'database' => 'databáze',
'DB' => 'DB',
'Use' => 'Vybrat',
'Select database' => 'Vybrat databázi',
@@ -211,7 +206,7 @@ Lang::$translations = array(
'Alter indexes' => 'Pozměnit indexy',
'Add next' => 'Přidat další',
'Index Type' => 'Typ indexu',
'length' => 'délka',
'Column (length)' => 'Sloupec (délka)',
'Foreign keys' => 'Cizí klíče',
'Foreign key' => 'Cizí klíč',
@@ -261,8 +256,8 @@ Lang::$translations = array(
'%d row(s)' => array('%d řádek', '%d řádky', '%d řádků'),
'Page' => 'Stránka',
'last' => 'poslední',
'Load more data' => 'Načíst další data',
'Loading' => 'Načítá se',
'Load more data' => 'Nahrát další data',
'Loading' => 'Nahrává se',
'Whole result' => 'Celý výsledek',
'%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtů'),
@@ -296,6 +291,13 @@ Lang::$translations = array(
'Delete' => 'Smazat',
'You have no privileges to update this table.' => 'Nemáte oprávnění editovat tuto tabulku.',
'E-mail' => 'E-mail',
'From' => 'Odesílatel',
'Subject' => 'Předmět',
'Attachments' => 'Přílohy',
'Send' => 'Odeslat',
'%d e-mail(s) have been sent.' => array('Byl odeslán %d e-mail.', 'Byly odeslány %d e-maily.', 'Bylo odesláno %d e-mailů.'),
// data type descriptions
'Numbers' => 'Čísla',
'Date and time' => 'Datum a čas',
@@ -345,13 +347,12 @@ Lang::$translations = array(
'Type has been created.' => 'Typ byl vytvořen.',
'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.',
// Plugins
'Columns' => 'Sloupce',
'Nullable' => 'Povoleno null',
'Default' => 'Výchozí',
'Yes' => 'Ano',
'No' => 'Ne',
'One Time Password' => 'Jednorázové heslo',
'Invalid OTP code.' => 'Neplatný kód OTP.',
);
// run `php ../../lang.php cs` to update this file

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'System' => 'System',
'Server' => 'Server',
'Username' => 'Brugernavn',
@@ -11,7 +9,7 @@ Lang::$translations = array(
'Logout' => 'Log ud',
'Logged as: %s' => 'Logget ind som: %s',
'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.',
'Language' => 'Sprog',
'Invalid CSRF token. Send the form again.' => 'Ugyldigt CSRF-token - Genindsend formen.',
@@ -66,6 +64,7 @@ Lang::$translations = array(
'Format' => 'Format',
'Data' => 'Data',
'Database' => 'Database',
'database' => 'database',
'Use' => 'Brug',
'Select database' => 'Vælg database',
'Invalid database.' => 'Ugyldig database.',
@@ -166,7 +165,7 @@ Lang::$translations = array(
'Alter indexes' => 'Ændre indekser',
'Add next' => 'Læg til næste',
'Index Type' => 'Indekstype',
'length' => 'længde',
'Column (length)' => 'Kolonne (længde)',
'Foreign keys' => 'Fremmednøgler',
'Foreign key' => 'Fremmednøgle',
'Foreign key has been dropped.' => 'Fremmednøglen er slettet.',
@@ -238,6 +237,12 @@ Lang::$translations = array(
'Clone' => 'Klon',
'Delete' => 'Slet',
'You have no privileges to update this table.' => 'Du mangler rettigheder til at ændre denne tabellen.',
'E-mail' => 'E-mail',
'From' => 'Fra',
'Subject' => 'Titel',
'Attachments' => 'Vedhæft',
'Send' => 'Send',
'%d e-mail(s) have been sent.' => array('%d email sendt.', '%d emails sendt.'),
'Numbers' => 'Nummer',
'Date and time' => 'Dato og tid',
'Strings' => 'Strenge',
@@ -274,6 +279,35 @@ Lang::$translations = array(
'Type has been created.' => 'Typen er oprettet.',
'Alter type' => 'Ændre type',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Ja',
'No' => 'Nej',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,11 +1,9 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Login',
'Logout successful.' => 'Abmeldung erfolgreich.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Danke, dass Sie Adminer genutzt haben. <a href="https://www.adminer.org/de/donation/">Spenden willkommen!</a>.',
'Invalid credentials.' => 'Ungültige Anmelde-Informationen.',
'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 server or credentials.' => 'Ungültige Server oder Anmelde-Informationen.',
'Server' => 'Server',
'Username' => 'Benutzer',
'Password' => 'Passwort',
@@ -34,7 +32,8 @@ Lang::$translations = array(
'Create database' => 'Datenbank erstellen',
'SQL command' => 'SQL-Kommando',
'Logout' => 'Abmelden',
'Use' => 'Auswählen',
'database' => 'Datenbank',
'Use' => 'Benutzung',
'No tables.' => 'Keine Tabellen.',
'select' => 'zeigen',
'Item has been deleted.' => 'Datensatz wurde gelöscht.',
@@ -98,7 +97,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Index-Typ',
'length' => 'Länge',
'Column (length)' => 'Spalte (Länge)',
'View has been dropped.' => 'View wurde entfernt.',
'View has been altered.' => 'View wurde geändert.',
'View has been created.' => 'View wurde erstellt.',
@@ -215,6 +214,11 @@ Lang::$translations = array(
'Binary' => 'Binär',
'Lists' => 'Listen',
'Editor' => 'Editor',
'E-mail' => 'E-Mail',
'From' => 'Von',
'Subject' => 'Betreff',
'Send' => 'Abschicken',
'%d e-mail(s) have been sent.' => array('%d E-Mail abgeschickt.', '%d E-Mails abgeschickt.'),
'Webserver file %s' => 'Webserver Datei %s',
'File does not exist.' => 'Datei existiert nicht.',
'%d in total' => '%d insgesamt',
@@ -249,6 +253,7 @@ Lang::$translations = array(
'Network' => 'Netzwerk',
'Geometry' => 'Geometrie',
'File exists.' => 'Datei existiert schon.',
'Attachments' => 'Anhänge',
'%d query(s) executed OK.' => array('SQL-Abfrage erfolgreich ausgeführt.', '%d SQL-Abfragen erfolgreich ausgeführt.'),
'Show only errors' => 'Nur Fehler anzeigen',
'Refresh' => 'Aktualisieren',
@@ -275,36 +280,34 @@ 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.',
'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 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',
'yes' => 'ja',
'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.',
'%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',
'Loaded plugins' => 'Geladene Plugins',
'%s must <a%s>return an array</a>.' => '%s muss <a%s>ein Array zurückgeben</a>.',
'<a%s>Configure</a> %s in %s.' => '<a%s>Konfigure</a> %s mit %s.',
);
// 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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Ja',
'No' => 'Nein',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Σύστημα',
'Server' => 'Διακομιστής',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Αποσύνδεση',
'Logged as: %s' => 'Συνδεθήκατε ως %s',
'Logout successful.' => 'Αποσυνδεθήκατε με επιτυχία.',
'Invalid credentials.' => 'Εσφαλμένα Διαπιστευτήρια.',
'Invalid server or credentials.' => null,
'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 για να τον κάνετε μόνιμο.',
'Language' => 'Γλώσσα',
@@ -81,6 +79,7 @@ Lang::$translations = array(
'Data' => 'Δεδομένα',
'Database' => 'Β. Δεδομένων',
'database' => 'β. δεδομένων',
'Use' => 'χρήση',
'Select database' => 'Επιλέξτε Β.Δ.',
'Invalid database.' => 'Λανθασμένη Β.Δ.',
@@ -195,7 +194,7 @@ Lang::$translations = array(
'Alter indexes' => 'Τροποποίηση δεικτών',
'Add next' => 'Προσθήκη επόμενου',
'Index Type' => 'Τύπος δείκτη',
'length' => 'μήκος',
'Column (length)' => 'Στήλη (μήκος)',
'Foreign keys' => 'Εξαρτημένα κλειδιά',
'Foreign key' => 'Εξαρτημένο κλειδί',
@@ -279,6 +278,13 @@ Lang::$translations = array(
'Delete' => 'Διαγραφή',
'You have no privileges to update this table.' => 'Δεν έχετε δικαίωμα να τροποποιήσετε αυτό τον πίνακα.',
'E-mail' => 'E-mail',
'From' => 'Από',
'Subject' => 'Θέμα',
'Attachments' => 'Συνημμένα',
'Send' => 'Αποστολή',
'%d e-mail(s) have been sent.' => array('%d e-mail απεστάλη.', '%d e-mail απεστάλησαν.'),
// data type descriptions
'Numbers' => 'Αριθμοί',
'Date and time' => 'Ημερομηνία και ώρα',
@@ -327,6 +333,26 @@ Lang::$translations = array(
'Type has been dropped.' => 'Ο τύπος διαγράφηκε.',
'Type has been created.' => 'Ο τύπος δημιουργήθηκε.',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$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.'),
'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'),
@@ -11,8 +9,7 @@ Lang::$translations = array(
'%d row(s)' => array('%d row', '%d rows'),
'%d item(s) have been affected.' => array('%d item has been affected.', '%d items have been affected.'),
'%d row(s) have been imported.' => array('%d row has been imported.', '%d rows have been imported.'),
'%d e-mail(s) have been sent.' => array('%d e-mail has been sent.', '%d e-mails have been sent.'),
'%d in total' => '%d in total',
'%d query(s) executed OK.' => array('%d query executed OK.', '%d queries executed OK.'),
);
// run `php ../../lang.php en` to update this file

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Login',
'Logout successful.' => 'Sesión finalizada con éxito.',
'Invalid credentials.' => 'Usuario y/o clave de acceso incorrecta.',
'Invalid server or credentials.' => null,
'Server' => 'Servidor',
'Username' => 'Usuario',
'Password' => 'Contraseña',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Crear Base de datos',
'SQL command' => 'Comando SQL',
'Logout' => 'Cerrar sesión',
'database' => 'base de datos',
'Use' => 'Usar',
'No tables.' => 'No existen tablas.',
'select' => 'registros',
@@ -44,7 +43,6 @@ Lang::$translations = array(
'Save and insert next' => 'Guardar e insertar siguiente',
'Delete' => 'Eliminar',
'Database' => 'Base de datos',
'DB' => 'BD',
'Routines' => 'Procedimientos',
'Indexes have been altered.' => 'Índices actualizados.',
'Indexes' => 'Índices',
@@ -63,22 +61,18 @@ Lang::$translations = array(
'Page' => 'Página',
'Query executed OK, %d row(s) affected.' => array('Consulta ejecutada, %d registro afectado.', 'Consulta ejecutada, %d registros afectados.'),
'Error in query' => 'Error al ejecutar consulta',
'Unknown error.' => 'Error desconocido.',
'Warnings' => 'Advertencias',
'ATTACH queries are not supported.' => 'Consultas tipo ATTACH no soportadas.',
'Execute' => 'Ejecutar',
'Table' => 'Tabla',
'Foreign keys' => 'Claves externas',
'Triggers' => 'Disparadores',
'View' => 'Vista',
'Materialized view' => 'Vista materializada',
'Unable to select the table' => 'No es posible seleccionar la tabla',
'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Vuelva a enviar los datos del formulario.',
'Comment' => 'Comentario',
'Default values' => 'Valores predeterminados',
'%d byte(s)' => array('%d byte', '%d bytes'),
'No commands to execute.' => 'Ningún comando para ejecutar.',
'Unable to upload a file.' => 'No es posible cargar el archivo.',
'No commands to execute.' => 'No es posible ejecutar ningún comando.',
'Unable to upload a file.' => 'No es posible importar el archivo.',
'File upload' => 'Importar archivo',
'File uploads are disabled.' => 'Importación de archivos deshablilitada.',
'Routine has been called, %d row(s) affected.' => array('Consulta ejecutada, %d registro afectado.', 'Consulta ejecutada, %d registros afectados.'),
@@ -88,9 +82,9 @@ Lang::$translations = array(
'Session support must be enabled.' => 'Deben estar habilitadas las sesiones.',
'Session expired, please login again.' => 'Sesión caducada, por favor escriba su clave de nuevo.',
'Text length' => 'Longitud de texto',
'Foreign key has been dropped.' => 'Clave foranea eliminada.',
'Foreign key has been altered.' => 'Clave foranea modificada.',
'Foreign key has been created.' => 'Clave foranea creada.',
'Foreign key has been dropped.' => 'Clave externa eliminada.',
'Foreign key has been altered.' => 'Clave externa modificada.',
'Foreign key has been created.' => 'Clave externa creada.',
'Foreign key' => 'Clave externa',
'Target table' => 'Tabla de destino',
'Change' => 'Modificar',
@@ -102,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'AL BORRAR',
'ON UPDATE' => 'AL ACTUALIZAR',
'Index Type' => 'Tipo de índice',
'length' => 'longitud',
'Column (length)' => 'Columna (longitud)',
'View has been dropped.' => 'Vista eliminada.',
'View has been altered.' => 'Vista modificada.',
'View has been created.' => 'Vista creada.',
@@ -145,8 +139,6 @@ Lang::$translations = array(
'Grant' => 'Conceder',
'Revoke' => 'Impedir',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'POST data demasiado grande. Reduzca el tamaño o aumente la directiva de configuración %s.',
'You can upload a big SQL file via FTP and import it from server.' => 'Usted puede cargar un SQL grande mediante FTP e importarlo desde el servidor.',
'You are offline.' => 'Usted no esta en linea.',
'Logged as: %s' => 'Logueado como: %s',
'Move up' => 'Mover arriba',
'Move down' => 'Mover abajo',
@@ -154,8 +146,8 @@ Lang::$translations = array(
'Aggregation' => 'Agregados',
'Export' => 'Exportar',
'Output' => 'Salida',
'open' => 'abrir',
'save' => 'guardar',
'open' => 'mostrar',
'save' => 'archivo',
'Format' => 'Formato',
'Tables' => 'Tablas',
'Data' => 'Datos',
@@ -202,7 +194,6 @@ Lang::$translations = array(
'Partition name' => 'Nombre de partición',
'Values' => 'Valores',
'%d row(s) have been imported.' => array('%d registro importado.', '%d registros importados.'),
'File must be in UTF-8 encoding.' => 'El archivo tiene que ser codificacion UTF-8.',
'anywhere' => 'donde sea',
'Import' => 'Importar',
'Stop on error' => 'Parar en caso de error',
@@ -222,6 +213,11 @@ Lang::$translations = array(
'Binary' => 'Binario',
'Lists' => 'Listas',
'Editor' => 'Editor',
'E-mail' => 'Email',
'From' => 'De',
'Subject' => 'Asunto',
'Send' => 'Enviar',
'%d e-mail(s) have been sent.' => array('%d email enviado.', '%d emails enviados.'),
'Webserver file %s' => 'Archivo de servidor web %s',
'File does not exist.' => 'Ese archivo no existe.',
'%d in total' => '%d en total',
@@ -256,9 +252,10 @@ Lang::$translations = array(
'Network' => 'Red',
'Geometry' => 'Geometría',
'File exists.' => 'Ese archivo ya existe.',
'Attachments' => 'Adjuntos',
'%d query(s) executed OK.' => array('%d sentencia SQL ejecutada correctamente.', '%d sentencias SQL ejecutadas correctamente.'),
'Show only errors' => 'Mostrar solamente errores',
'Refresh' => 'Actualizar',
'Refresh' => 'Refrescar',
'Invalid schema.' => 'Esquema inválido.',
'Please use one of the extensions %s.' => 'Por favor, use una de las extensiones %s.',
'now' => 'ahora',
@@ -269,27 +266,48 @@ Lang::$translations = array(
'Edit all' => 'Editar todos',
'HH:MM:SS' => 'HH:MM:SS',
'Loaded plugins' => 'Plugins cargados',
'%s must <a%s>return an array</a>.' => '%s tiene que <a%s>retornar un arreglo</a>.',
'<a%s>Configure</a> %s in %s.' => '<a%s>Configurar</a> %s en %s.',
'There is a space in the input password which might be the cause.' => 'Hay un espacio en el password, lo cual puede ser la causa.',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer no soporta accesar una base de datos sin clave, <a href="https://www.adminer.org/en/password/"%s>Ver detalles</a>.',
'Database does not support password.' => 'La base de datos no soporta password.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Muchos intentos de acceso Intente en %d minutos.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Password maestro expirado. <a href="https://www.adminer.org/en/extension/"%s>Implemente</a> %s metodo para hacerlo permanente.',
'If you did not send this request from Adminer then close this page.' => 'Si no puede enviar la solicitud por Adminer entonces cierre esta pagina.',
'Connecting to privileged ports is not allowed.' => 'Conexiones a puertos privilegiados no son permitidas.',
'Disable %s or enable %s or %s extensions.' => 'Desactivar %s o activar %s o %s extensiones.',
'The action will be performed after successful login with the same credentials.' => 'La operacion sera ejecutada despues de ingresar nuevamente con las mismas credenciales.',
'You have no privileges to update this table.' => 'Usted no tiene privilegios para actualizar esta tabla.',
'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,
// Table check constraints
'Checks' => 'Chequeos',
'Create check' => 'Crear chequeo',
'Alter check' => 'Cambiar chequeo',
'Check has been created.' => 'Chequeo creado.',
'Check has been altered.' => 'Chequeo cambiado.',
'Check has been dropped.' => 'Chequeo eliminado.',
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);
// run `php ../../lang.php es` to update this file

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Logi sisse',
'Logout successful.' => 'Väljalogimine õnnestus.',
'Invalid credentials.' => 'Ebakorrektsed andmed.',
'Invalid server or credentials.' => null,
'Server' => 'Server',
'Username' => 'Kasutajanimi',
'Password' => 'Parool',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Loo uus andmebaas',
'SQL command' => 'SQL-Päring',
'Logout' => 'Logi välja',
'database' => 'andmebaas',
'Use' => 'Kasuta',
'No tables.' => 'Tabeleid ei leitud.',
'select' => 'kuva',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Indeksi tüüp',
'length' => 'pikkus',
'Column (length)' => 'Veerg (pikkus)',
'View has been dropped.' => 'Vaade (VIEW) on edukalt kustutatud.',
'View has been altered.' => 'Vaade (VIEW) on edukalt muudetud.',
'View has been created.' => 'Vaade (VIEW) on edukalt loodud.',
@@ -214,6 +213,11 @@ Lang::$translations = array(
'Binary' => 'Binaar',
'Lists' => 'Listid',
'Editor' => 'Redaktor',
'E-mail' => 'E-post',
'From' => 'Kellelt',
'Subject' => 'Pealkiri',
'Send' => 'Saada',
'%d e-mail(s) have been sent.' => 'Saadetud kirju: %d.',
'Webserver file %s' => 'Fail serveris: %s',
'File does not exist.' => 'Faili ei leitud.',
'%d in total' => 'Kokku: %d',
@@ -248,6 +252,7 @@ Lang::$translations = array(
'Network' => 'Võrk (network)',
'Geometry' => 'Geomeetria',
'File exists.' => 'Fail juba eksisteerib.',
'Attachments' => 'Manused',
'%d query(s) executed OK.' => array('%d päring edukalt käivitatud.', '%d päringut edukalt käivitatud.'),
'Show only errors' => 'Kuva vaid veateateid',
'Refresh' => 'Uuenda',
@@ -260,6 +265,49 @@ Lang::$translations = array(
'Permanent link' => 'Püsilink',
'Edit all' => 'Muuda kõiki',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'سیستم',
'Server' => 'سرور',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'خروج',
'Logged as: %s' => 'ورود به عنوان: %s',
'Logout successful.' => 'با موفقیت خارج شدید.',
'Invalid credentials.' => 'اعتبار سنجی نامعتبر.',
'Invalid server or credentials.' => null,
'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> کرده تا آن را دائمی سازید.',
'Language' => 'زبان',
@@ -79,6 +77,7 @@ Lang::$translations = array(
'Data' => 'داده',
'Database' => 'پایگاه داده',
'database' => 'پایگاه داده',
'Use' => 'استفاده',
'Select database' => 'انتخاب پایگاه داده',
'Invalid database.' => 'پایگاه داده نامعتبر.',
@@ -146,7 +145,7 @@ Lang::$translations = array(
'Tables' => 'جدولها',
'Tables and views' => 'جدولها و نمایه ها',
'Table' => 'جدول',
'No tables.' => 'جدولی وجود ندارد.',
'No tables.' => 'جدولی وجود ندارد',
'Alter table' => 'ویرایش جدول',
'Create table' => 'ایجاد جدول',
'Table has been dropped.' => 'جدول حذف شد.',
@@ -193,7 +192,7 @@ Lang::$translations = array(
'Alter indexes' => 'ویرایش ایندکسها',
'Add next' => 'افرودن بعدی',
'Index Type' => 'نوع ایندکس',
'length' => 'طول',
'Column (length)' => 'ستون (طول)',
'Foreign keys' => 'کلیدهای خارجی',
'Foreign key' => 'کلید خارجی',
@@ -238,7 +237,7 @@ Lang::$translations = array(
'Action' => 'عملیات',
'Full table scan' => 'اسکن کامل جدول',
'Unable to select the table' => 'قادر به انتخاب جدول نیستید',
'No rows.' => 'سطری وجود ندارد.',
'No rows.' => 'سطری وجود ندارد',
'%d / ' => '%d / ',
'%d row(s)' => array('%d سطر', '%d سطر'),
'Page' => 'صفحه',
@@ -277,6 +276,13 @@ Lang::$translations = array(
'Delete' => 'حذف',
'You have no privileges to update this table.' => 'شما اختیار ویرایش این جدول را ندارید.',
'E-mail' => 'پست الکترونیک',
'From' => 'فرستنده',
'Subject' => 'موضوع',
'Attachments' => 'پیوست ها',
'Send' => 'ارسال',
'%d e-mail(s) have been sent.' => array('%d ایمیل ارسال شد.', '%d ایمیل ارسال شد.'),
// data type descriptions
'Numbers' => 'اعداد',
'Date and time' => 'تاریخ و زمان',
@@ -325,6 +331,28 @@ Lang::$translations = array(
'Type has been dropped.' => 'نوع حذف شد.',
'Type has been created.' => 'نوع ایجاد شد.',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Järjestelmä',
'Server' => 'Palvelin',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Kirjaudu ulos',
'Logged as: %s' => 'Olet kirjautunut käyttäjänä: %s',
'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.'),
'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',
@@ -81,6 +79,7 @@ Lang::$translations = array(
'Data' => 'Data',
'Database' => 'Tietokanta',
'database' => 'tietokanta',
'Use' => 'Käytä',
'Select database' => 'Valitse tietokanta',
'Invalid database.' => 'Tietokanta ei kelpaa.',
@@ -195,7 +194,7 @@ Lang::$translations = array(
'Alter indexes' => 'Muuta indeksejä',
'Add next' => 'Lisää seuraava',
'Index Type' => 'Indeksityyppi',
'length' => 'pituus',
'Column (length)' => 'Sarake (pituus)',
'Foreign keys' => 'Vieraat avaimet',
'Foreign key' => 'Vieras avain',
@@ -279,6 +278,13 @@ Lang::$translations = array(
'Delete' => 'Poista',
'You have no privileges to update this table.' => 'Sinulla ei ole oikeutta päivittää tätä taulua.',
'E-mail' => 'S-posti',
'From' => 'Lähettäjä',
'Subject' => 'Aihe',
'Attachments' => 'Liitteet',
'Send' => 'Lähetä',
'%d e-mail(s) have been sent.' => array('% sähköpostiviestiä lähetetty.', '% sähköpostiviestiä lähetetty.'),
// data type descriptions
'Numbers' => 'Numerot',
'Date and time' => 'Päiväys ja aika',
@@ -341,6 +347,12 @@ Lang::$translations = array(
'Unknown error.' => 'Tuntematon virhe.',
'Database does not support password.' => 'Tietokanta ei tue salasanaa.',
'Disable %s or enable %s or %s extensions.' => 'Poista käytöstä %s tai ota käyttöön laajennus %s tai %s.',
);
// run `php ../../lang.php fi` to update this file
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Kyllä',
'No' => 'Ei',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Authentification',
'Logout successful.' => 'Au revoir !',
'Invalid credentials.' => 'Authentification échouée.',
'Invalid server or credentials.' => null,
'Server' => 'Serveur',
'Username' => 'Utilisateur',
'Password' => 'Mot de passe',
@@ -32,6 +30,7 @@ Lang::$translations = array(
'Create database' => 'Créer une base de données',
'SQL command' => 'Requête SQL',
'Logout' => 'Déconnexion',
'database' => 'base de données',
'Use' => 'Utiliser',
'No tables.' => 'Aucune table.',
'select' => 'select',
@@ -95,7 +94,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Type d\'index',
'length' => 'longueur',
'Column (length)' => 'Colonne (longueur)',
'View has been dropped.' => 'La vue a été effacée.',
'View has been altered.' => 'La vue a été modifiée.',
'View has been created.' => 'La vue a été créée.',
@@ -212,6 +211,11 @@ Lang::$translations = array(
'Binary' => 'Binaires',
'Lists' => 'Listes',
'Editor' => 'Éditeur',
'E-mail' => 'Courriel',
'From' => 'De',
'Subject' => 'Sujet',
'Send' => 'Envoyer',
'%d e-mail(s) have been sent.' => array('%d message a été envoyé.', '%d messages ont été envoyés.'),
'Webserver file %s' => 'Fichier %s du serveur Web',
'File does not exist.' => 'Le fichier est introuvable.',
'%d in total' => '%d au total',
@@ -237,7 +241,7 @@ Lang::$translations = array(
'Type has been dropped.' => 'Le type a été supprimé.',
'Type has been created.' => 'Le type a été créé.',
'Ctrl+click on a value to modify it.' => 'Ctrl+cliquez sur une valeur pour la modifier.',
'Use edit link to modify this value.' => 'Utilisez le lien \'modifier\' pour modifier cette valeur.',
'Use edit link to modify this value.' => 'Utilisez le lien "modifier" pour modifier cette valeur.',
'last' => 'dernière',
'From server' => 'Depuis le serveur',
'System' => 'Système',
@@ -247,6 +251,7 @@ Lang::$translations = array(
'Network' => 'Réseau',
'Geometry' => 'Géométrie',
'File exists.' => 'Le fichier existe.',
'Attachments' => 'Pièces jointes',
'Item%s has been inserted.' => 'L\'élément%s a été inséré.',
'now' => 'maintenant',
'%d query(s) executed OK.' => array('%d requête exécutée avec succès.', '%d requêtes exécutées avec succès.'),
@@ -283,18 +288,26 @@ Lang::$translations = array(
'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.',
'You are offline.' => 'Vous êtes hors ligne.',
'Drop %s?' => 'Supprimer %s?',
'overwrite' => 'écraser',
'DB' => 'BD',
'ATTACH queries are not supported.' => 'Requêtes ATTACH ne sont pas supportées.',
'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>.',
'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.',
'Connecting to privileged ports is not allowed.' => 'La connexion aux ports privilégiés n\'est pas autorisée.',
'There is a space in the input password which might be the cause.' => 'Il y a un espace dans le mot de passe entré qui pourrait en être la cause.',
'Unknown error.' => 'Erreur inconnue.',
'Database does not support password.' => 'La base de données ne support pas les mots de passe.',
'Unknown error.' => 'Erreur inconnue',
'Database does not support password.' => 'La base de données ne support pas les mots de passe',
'Disable %s or enable %s or %s extensions.' => 'Désactiver %s ou activer %s or %s extensions.',
);
// run `php ../../lang.php fr` to update this file
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Oui',
'No' => 'Non',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Conectar',
'Logout successful.' => 'Pechouse a sesión con éxito.',
'Invalid credentials.' => 'Credenciais (usuario e/ou contrasinal) inválidos.',
'Invalid server or credentials.' => null,
'Server' => 'Servidor',
'Username' => 'Usuario',
'Password' => 'Contrasinal',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Crear Base de datos',
'SQL command' => 'Comando SQL',
'Logout' => 'Pechar sesión',
'database' => 'base de datos',
'Use' => 'Usar',
'No tables.' => 'Nengunha táboa.',
'select' => 'selecciona',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'AO BORRAR (ON DELETE)',
'ON UPDATE' => 'AO ACTUALIZAR (ON UPDATE)',
'Index Type' => 'Tipo de índice',
'length' => 'lonxitude',
'Column (length)' => 'Columna (lonxitude)',
'View has been dropped.' => 'Eliminouse a vista.',
'View has been altered.' => 'Modificouse a vista.',
'View has been created.' => 'Creouse a vista.',
@@ -214,6 +213,11 @@ Lang::$translations = array(
'Binary' => 'Binario',
'Lists' => 'Listas',
'Editor' => 'Editor',
'E-mail' => 'Email',
'From' => 'De',
'Subject' => 'Asunto',
'Send' => 'Enviar',
'%d e-mail(s) have been sent.' => array('%d email enviado.', '%d emails enviados.'),
'Webserver file %s' => 'Ficheiro de servidor web %s',
'File does not exist.' => 'O ficheiro non existe.',
'%d in total' => '%d en total',
@@ -248,6 +252,7 @@ Lang::$translations = array(
'Network' => 'Rede',
'Geometry' => 'Xeometría',
'File exists.' => 'O ficheiro xa existe.',
'Attachments' => 'Adxuntos',
'%d query(s) executed OK.' => array('%d consulta executada correctamente.', '%d consultas executadas correctamente.'),
'Show only errors' => 'Amosar só erros',
'Refresh' => 'Refrescar',
@@ -260,11 +265,11 @@ Lang::$translations = array(
'Permanent link' => 'Ligazón permanente',
'Edit all' => 'Editar todo',
'HH:MM:SS' => 'HH:MM:SS',
'Tables have been optimized.' => 'Optimizáronse as táboas.',
'Tables have been optimized.' => 'Optimizáronse as táboas',
'Materialized view' => 'Vista materializada',
'Vacuum' => 'Baleirar',
'Selected' => 'Selección',
'File must be in UTF-8 encoding.' => 'O ficheiro ten que estar codificado con UTF-8.',
'File must be in UTF-8 encoding.' => 'O ficheiro ten que estar codificado con UTF-8',
'Modify' => 'Modificar',
'Loading' => 'Cargando',
'Load more data' => 'Cargar máis datos',
@@ -272,17 +277,37 @@ Lang::$translations = array(
'Limit rows' => 'Limitar filas',
'Default value' => 'Valor por defecto',
'Full table scan' => 'Escaneo completo da táboa',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Demasiados intentos de conexión, intentao de novo en %d minuto.', 'Demasiados intentos de conexión, intentao de novo en %d minutos.'),
'Too many unsuccessful logins, try again in %d minute(s).' => array('Demasiados intentos de conexión, intentao de novo en %d minuto', 'Demasiados intentos de conexión, intentao de novo en %d minutos'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'O contrasinal principal caducou. <a href="https://www.adminer.org/en/extension/"%s>Implementa</a> o método %s para facelo permanente.',
'If you did not send this request from Adminer then close this page.' => 'Se non enviaches esta petición dende o Adminer entón pecha esta páxina.',
'You can upload a big SQL file via FTP and import it from server.' => 'Podes subir un ficheiro SQL de gran tamaño vía FTP e importalo dende o servidor.',
'If you did not send this request from Adminer then close this page.' => 'Se non enviaches esta petición dende o Adminer entón pecha esta páxina',
'You can upload a big SQL file via FTP and import it from server.' => 'Podes subir un ficheiro SQL de gran tamaño vía FTP e importalo dende o servidor',
'Size' => 'Tamaño',
'Compute' => 'Calcular',
'You are offline.' => 'Non tes conexión.',
'You have no privileges to update this table.' => 'Non tes privilexios para actualizar esta táboa.',
'You are offline.' => 'Non tes conexión',
'You have no privileges to update this table.' => 'Non tes privilexios para actualizar esta táboa',
'Saving' => 'Gardando',
'yes' => 'si',
'no' => 'non',
);
// 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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Si',
'No' => 'Non',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'התחברות',
'Logout successful.' => 'ההתחברות הצליחה',
'Invalid credentials.' => 'פרטי התחברות שגויים',
'Invalid server or credentials.' => null,
'Server' => 'שרת',
'Username' => 'שם משתמש',
'Password' => 'סיסמה',
@@ -32,6 +30,7 @@ Lang::$translations = array(
'Create database' => 'צור מסד נתונים',
'SQL command' => 'שאילתת SQL',
'Logout' => 'התנתק',
'database' => 'מסד נתונים',
'Use' => 'השתמש',
'No tables.' => 'אין טבלאות',
'select' => 'בחר',
@@ -95,7 +94,7 @@ Lang::$translations = array(
'ON DELETE' => 'בעת מחיקה',
'ON UPDATE' => 'בעת עידכון',
'Index Type' => 'סוג אינדקס',
'length' => 'אורך',
'Column (length)' => 'עמודה (אורך)',
'View has been dropped.' => 'התצוגה הושלכה',
'View has been altered.' => 'התצוגה שונתה',
'View has been created.' => 'התצוגה נוצרה',
@@ -212,6 +211,11 @@ Lang::$translations = array(
'Binary' => 'בינארי',
'Lists' => 'רשימות',
'Editor' => 'עורך',
'E-mail' => 'דוא"ל',
'From' => 'מ:',
'Subject' => 'נושא',
'Send' => 'שלח',
'%d e-mail(s) have been sent.' => '%d הודעות דוא"ל נשלחו',
'Webserver file %s' => 'קובץ השרת %s',
'File does not exist.' => 'הקובץ אינו קיים',
'%d in total' => '%d בסך הכל',
@@ -246,6 +250,7 @@ Lang::$translations = array(
'Network' => 'רשת',
'Geometry' => 'גיאומטריה',
'File exists.' => 'קובץ קיים',
'Attachments' => 'קבצים מצורפים',
'Item%s has been inserted.' => 'הפריט %s הוזן בהצלחה',
'now' => 'כעת',
'%d query(s) executed OK.' => '%d שאילתות בוצעו בהצלחה',
@@ -274,7 +279,7 @@ Lang::$translations = array(
'Default value' => 'ערך ברירת מחדל',
'Full table scan' => 'סריקה טבלה מלאה',
'Too many unsuccessful logins, try again in %d minute(s).' => 'יותר מידי נסיונות כניסה נכשלו, אנא נסה עוד %d דקות',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'תודה שהשתמש ב-adminer אנא שקול <a href="https://www.adminer.org/en/donation/">לתרום</a>',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'תודה שהשתמש ב-adminer אנא שקול <a href="https://www.adminer.org/en/donation/">לתרום</a>.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'סיסמת המאסטר פגה <a href="https://www.adminer.org/en/extension/"%s>התקן תוסף</a> על מנת להפוך את זה לתמידי',
'If you did not send this request from Adminer then close this page.' => 'אם לא אתה שלחת בקשה ל-Adminer הינך יכול לסגור חלון זה',
'You can upload a big SQL file via FTP and import it from server.' => 'ניתן לעלות קבצים ב-FTP ואז למשוך אותם מהשרת',
@@ -285,6 +290,24 @@ Lang::$translations = array(
'Saving' => 'שומר',
'yes' => 'כן',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Belépés',
'Logout successful.' => 'Sikeres kilépés.',
'Invalid credentials.' => 'Érvénytelen adatok.',
'Invalid server or credentials.' => null,
'Server' => 'Szerver',
'Username' => 'Felhasználó',
'Password' => 'Jelszó',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Adatbázis létrehozása',
'SQL command' => 'SQL parancs',
'Logout' => 'Kilépés',
'database' => 'adatbázis',
'Use' => 'Használ',
'No tables.' => 'Nincs tábla.',
'select' => 'kiválasztás',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'törléskor',
'ON UPDATE' => 'frissítéskor',
'Index Type' => 'Index típusa',
'length' => 'méret',
'Column (length)' => 'Oszop (méret)',
'View has been dropped.' => 'A nézet eldobva.',
'View has been altered.' => 'A nézet módosult.',
'View has been created.' => 'A nézet létrejött.',
@@ -206,6 +205,11 @@ Lang::$translations = array(
'History' => 'Történet',
'Variables' => 'Változók',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'A forrás és cél oszlopoknak azonos típusúak legyenek, a cél oszlopok indexeltek legyenek, és a hivatkozott adatnak léteznie kell.',
'E-mail' => 'E-mail',
'From' => 'Feladó',
'Subject' => 'Tárgy',
'Send' => 'Küldés',
'%d e-mail(s) have been sent.' => array('%d e-mail elküldve.', '%d e-mail elküldve.', '%d e-mail elküldve.'),
'Run file' => 'Fájl futtatása',
'Numbers' => 'Szám',
'Date and time' => 'Dátum és idő',
@@ -220,6 +224,7 @@ Lang::$translations = array(
'File does not exist.' => 'A fájl nem létezik.',
'Permanent login' => 'Emlékezz rám',
'%d in total' => 'összesen %d',
'Attachments' => 'Csatolmány',
'System' => 'Adatbázis',
'last' => 'utolsó',
'Network' => 'Hálózat',
@@ -259,6 +264,50 @@ Lang::$translations = array(
'Permanent link' => 'Hivatkozás',
'Edit all' => 'Összes szerkesztése',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem',
'Server' => 'Server',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Keluar',
'Logged as: %s' => 'Masuk sebagai: %s',
'Logout successful.' => 'Berhasil keluar.',
'Invalid credentials.' => 'Akses tidak sah.',
'Invalid server or credentials.' => null,
'Language' => 'Bahasa',
'Invalid CSRF token. Send the form again.' => 'Token CSRF tidak sah. Kirim ulang formulir.',
'No extension' => 'Ekstensi tidak ada',
@@ -75,6 +73,7 @@ Lang::$translations = array(
'Data' => 'Data',
'Database' => 'Basis data',
'database' => 'basis data',
'Use' => 'Gunakan',
'Select database' => 'Pilih basis data',
'Invalid database.' => 'Basis data tidak sah.',
@@ -184,7 +183,7 @@ Lang::$translations = array(
'Alter indexes' => 'Ubah indeks',
'Add next' => 'Tambah setelahnya',
'Index Type' => 'Jenis Indeks',
'length' => 'panjang',
'Column (length)' => 'Kolom (panjang)',
'Foreign keys' => 'Kunci asing',
'Foreign key' => 'Kunci asing',
@@ -259,6 +258,13 @@ Lang::$translations = array(
'Clone' => 'Gandakan',
'Delete' => 'Hapus',
'E-mail' => 'Surel',
'From' => 'Dari',
'Subject' => 'Judul',
'Attachments' => 'Lampiran',
'Send' => 'Kirim',
'%d e-mail(s) have been sent.' => '%d surel berhasil dikirim.',
// data type descriptions
'Numbers' => 'Angka',
'Date and time' => 'Tanggal dan waktu',
@@ -307,6 +313,46 @@ Lang::$translations = array(
'Type has been dropped.' => 'Jenis berhasil dihapus.',
'Type has been created.' => 'Jenis berhasil dibuat.',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Autenticazione',
'Logout successful.' => 'Uscita effettuata con successo.',
'Invalid credentials.' => 'Credenziali non valide.',
'Invalid server or credentials.' => 'Server o credenziali non valide.',
'Server' => 'Server',
'Username' => 'Utente',
'Password' => 'Password',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Crea database',
'SQL command' => 'Comando SQL',
'Logout' => 'Esci',
'database' => 'database',
'Use' => 'Usa',
'No tables.' => 'No tabelle.',
'select' => 'seleziona',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Tipo indice',
'length' => 'lunghezza',
'Column (length)' => 'Colonna (lunghezza)',
'View has been dropped.' => 'Vista eliminata.',
'View has been altered.' => 'Vista modificata.',
'View has been created.' => 'Vista creata.',
@@ -214,6 +213,11 @@ Lang::$translations = array(
'Binary' => 'Binari',
'Lists' => 'Liste',
'Editor' => 'Editor',
'E-mail' => 'E-mail',
'From' => 'Da',
'Subject' => 'Oggetto',
'Send' => 'Invia',
'%d e-mail(s) have been sent.' => array('%d e-mail inviata.', '%d e-mail inviate.'),
'Webserver file %s' => 'Webserver file %s',
'File does not exist.' => 'Il file non esiste.',
'%d in total' => '%d in totale',
@@ -248,6 +252,7 @@ Lang::$translations = array(
'Network' => 'Rete',
'Geometry' => 'Geometria',
'File exists.' => 'Il file esiste già.',
'Attachments' => 'Allegati',
'%d query(s) executed OK.' => array('%d query eseguita con successo.', '%d query eseguite con successo.'),
'Show only errors' => 'Mostra solo gli errori',
'Refresh' => 'Aggiorna',
@@ -260,8 +265,9 @@ Lang::$translations = array(
'Permanent link' => 'Link permanente',
'Edit all' => 'Modifica tutto',
'HH:MM:SS' => 'HH:MM:SS',
'Drop %s?' => 'Scartare %s?',
'Tables have been optimized.' => 'Le tabelle sono state ottimizzate.',
'Tables have been optimized.' => 'Le tabelle sono state ottimizzate',
'Materialized view' => 'Vista materializzata',
'Vacuum' => 'Aspira',
'Selected' => 'Selezionato',
@@ -273,12 +279,13 @@ Lang::$translations = array(
'Loading' => 'Caricamento',
'ATTACH queries are not supported.' => 'ATTACH queries non sono supportate.',
'Warnings' => 'Attenzione',
'%d / ' => '%d / ',
'%d / ' => array('%d / '),
'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>.',
'Default value' => 'Valore predefinito',
'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.'),
'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.',
'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.',
@@ -290,11 +297,17 @@ Lang::$translations = array(
'You are offline.' => 'Sei disconnesso.',
'You have no privileges to update this table.' => 'Non hai i privilegi per aggiornare questa tabella.',
'Saving' => 'Salvataggio',
'Unknown error.' => 'Errore sconosciuto.',
'Unknown error.' => 'Errore sconosciuto',
'Database does not support password.' => 'Il database non supporta password.',
'Disable %s or enable %s or %s extensions.' => 'Disabilita %s o abilita %s oppure %s estensioni.',
'yes' => 'si',
'no' => 'no',
);
// run `php ../../lang.php it` to update this file
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Si',
'No' => 'No',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

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

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'შესვლა',
'Logout successful.' => 'გამოხვედით სისტემიდან.',
'Invalid credentials.' => 'არასწორი მომხმარებელი ან პაროლი.',
'Invalid server or credentials.' => null,
'Server' => 'სერვერი',
'Username' => 'მომხმარებელი',
'Password' => 'პაროლი',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'ბაზის შექმნა',
'SQL command' => 'SQL-ბრძანება',
'Logout' => 'გასვლა',
'database' => 'ბაზა',
'Use' => 'არჩევა',
'No tables.' => 'ბაზაში ცხრილი არაა.',
'select' => 'არჩევა',
@@ -95,7 +94,7 @@ Lang::$translations = array(
'ON DELETE' => 'წაშლისას',
'ON UPDATE' => 'განახლებისას',
'Index Type' => 'ინდექსის სახეობა',
'length' => 'სიგრძე',
'Column (length)' => 'ველი (სიგრძე)',
'View has been dropped.' => 'წარმოდგენა წაიშალა.',
'View has been altered.' => 'წარმოდგენა შეიცვალა.',
'View has been created.' => 'წარმოდგენა შეიქმნა.',
@@ -210,6 +209,11 @@ Lang::$translations = array(
'Binary' => 'ორობითი',
'Lists' => 'სია',
'Editor' => 'რედაქტორი',
'E-mail' => 'ელ. ფოსტა',
'From' => 'ავტორი:',
'Subject' => 'თემა',
'Send' => 'გაგზავნა',
'%d e-mail(s) have been sent.' => 'გაიგზავნა %d წერილი.',
'Webserver file %s' => 'ფაილი %s ვებსერვერზე',
'File does not exist.' => 'ასეთი ფაილი არ არსებობს.',
'%d in total' => 'სულ %d',
@@ -244,6 +248,7 @@ Lang::$translations = array(
'Network' => 'ქსელი',
'Geometry' => 'გეომეტრია',
'File exists.' => 'ფაილი უკვე არსებობს.',
'Attachments' => 'მიმაგრებული ფაილები',
'%d query(s) executed OK.' => '%d მოთხოვნა შესრულდა.',
'Show only errors' => 'მხოლოდ შეცდომები',
'Refresh' => 'განახლება',
@@ -295,6 +300,14 @@ Lang::$translations = array(
'Unknown error.' => 'უცნობი შეცდომა.',
'Database does not support password.' => 'ბაზაში არაა მხარდაჭერილი პაროლი.',
'Disable %s or enable %s or %s extensions.' => 'გათიშეთ %s ან ჩართეთ %s ან %s გაფართოება.',
);
// run `php ../../lang.php ka` to update this file
'overwrite' => null,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,9 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'$1-$3-$5' => '$1-$3-$5',
'%.3f s' => '%.3f 초',
'%d byte(s)' => '%d 바이트',
'%d e-mail(s) have been sent.' => '%d개 메일을 보냈습니다.',
'%d in total' => '총 %d개',
'%d item(s) have been affected.' => '%d개 항목을 갱신했습니다.',
'%d process(es) have been killed.' => '%d개 프로세스를 강제 종료하였습니다.',
@@ -37,6 +36,7 @@ Lang::$translations = array(
'anywhere' => '모든',
'Are you sure?' => '실행 하시겠습니까?',
'At given time' => '지정 시간',
'Attachments' => '첨부 파일',
'Auto Increment' => '자동 증가',
'Binary' => '이진',
'Call' => '호출',
@@ -46,7 +46,7 @@ Lang::$translations = array(
'Clone' => '복제',
'collation' => '정렬',
'Collation' => '정렬',
'length' => '길이',
'Column (length)' => '열 (길이)',
'Column name' => '열 이름',
'Column' => '열',
'Comment' => '주석',
@@ -71,6 +71,7 @@ Lang::$translations = array(
'Database has been dropped.' => '데이터베이스를 삭제했습니다.',
'Database has been renamed.' => '데이터베이스의 이름을 바꾸었습니다.',
'Database schema' => '데이터베이스 구조',
'database' => '데이터베이스',
'Database' => '데이터베이스',
'Databases have been dropped.' => '데이터베이스를 삭제했습니다.',
'Date and time' => '시간',
@@ -78,6 +79,7 @@ Lang::$translations = array(
'Delete' => '삭제',
'descending' => '역순',
'Drop' => '삭제',
'E-mail' => '메일',
'Edit all' => '모두 편집',
'Edit' => '편집',
'edit' => '편집',
@@ -106,6 +108,7 @@ Lang::$translations = array(
'Foreign keys' => '외부 키',
'Format' => '형식',
'From server' => '서버에서 실행',
'From' => '보낸 사람',
'Functions' => '함수',
'Geometry' => '기하 형',
'Grant' => '권한 부여',
@@ -118,7 +121,7 @@ Lang::$translations = array(
'Indexes have been altered.' => '색인을 변경했습니다.',
'Indexes' => '색인',
'Insert' => '삽입',
'Invalid credentials.' => '잘못된 로그인.',
'Invalid server or credentials.' => null,
'Invalid CSRF token. Send the form again.' => '잘못된 CSRF 토큰입니다. 다시 보내주십시오.',
'Invalid database.' => '잘못된 데이터베이스입니다.',
'Invalid schema.' => '잘못된 스키마입니다.',
@@ -139,7 +142,7 @@ Lang::$translations = array(
'Logout successful.' => '로그아웃을 성공했습니다.',
'Logout' => '로그아웃',
'ltr' => 'ltr',
'Maximum allowed file size is %sB.' => '파일의 최대 크기 %sB.',
'Maximum allowed file size is %sB.' => '파일의 최대 크기 %sB',
'Maximum number of allowed fields exceeded. Please increase %s.' => '정의 가능한 최대 필드 수를 초과했습니다. %s(을)를 늘리십시오.',
'Modify' => '수정',
'Move down' => '아래로',
@@ -150,7 +153,7 @@ Lang::$translations = array(
'Network' => '네트워크 형',
'New item' => '항목 만들기',
'No commands to execute.' => '실행할 수 있는 명령이 없습니다.',
'No extension' => '확장이 없습니다',
'No extension' => '확장이 없습니다.',
'No rows.' => '행이 없습니다.',
'No tables.' => '테이블이 없습니다.',
'None of the supported PHP extensions (%s) are available.' => 'PHP 확장(%s)이 설치되어 있지 않습니다.',
@@ -202,11 +205,12 @@ Lang::$translations = array(
'Schema' => '스키마',
'Search data in tables' => '테이블 내 데이터 검색',
'Search' => '검색',
'Select data' => '데이터를 선택하십시오',
'Select database' => '데이터베이스를 선택하십시오',
'Select data' => '데이터를 선택하십시오.',
'Select database' => '데이터베이스를 선택하십시오.',
'Select' => '선택',
'select' => '선택',
'Selected' => '선택됨',
'Send' => '보내기',
'Sequence has been altered.' => '시퀀스를 변경했습니다.',
'Sequence has been created.' => '시퀀스를 추가했습니다.',
'Sequence has been dropped.' => '시퀀스를 제거했습니다.',
@@ -225,6 +229,7 @@ Lang::$translations = array(
'Status' => '상태',
'Stop on error' => '오류의 경우 중지',
'Strings' => '문자열',
'Subject' => '제목',
'System' => '데이터베이스 형식',
'Table has been altered.' => '테이블을 변경했습니다.',
'Table has been created.' => '테이블을 만들었습니다.',
@@ -232,7 +237,7 @@ Lang::$translations = array(
'Table name' => '테이블 이름',
'Table' => '테이블',
'Tables and views' => '테이블과 뷰',
'Tables have been copied.' => '테이블을 복사했습니다.',
'Tables have been copied.' => '테이블을 복사했습니다',
'Tables have been dropped.' => '테이블을 삭제했습니다.',
'Tables have been moved.' => '테이블을 옮겼습니다.',
'Tables have been truncated.' => '테이블의 데이터 내용만 지웠습니다.',
@@ -250,7 +255,7 @@ Lang::$translations = array(
'Type has been created.' => '유형을 추가했습니다.',
'Type has been dropped.' => '유형을 삭제했습니다.',
'Type' => '형',
'Unable to select the table' => '테이블을 선택할 수 없습니다',
'Unable to select the table' => '테이블을 선택할 수 없습니다.',
'Unable to upload a file.' => '파일을 업로드 할 수 없습니다.',
'Use edit link to modify this value.' => '이 값을 수정하려면 편집 링크를 사용하십시오.',
'Use' => '사용',
@@ -272,6 +277,37 @@ Lang::$translations = array(
'You are offline.' => '오프라인입니다.',
'You can upload a big SQL file via FTP and import it from server.' => '큰 SQL 파일은 FTP를 통하여 업로드하여 서버에서 가져올 수 있습니다.',
'You have no privileges to update this table.' => '이 테이블을 업데이트할 권한이 없습니다.',
);
// run `php ../../lang.php ko` to update this file
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistema',
'Server' => 'Serveris',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Atsijungti',
'Logged as: %s' => 'Prisijungęs kaip: %s',
'Logout successful.' => 'Jūs atsijungėte nuo sistemos.',
'Invalid credentials.' => 'Neteisingi prisijungimo duomenys.',
'Invalid server or credentials.' => null,
'Language' => 'Kalba',
'Invalid CSRF token. Send the form again.' => 'Neteisingas CSRF tokenas. Bandykite siųsti formos duomenis dar kartą.',
'No extension' => 'Nėra plėtiio',
@@ -75,6 +73,7 @@ Lang::$translations = array(
'Data' => 'Duomenys',
'Database' => 'Duomenų bazė',
'database' => 'duomenų bazė',
'Use' => 'Naudoti',
'Select database' => 'Pasirinkti duomenų bazę',
'Invalid database.' => 'Neteisinga duomenų bazė.',
@@ -183,7 +182,7 @@ Lang::$translations = array(
'Alter indexes' => 'Redaguoti indeksus',
'Add next' => 'Pridėti kitą',
'Index Type' => 'Indekso tipas',
'length' => 'ilgis',
'Column (length)' => 'Stulpelis (ilgis)',
'Foreign keys' => 'Išoriniai raktai',
'Foreign key' => 'Išorinis raktas',
@@ -257,6 +256,13 @@ Lang::$translations = array(
'Clone' => 'Klonuoti',
'Delete' => 'Trinti',
'E-mail' => 'El. paštas',
'From' => 'Nuo',
'Subject' => 'Antraštė',
'Attachments' => 'Priedai',
'Send' => 'Siųsti',
'%d e-mail(s) have been sent.' => array('Išsiųstas %d laiškas.', 'Išsiųsti %d laiškai.', 'Išsiųsta %d laiškų.'),
// data type descriptions
'Numbers' => 'Skaičiai',
'Date and time' => 'Data ir laikas',
@@ -303,6 +309,50 @@ Lang::$translations = array(
'Type has been dropped.' => 'Tipas pašalintas.',
'Type has been created.' => 'Tipas sukurtas.',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Ieiet',
'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',
'Username' => 'Lietotājs',
'Password' => 'Parole',
@@ -33,12 +31,13 @@ Lang::$translations = array(
'Create database' => 'Izveidot datubāzi',
'SQL command' => 'SQL pieprasījums',
'Logout' => 'Iziet',
'database' => 'datubāze',
'Use' => 'Lietot',
'No tables.' => 'Datubāzē nav tabulu.',
'select' => 'izvēlēties',
'Item has been deleted.' => 'Ieraksts dzests.',
'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',
'Insert' => 'Ievietot',
'Save and insert next' => 'Saglabāt un ievietot nākamo',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'Pie dzēšanas',
'ON UPDATE' => 'Pie atjaunošanas',
'Index Type' => 'Indeksa tips',
'length' => 'garums',
'Column (length)' => 'Lauks (garums)',
'View has been dropped.' => 'Skats dzēsts.',
'View has been altered.' => 'Skats izmainīts.',
'View has been created.' => 'Skats izveidots.',
@@ -214,6 +213,11 @@ Lang::$translations = array(
'Binary' => 'Binārie',
'Lists' => 'Saraksti',
'Editor' => 'Redaktors',
'E-mail' => 'Epasts',
'From' => 'No',
'Subject' => 'Tēma',
'Send' => 'Sūtīt',
'%d e-mail(s) have been sent.' => array('Nosūtīts %d epasts.', 'Nosūtīti %d epasti.', 'Nosūtīti %d epasti.'),
'Webserver file %s' => 'Fails %s uz servera',
'File does not exist.' => 'Fails neeksistē.',
'%d in total' => 'Kopā %d',
@@ -238,7 +242,7 @@ Lang::$translations = array(
'Type has been dropped.' => 'Tips dzēsts.',
'Type has been created.' => 'Tips izveidots.',
'Ctrl+click on a value to modify it.' => 'Lai izmainītu vērtību, izmanto Ctrl + peles klikšķi.',
'Use edit link to modify this value.' => 'Izmainīt vērtību var tikai ar saiti \'Izmainīt\'.',
'Use edit link to modify this value.' => 'Izmainīt vērtību var tikai ar saiti "Izmainīt".',
'last' => 'pēdējā',
'From server' => 'No servera',
'System' => 'Sistēma',
@@ -248,6 +252,7 @@ Lang::$translations = array(
'Network' => 'Tīkls',
'Geometry' => 'Ģeometrija',
'File exists.' => 'Fails eksistē.',
'Attachments' => 'Pielikumi',
'%d query(s) executed OK.' => array('%d pieprasījums veiksmīgs.', '%d pieprasījumi veiksmīgi.', '%d pieprasījumi veiksmīgi.'),
'Show only errors' => 'Rādīt tikai kļūdas',
'Refresh' => 'Atjaunot',
@@ -280,10 +285,10 @@ Lang::$translations = array(
'Size' => 'Izmērs',
'Compute' => 'Izskaitļot',
'You are offline.' => 'Jūs est bezsasaistē.',
'You have no privileges to update this table.' => 'jums nav pieejas labot šo tabulu.',
'You have no privileges to update this table.' => 'Jums nav pieejas labot šo tabulu.',
'Saving' => 'Saglabāšana',
'yes' => 'Jā',
'no' => 'Nē',
'yes' => 'jā',
'no' => 'nē',
'Drop %s?' => 'Dzēst %s?',
'overwrite' => 'pārrakstīt',
'DB' => 'DB',
@@ -295,6 +300,14 @@ 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.',
'Unknown error.' => 'Nezināma kļūda.',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Jā',
'No' => 'Nē',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem',
'Server' => 'Pelayan',
@@ -13,7 +11,7 @@ Lang::$translations = array(
'Logged as: %s' => 'Log masuk sebagai: %s',
'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>.',
'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.',
'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',
@@ -84,6 +82,7 @@ Lang::$translations = array(
'Data' => 'Data',
'Database' => 'Pangkalan data',
'database' => 'pangkalan data',
'Use' => 'Guna',
'Select database' => 'Pilih pangkalan data',
'Invalid database.' => 'Pangkalan data tidak sah.',
@@ -199,7 +198,7 @@ Lang::$translations = array(
'Alter indexes' => 'Ubah indeks',
'Add next' => 'Tambah yang seterusnya',
'Index Type' => 'Jenis Indeks',
'length' => 'kepanjangan',
'Column (length)' => 'Kolum (kepanjangan)',
'Foreign keys' => 'Kunci asing',
'Foreign key' => 'Kunci asing',
@@ -283,6 +282,13 @@ Lang::$translations = array(
'Delete' => 'Padam',
'You have no privileges to update this table.' => 'Anda tidak mempunyai keistimewaan untuk mengemaskini jadual ini.',
'E-mail' => 'Emel',
'From' => 'Dari',
'Subject' => 'Subjek',
'Attachments' => 'Lampiran',
'Send' => 'Hantar',
'%d e-mail(s) have been sent.' => '%d emel telah dihantar.',
// data type descriptions
'Numbers' => 'Nombor',
'Date and time' => 'Tarikh dan masa',
@@ -331,6 +337,22 @@ Lang::$translations = array(
'Type has been dropped.' => 'Jenis telah dijatuhkan.',
'Type has been created.' => 'Jenis telah dibuat.',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Ya',
'No' => 'Tidak',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Aanmelden',
'Logout successful.' => 'Successvol afgemeld.',
'Invalid credentials.' => 'Ongeldige gebruikersgegevens.',
'Invalid server or credentials.' => null,
'Server' => 'Server',
'Username' => 'Gebruikersnaam',
'Password' => 'Wachtwoord',
@@ -34,6 +32,7 @@ Lang::$translations = array(
'Create database' => 'Database aanmaken',
'SQL command' => 'SQL opdracht',
'Logout' => 'Afmelden',
'database' => 'database',
'Use' => 'Gebruik',
'No tables.' => 'Geen tabellen.',
'select' => 'kies',
@@ -98,7 +97,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Index type',
'length' => 'lengte',
'Column (length)' => 'Kolom (lengte)',
'View has been dropped.' => 'View verwijderd.',
'View has been altered.' => 'View aangepast.',
'View has been created.' => 'View aangemaakt.',
@@ -215,6 +214,11 @@ Lang::$translations = array(
'Binary' => 'Binaire gegevens',
'Lists' => 'Lijsten',
'Editor' => 'Editor',
'E-mail' => 'E-mail',
'From' => 'Van',
'Subject' => 'Onderwerp',
'Send' => 'Verzenden',
'%d e-mail(s) have been sent.' => array('%d e-mail verzonden.', '%d e-mails verzonden.'),
'Webserver file %s' => 'Webserver bestand %s',
'File does not exist.' => 'Bestand niet gevonden.',
'%d in total' => '%d in totaal',
@@ -238,7 +242,7 @@ Lang::$translations = array(
'Type has been dropped.' => 'Type verwijderd.',
'Type has been created.' => 'Type aangemaakt.',
'Ctrl+click on a value to modify it.' => 'Ctrl+klik op een waarde om deze te bewerken.',
'Use edit link to modify this value.' => 'Gebruik de link \'bewerk\' om deze waarde te wijzigen.',
'Use edit link to modify this value.' => 'Gebruik de link "bewerk" om deze waarde te wijzigen.',
'last' => 'laatste',
'From server' => 'Van server',
'System' => 'Databasesysteem',
@@ -248,7 +252,8 @@ Lang::$translations = array(
'Network' => 'Netwerk',
'Geometry' => 'Geometrie',
'File exists.' => 'Bestand bestaat reeds.',
'%d query(s) executed OK.' => array('%d query succesvol uitgevoerd.', '%d querys succesvol uitgevoerd.'),
'Attachments' => 'Bijlagen',
'%d query(s) executed OK.' => array('%d query succesvol uitgevoerd.', '%d querys succesvol uitgevoerd'),
'Show only errors' => 'Enkel fouten tonen',
'Refresh' => 'Vernieuwen',
'Invalid schema.' => 'Ongeldig schema.',
@@ -260,6 +265,7 @@ Lang::$translations = array(
'Permanent link' => 'Permanente link',
'Edit all' => 'Alles bewerken',
'HH:MM:SS' => 'HH:MM:SS',
'Drop %s?' => 'Verwijder %s?',
'Tables have been optimized.' => 'Tabellen zijn geoptimaliseerd.',
'Materialized view' => 'Materialized view',
@@ -271,7 +277,7 @@ Lang::$translations = array(
'Modify' => 'Aanpassen',
'Load more data' => 'Meer data inladen',
'Loading' => 'Aan het laden',
'ATTACH queries are not supported.' => 'ATTACH queries worden niet ondersteund.',
'ATTACH queries are not supported.' => 'ATTACH queries worden niet ondersteund',
'Warnings' => 'Waarschuwingen',
'%d / ' => '%d / ',
'Limit rows' => 'Rijen beperken',
@@ -279,8 +285,9 @@ Lang::$translations = array(
'Default value' => 'Standaardwaarde',
'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.'),
'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.',
'The action will be performed after successful login with the same credentials.' => 'Deze actie zal uitgevoerd worden na het succesvol aanmelden met dezelfde gebruikersgegevens.',
'The action will be performed after successful login with the same credentials.' => 'Deze actie zal uitgevoerd worden na het succesvol aanmelden met dezelfde gebruikersgegevens',
'Connecting to privileged ports is not allowed.' => 'Verbindingen naar geprivilegieerde poorten is niet toegestaan.',
'There is a space in the input password which might be the cause.' => 'Er staat een spatie in het wachtwoord, wat misschien de oorzaak is.',
'If you did not send this request from Adminer then close this page.' => 'Als u deze actie niet via Adminer hebt gedaan, gelieve deze pagina dan te sluiten.',
@@ -290,11 +297,17 @@ Lang::$translations = array(
'You are offline.' => 'U bent offline.',
'You have no privileges to update this table.' => 'U bent niet gemachtigd om deze tabel aan te passen.',
'Saving' => 'Opslaan',
'Unknown error.' => 'Onbekende fout.',
'Unknown error.' => 'Onbekende fout',
'Database does not support password.' => 'Database ondersteunt het wachtwoord niet.',
'Disable %s or enable %s or %s extensions.' => 'Schakel %s uit or schakel extensies %s of %s in.',
'yes' => 'ja',
'no' => 'neen',
);
// run `php ../../lang.php nl` to update this file
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Ja',
'No' => 'Neen',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'System' => 'System',
'Server' => 'Server',
'Username' => 'Brukernavn',
@@ -11,7 +9,7 @@ Lang::$translations = array(
'Logout' => 'Logg ut',
'Logged as: %s' => 'Logget inn som: %s',
'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.',
'Language' => 'Språk',
'Invalid CSRF token. Send the form again.' => 'Ugylding CSRF-token - Send inn skjemaet igjen.',
@@ -66,6 +64,7 @@ Lang::$translations = array(
'Format' => 'Format',
'Data' => 'Data',
'Database' => 'Database',
'database' => 'database',
'Use' => 'Bruk',
'Select database' => 'Velg database',
'Invalid database.' => 'Ugyldig database.',
@@ -166,7 +165,7 @@ Lang::$translations = array(
'Alter indexes' => 'Endre indekser',
'Add next' => 'Legg til neste',
'Index Type' => 'Indekstype',
'length' => 'lengde',
'Column (length)' => 'Kolonne (lengde)',
'Foreign keys' => 'Fremmednøkler',
'Foreign key' => 'Fremmednøkkel',
'Foreign key has been dropped.' => 'Fremmednøkkelen er slettet.',
@@ -238,6 +237,12 @@ Lang::$translations = array(
'Clone' => 'Klon',
'Delete' => 'Slett',
'You have no privileges to update this table.' => 'Du mangler rettighetene som trengs for å endre denne tabellen.',
'E-mail' => 'E-post',
'From' => 'Fra',
'Subject' => 'Tittel',
'Attachments' => 'Vedlegg',
'Send' => 'Send',
'%d e-mail(s) have been sent.' => array('%d epost sendt.', '%d eposter sendt.'),
'Numbers' => 'Nummer',
'Date and time' => 'Dato og tid',
'Strings' => 'Strenger',
@@ -274,6 +279,35 @@ Lang::$translations = array(
'Type has been created.' => 'Type er opprettet.',
'Alter type' => 'Endre type',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Ja',
'No' => 'Nei',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

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

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Entrar',
'Logout successful.' => 'Saída bem sucedida.',
'Invalid credentials.' => 'Identificação inválida.',
'Invalid server or credentials.' => null,
'Server' => 'Servidor',
'Username' => 'Usuário',
'Password' => 'Senha',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Criar Base de dados',
'SQL command' => 'Comando SQL',
'Logout' => 'Sair',
'database' => 'base de dados',
'Use' => 'Usar',
'No tables.' => 'Não existem tabelas.',
'select' => 'selecionar',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Tipo de índice',
'length' => 'tamanho',
'Column (length)' => 'Coluna (tamanho)',
'View has been dropped.' => 'A Visão foi apagada.',
'View has been altered.' => 'A Visão foi alterada.',
'View has been created.' => 'A Visão foi criada.',
@@ -214,6 +213,11 @@ Lang::$translations = array(
'Binary' => 'Binário',
'Lists' => 'Listas',
'Editor' => 'Editor',
'E-mail' => 'E-mail',
'From' => 'De',
'Subject' => 'Assunto',
'Send' => 'Enviar',
'%d e-mail(s) have been sent.' => array('%d email foi enviado.', '%d emails foram enviados.'),
'Webserver file %s' => 'Arquivo do servidor web %s',
'File does not exist.' => 'Arquivo não existe.',
'%d in total' => '%d no total',
@@ -248,6 +252,7 @@ Lang::$translations = array(
'Network' => 'Rede',
'Geometry' => 'Geometria',
'File exists.' => 'Arquivo já existe.',
'Attachments' => 'Anexos',
'%d query(s) executed OK.' => array('%d consulta sql executada corretamente.', '%d consultas sql executadas corretamente.'),
'Show only errors' => 'Mostrar somente erros',
'Refresh' => 'Atualizar',
@@ -255,6 +260,54 @@ Lang::$translations = array(
'Please use one of the extensions %s.' => 'Por favor use uma das extensões %s.',
'now' => 'agora',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Entrar',
'Logout successful.' => 'Sessão terminada com sucesso.',
'Invalid credentials.' => 'Identificação inválida.',
'Invalid server or credentials.' => null,
'Server' => 'Servidor',
'Username' => 'Nome de utilizador',
'Password' => 'Senha',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Criar Base de dados',
'SQL command' => 'Comando SQL',
'Logout' => 'Terminar sessão',
'database' => 'base de dados',
'Use' => 'Usar',
'No tables.' => 'Não existem tabelas.',
'select' => 'registos',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Tipo de índice',
'length' => 'tamanho',
'Column (length)' => 'coluna (tamanho)',
'View has been dropped.' => 'Vista eliminada.',
'View has been altered.' => 'Vista modificada.',
'View has been created.' => 'Vista criada.',
@@ -214,6 +213,11 @@ Lang::$translations = array(
'Binary' => 'Binário',
'Lists' => 'Listas',
'Editor' => 'Editor',
'E-mail' => 'E-mail',
'From' => 'De',
'Subject' => 'Assunto',
'Send' => 'Enviar',
'%d e-mail(s) have been sent.' => array('%d email enviado.', '%d emails enviados.'),
'Webserver file %s' => 'Ficheiro do servidor web %s',
'File does not exist.' => 'Ficheiro não existe.',
'%d in total' => '%d no total',
@@ -248,6 +252,7 @@ Lang::$translations = array(
'Network' => 'Rede',
'Geometry' => 'Geometria',
'File exists.' => 'Ficheiro já existe.',
'Attachments' => 'Anexos',
'%d query(s) executed OK.' => array('%d consulta sql executada corretamente.', '%d consultas sql executadas corretamente.'),
'Show only errors' => 'Mostrar somente erros',
'Refresh' => 'Atualizar',
@@ -255,6 +260,54 @@ Lang::$translations = array(
'Please use one of the extensions %s.' => 'Por favor use uma das extensões %s.',
'now' => 'agora',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Intră',
'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',
'Username' => 'Nume de utilizator',
'Password' => 'Parola',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Crează baza de date',
'SQL command' => 'SQL query',
'Logout' => 'Ieșire',
'database' => 'baza de date',
'Use' => 'Alege',
'No tables.' => 'În baza de date nu sunt tabele.',
'select' => 'selectează',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'La ștergere',
'ON UPDATE' => 'La modificare',
'Index Type' => 'Tipul indexului',
'length' => 'lungimea',
'Column (length)' => 'Coloană (lungimea)',
'View has been dropped.' => 'Reprezentarea a fost ștearsă.',
'View has been altered.' => 'Reprezentarea a fost modificată.',
'View has been created.' => 'Reprezentarea a fost creată.',
@@ -214,6 +213,11 @@ Lang::$translations = array(
'Binary' => 'Tip binar',
'Lists' => 'Liste',
'Editor' => 'Editor',
'E-mail' => 'Poșta electronică',
'From' => 'De la',
'Subject' => 'Pentru',
'Send' => 'Trimite',
'%d e-mail(s) have been sent.' => array('A fost trimis %d mail.', 'Au fost trimise %d mail-uri.'),
'Webserver file %s' => 'Fișierul %s pe server',
'File does not exist.' => 'Acest fișier nu există.',
'%d in total' => 'În total %d',
@@ -248,6 +252,7 @@ Lang::$translations = array(
'Network' => 'Rețea',
'Geometry' => 'Geometrie',
'File exists.' => 'Fișierul există deja.',
'Attachments' => 'Fișiere atașate',
'%d query(s) executed OK.' => array('%d query executat.', '%d query-uri executate cu succes.'),
'Show only errors' => 'Arată doar greșeli',
'Refresh' => 'Împrospătează',
@@ -255,11 +260,54 @@ Lang::$translations = array(
'Please use one of the extensions %s.' => 'Folosiți una din următoarele extensii %s.',
'now' => 'acum',
'ltr' => 'ltr',
'Tables have been copied.' => 'Tabelele au fost copiate.',
'Tables have been copied.' => 'Tabelele au fost copiate',
'Copy' => 'Copiază',
'Permanent link' => 'Adresă permanentă',
'Edit all' => 'Editează tot',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Войти',
'Logout successful.' => 'Вы успешно покинули систему.',
'Invalid credentials.' => 'Неправильное имя пользователя или пароль.',
'Invalid server or credentials.' => null,
'Server' => 'Сервер',
'Username' => 'Имя пользователя',
'Password' => 'Пароль',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'Создать базу данных',
'SQL command' => 'SQL-запрос',
'Logout' => 'Выйти',
'database' => 'база данных',
'Use' => 'Выбрать',
'No tables.' => 'В базе данных нет таблиц.',
'select' => 'выбрать',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'При стирании',
'ON UPDATE' => 'При обновлении',
'Index Type' => 'Тип индекса',
'length' => 'длина',
'Column (length)' => 'Поле (длина)',
'View has been dropped.' => 'Представление было удалено.',
'View has been altered.' => 'Представление было изменено.',
'View has been created.' => 'Представление было создано.',
@@ -214,6 +213,11 @@ Lang::$translations = array(
'Binary' => 'Двоичный тип',
'Lists' => 'Списки',
'Editor' => 'Редактор',
'E-mail' => 'Эл. почта',
'From' => 'От',
'Subject' => 'Тема',
'Send' => 'Послать',
'%d e-mail(s) have been sent.' => array('Было отправлено %d письмо.', 'Было отправлено %d письма.', 'Было отправлено %d писем.'),
'Webserver file %s' => 'Файл %s на вебсервере',
'File does not exist.' => 'Такого файла не существует.',
'%d in total' => 'Всего %d',
@@ -248,6 +252,7 @@ Lang::$translations = array(
'Network' => 'Сеть',
'Geometry' => 'Геометрия',
'File exists.' => 'Файл уже существует.',
'Attachments' => 'Прикреплённые файлы',
'%d query(s) executed OK.' => array('%d запрос выполнен успешно.', '%d запроса выполнено успешно.', '%d запросов выполнено успешно.'),
'Show only errors' => 'Только ошибки',
'Refresh' => 'Обновить',
@@ -282,8 +287,8 @@ Lang::$translations = array(
'You are offline.' => 'Вы не выполнили вход.',
'You have no privileges to update this table.' => 'У вас нет прав на обновление этой таблицы.',
'Saving' => 'Сохранение',
'yes' => 'Да',
'no' => 'Нет',
'yes' => 'да',
'no' => 'нет',
'Drop %s?' => 'Удалить %s?',
'overwrite' => 'перезаписать',
'DB' => 'DB',
@@ -295,16 +300,14 @@ Lang::$translations = array(
'There is a space in the input password which might be the cause.' => 'В введеном пароле есть пробел, это может быть причиною.',
'Unknown error.' => 'Неизвестная ошибка.',
'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.',
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Да',
'No' => 'Нет',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'Prihlásiť sa',
'Logout successful.' => 'Odhlásenie prebehlo v poriadku.',
'Invalid credentials.' => 'Neplatné prihlasovacie údaje.',
'Invalid server or credentials.' => 'Neplatný server alebo prihlasovacie údaje.',
'Server' => 'Server',
'Username' => 'Používateľ',
'Password' => 'Heslo',
@@ -34,6 +32,7 @@ Lang::$translations = array(
'Create database' => 'Vytvoriť databázu',
'SQL command' => 'SQL príkaz',
'Logout' => 'Odhlásiť',
'database' => 'databáza',
'Use' => 'Vybrať',
'No tables.' => 'Žiadne tabuľky.',
'select' => 'vypísať',
@@ -98,7 +97,7 @@ Lang::$translations = array(
'ON DELETE' => 'Pri zmazaní',
'ON UPDATE' => 'Pri aktualizácii',
'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 altered.' => 'Pohľad bol zmenený.',
'View has been created.' => 'Pohľad bol vytvorený.',
@@ -205,6 +204,11 @@ Lang::$translations = array(
'History' => 'História',
'Variables' => 'Premenné',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'Zdrojové a cieľové stĺpce musia mať rovnaký datový typ, nad cieľovými stĺpcami musí byť definovaný index a odkazované dáta musia existovať.',
'E-mail' => 'E-mail',
'From' => 'Odosielateľ',
'Subject' => 'Predmet',
'Send' => 'Odoslať',
'%d e-mail(s) have been sent.' => array('Bol odoslaný %d e-mail.', 'Boli odoslané %d e-maily.', 'Bolo odoslaných %d e-mailov.'),
'Run file' => 'Spustiť súbor',
'Numbers' => 'Čísla',
'Date and time' => 'Dátum a čas',
@@ -248,6 +252,7 @@ Lang::$translations = array(
'Network' => 'Sieť',
'Geometry' => 'Geometria',
'File exists.' => 'Súbor existuje.',
'Attachments' => 'Prílohy',
'%d query(s) executed OK.' => array('Bol vykonaný %d dotaz.', 'Boli vykonané %d dotazy.', 'Bolo vykonaných %d dotazov.'),
'Show only errors' => 'Zobraziť iba chyby',
'Refresh' => 'Obnoviť',
@@ -269,21 +274,21 @@ Lang::$translations = array(
'DB' => 'DB',
'File must be in UTF-8 encoding.' => 'Súbor musí byť v kódovaní UTF-8.',
'Modify' => 'Zmeniť',
'Load more data' => 'Načítať ďalšie dáta',
'Loading' => 'Načítava sa',
'Load more data' => 'Nahráť ďalšie dáta',
'Loading' => 'Nahráva sa',
'ATTACH queries are not supported.' => 'Dotazy ATTACH nie sú podporované.',
'Warnings' => 'Varovania',
'%d / ' => '%d / ',
'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',
'Full table scan' => 'Prechod celej tabuľky',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Príliš veľa pokusov o prihlásenie, skúste to znova za %d minutu.', 'Príliš veľa pokusov o prihlásenie, skúste to znova za %d minuty.', 'Príliš veľa pokusov o prihlásenie, skúste to znova za %d minút.'),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Vďaka za používanie Admineru, <a href="https://www.adminer.org/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.',
'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é.',
'There is a space in the input password which might be the cause.' => 'V zadanom hesle je medzera, ktorá môže byť príčinou.',
'There is a space in the input password which might be the cause.' => 'V zadanom hesle je medzera, ktorá môže byť príčinou.',
'If you did not send this request from Adminer then close this page.' => 'Pokiaľ ste tento požiadavok neodoslali z Adminera, zatvorte túto stránku.',
'You can upload a big SQL file via FTP and import it from server.' => 'Veľký SQL soubor môžete nahrať pomocou FTP a importovať ho zo servera.',
'Size' => 'Veľkosť',
@@ -296,12 +301,11 @@ Lang::$translations = array(
'Disable %s or enable %s or %s extensions.' => 'Zakážte %s alebo povoľte rozšírenie %s alebo %s.',
'yes' => 'áno',
'no' => 'nie',
'Checks' => 'Kontroly',
'Create check' => 'Vytvoriť kontrolu',
'Alter check' => 'Zmeniť kontrolu',
'Check has been created.' => 'Kontrola bola vytvorená.',
'Check has been altered.' => 'Kontrola bola zmenená.',
'Check has been dropped.' => 'Kontrola bola odstránená.',
'Yes' => 'Áno',
'No' => 'Nie',
'Columns' => 'Stĺpce',
'Nullable' => 'Povolené null',
'Default' => 'Predvolené',
'One Time Password' => 'Jednorázové heslo',
'Invalid OTP code.' => 'Neplatný kód OTP.',
);
// run `php ../../lang.php sk` to update this file

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem',
'Server' => 'Strežnik',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Odjavi se',
'Logged as: %s' => 'Prijavljen kot: %s',
'Logout successful.' => 'Prijava uspešna.',
'Invalid credentials.' => 'Neveljavne pravice.',
'Invalid server or credentials.' => 'Neveljaven strežnik ali pravice.',
'Language' => 'Jezik',
'Invalid CSRF token. Send the form again.' => 'Neveljaven token CSRF. Pošljite formular še enkrat.',
'No extension' => 'Brez dodatkov',
@@ -74,6 +72,7 @@ Lang::$translations = array(
'Data' => 'Podatki',
'Database' => 'Baza',
'database' => 'baza',
'Use' => 'Uporabi',
'Select database' => 'Izberi bazo',
'Invalid database.' => 'Neveljavna baza.',
@@ -179,7 +178,7 @@ Lang::$translations = array(
'Alter indexes' => 'Spremeni indekse',
'Add next' => 'Dodaj naslednjega',
'Index Type' => 'Tip indeksa',
'length' => 'dolžina',
'Column (length)' => 'Stolpec (dolžina)',
'Foreign keys' => 'Tuji ključi',
'Foreign key' => 'Tuj ključ',
@@ -254,6 +253,13 @@ Lang::$translations = array(
'Clone' => 'Kloniraj',
'Delete' => 'Izbriši',
'E-mail' => 'E-mail',
'From' => 'Od',
'Subject' => 'Zadeva',
'Attachments' => 'Priponke',
'Send' => 'Pošlji',
'%d e-mail(s) have been sent.' => array('Poslan je %d e-mail.', 'Poslana sta %d e-maila.', 'Poslani so %d e-maili.', 'Poslanih je %d e-mailov.'),
// data type descriptions
'Numbers' => 'Števila',
'Date and time' => 'Datum in čas',
@@ -298,6 +304,52 @@ Lang::$translations = array(
'Type has been dropped.' => 'Tip je zavržen.',
'Type has been created.' => 'Tip je ustvarjen.',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Систем',
'Server' => 'Сервер',
@@ -12,11 +10,11 @@ Lang::$translations = array(
'Logout' => 'Одјава',
'Logged as: %s' => 'Пријави се као: %s',
'Logout successful.' => 'Успешна одјава.',
'Invalid credentials.' => 'Неважеће дозволе.',
'Invalid server or credentials.' => null,
'Language' => 'Језик',
'Invalid CSRF token. Send the form again.' => 'Неважећи CSRF код. Проследите поново форму.',
'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 expired, please login again.' => 'Ваша сесија је истекла, пријавите се поново.',
'%s version: %s through PHP extension %s' => '%s верзија: %s помоћу PHP додатка је %s',
@@ -75,6 +73,7 @@ Lang::$translations = array(
'Data' => 'Податци',
'Database' => 'База података',
'database' => 'база података',
'Use' => 'Користи',
'Select database' => 'Изаберите базу',
'Invalid database.' => 'Неисправна база података.',
@@ -184,7 +183,7 @@ Lang::$translations = array(
'Alter indexes' => 'Уреди индексе',
'Add next' => 'Додај следећи',
'Index Type' => 'Тип индекса',
'length' => 'дужина',
'Column (length)' => 'Колона (дужина)',
'Foreign keys' => 'Страни кључеви',
'Foreign key' => 'Страни кључ',
@@ -262,6 +261,13 @@ Lang::$translations = array(
'Clone' => 'Дуплирај',
'Delete' => 'Избриши',
'E-mail' => 'Ел. пошта',
'From' => 'Од',
'Subject' => 'Наслов',
'Attachments' => 'Прилози',
'Send' => 'Пошаљи',
'%d e-mail(s) have been sent.' => array('%d порука ел. поште је послата.', '%d поруке ел. поште су послате.', '%d порука ел. поште је послато.'),
// data type descriptions
'Numbers' => 'Број',
'Date and time' => 'Датум и време',
@@ -310,6 +316,43 @@ Lang::$translations = array(
'Type has been dropped.' => 'Тип је избрисан.',
'Type has been created.' => 'тип је креиран.',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Да',
'No' => 'Не',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'System',
'Server' => 'Server',
@@ -13,7 +11,7 @@ Lang::$translations = array(
'Logged as: %s' => 'Inloggad som: %s',
'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>.',
'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.',
'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.',
@@ -91,6 +89,7 @@ Lang::$translations = array(
'Data' => 'Data',
'Database' => 'Databas',
'database' => 'databas',
'DB' => 'DB',
'Use' => 'Använd',
'Select database' => 'Välj databas',
@@ -208,7 +207,7 @@ Lang::$translations = array(
'Alter indexes' => 'Ändra index',
'Add next' => 'Lägg till nästa',
'Index Type' => 'Indextyp',
'length' => 'längd',
'Column (length)' => 'Kolumn (längd)',
'Foreign keys' => 'Främmande nycklar',
'Foreign key' => 'Främmande nyckel',
@@ -292,6 +291,13 @@ Lang::$translations = array(
'Delete' => 'Ta bort',
'You have no privileges to update this table.' => 'Du har inga privilegier för att uppdatera den här tabellen.',
'E-mail' => 'Email',
'From' => 'Från',
'Subject' => 'Ämne',
'Attachments' => 'Bilagor',
'Send' => 'Skicka',
'%d e-mail(s) have been sent.' => array('%d email har blivit skickat.', '%d email har blivit skickade.'),
// data type descriptions
'Numbers' => 'Nummer',
'Date and time' => 'Datum och tid',
@@ -340,6 +346,12 @@ Lang::$translations = array(
'Type has been dropped.' => 'Typ har, typ, tagits bort.',
'Type has been created.' => 'Typ har skapats.',
'Alter type' => 'Ändra typ',
);
// run `php ../../lang.php sv` to update this file
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Ja',
'No' => 'Nej',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'நுழை',
'Logout successful.' => 'வெற்றிக‌ர‌மாய் வெளியேறியாயிற்று.',
'Invalid credentials.' => 'ச‌ரியான‌ விப‌ர‌ங்க‌ள் இல்லை.',
'Invalid server or credentials.' => null,
'Server' => 'வ‌ழ‌ங்கி (Server)',
'Username' => 'ப‌ய‌னாள‌ர் (User)',
'Password' => 'க‌ட‌வுச்சொல்',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'த‌க‌வ‌ல்த‌ள‌த்தை உருவாக்கு',
'SQL command' => 'SQL க‌ட்ட‌ளை',
'Logout' => 'வெளியேறு',
'database' => 'த‌க‌வ‌ல்த‌ள‌ம்',
'Use' => 'உப‌யோகி',
'No tables.' => 'அட்ட‌வ‌ணை இல்லை.',
'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 altered.' => 'தோற்றம் மாற்றப்ப‌ட்ட‌து.',
'View has been created.' => 'தோற்ற‌ம் உருவாக்க‌ப்ப‌ட்ட‌து.',
@@ -212,6 +211,11 @@ Lang::$translations = array(
'Binary' => 'பைன‌ரி',
'Lists' => 'ப‌ட்டிய‌ல்',
'Editor' => 'தொகுப்பாளர்',
'E-mail' => 'மின்ன‌ஞ்ச‌ல்',
'From' => 'அனுப்புனர்',
'Subject' => 'பொருள்',
'Send' => 'அனுப்பு',
'%d e-mail(s) have been sent.' => array('%d மின்ன‌ஞ்ச‌ல் அனுப்ப‌ப‌ட்ட‌து.', '%d மின்ன‌ஞ்ச‌ல்க‌ள் அனுப்ப‌ப்ப‌ட்ட‌ன‌.'),
'Webserver file %s' => 'வெப் ச‌ர்வ‌ர் கோப்பு %s',
'File does not exist.' => 'கோப்பு இல்லை.',
'%d in total' => 'மொத்தம் %d ',
@@ -224,7 +228,7 @@ Lang::$translations = array(
'Create sequence' => 'வ‌ரிசைமுறையை உருவாக்கு',
'User types' => 'ப‌ய‌னாள‌ர் வ‌கைக‌ள்',
'Create type' => 'வ‌கையை உருவாக்கு',
'Item%s has been inserted.' => 'உருப்ப‌டி (Item%s) சேர்க்க‌ப்ப‌ட்ட‌து.',
'Item%s has been inserted.' => 'உருப்ப‌டி (Item) சேர்க்க‌ப்ப‌ட்ட‌து.',
'Schema has been dropped.' => 'அமைப்புமுறை நீக்க‌ப்ப‌ட்ட‌து.',
'Schema has been created.' => 'அமைப்புமுறை உருவாக்க‌ப்ப‌ட்ட‌து.',
'Schema has been altered.' => 'அமைப்புமுறை மாற்ற‌ப்ப‌ட்ட‌து.',
@@ -247,6 +251,7 @@ Lang::$translations = array(
'Network' => 'நெட்வொர்க்',
'Geometry' => 'வ‌டிவ‌விய‌ல் (Geometry)',
'File exists.' => 'கோப்பு உள்ள‌து.',
'Attachments' => 'இணைப்புக‌ள்',
'now' => 'இப்பொழுது',
'%d query(s) executed OK.' => array('%d வின‌வ‌ல் செய‌ல்ப‌டுத்த‌ப்ப‌ட்ட‌து.', '%d வின‌வ‌ல்க‌ள் செய‌ல்ப‌டுத்த‌ப்ப‌ட்ட‌ன‌.'),
'Show only errors' => 'பிழைக‌ளை ம‌ட்டும் காண்பிக்க‌வும்',
@@ -259,6 +264,50 @@ Lang::$translations = array(
'Permanent link' => 'நிரந்தர இணைப்பு',
'Edit all' => 'அனைத்தையும் தொகு',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,10 +1,8 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
'Login' => 'เข้าสู่ระบบ',
'Logout successful.' => 'ออกจากระบบเรียบร้อยแล้ว.',
'Invalid credentials.' => 'ข้อมูลไม่ถูกต้อง.',
'Invalid server or credentials.' => null,
'Server' => 'เซอเวอร์',
'Username' => 'ชื่อผู้ใช้งาน',
'Password' => 'รหัสผ่าน',
@@ -33,6 +31,7 @@ Lang::$translations = array(
'Create database' => 'สร้างฐานข้อมูล',
'SQL command' => 'คำสั่ง SQL',
'Logout' => 'ออกจากระบบ',
'database' => 'ฐานข้อมูล',
'Use' => 'ใช้งาน',
'No tables.' => 'ไม่พบตาราง.',
'select' => 'เลือก',
@@ -97,7 +96,7 @@ Lang::$translations = array(
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'ชนิดของดัชนี',
'length' => 'ความยาว',
'Column (length)' => 'คอลัมน์ (ความยาว)',
'View has been dropped.' => 'วิวถูกลบแล้ว.',
'View has been altered.' => 'วิวถูกเปลี่ยนแปลงแล้ว.',
'View has been created.' => 'วิวถูกสร้างแล้ว.',
@@ -214,6 +213,11 @@ Lang::$translations = array(
'Binary' => 'เลขฐานสอง',
'Lists' => 'รายการ',
'Editor' => 'ผู้แก้ไข',
'E-mail' => 'อีเมล์',
'From' => 'จาก',
'Subject' => 'หัวข้อ',
'Send' => 'ส่ง',
'%d e-mail(s) have been sent.' => 'มี %d อีเมล์ ถูกส่งออกแล้ว.',
'Webserver file %s' => 'Webserver file %s',
'File does not exist.' => 'ไม่มีไฟล์.',
'%d in total' => '%d ของทั้งหมด',
@@ -248,6 +252,7 @@ Lang::$translations = array(
'Network' => 'เครื่องข่าย',
'Geometry' => 'เรขาคณิต',
'File exists.' => 'มีไฟล์นี้อยู่แล้ว.',
'Attachments' => 'ไฟล์แนบ',
'%d query(s) executed OK.' => '%d คำสั่งถูกดำเนินการแล้ว.',
'Show only errors' => 'แสดงเฉพาะเออเรอ',
'Refresh' => 'โหลดใหม่',
@@ -260,6 +265,49 @@ Lang::$translations = array(
'Permanent link' => 'ลิงค์ถาวร',
'Edit all' => 'แก้ไขทั้งหมด',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => null,
'No' => null,
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem',
'Server' => 'Sunucu',
@@ -13,7 +11,7 @@ Lang::$translations = array(
'Logged as: %s' => '%s olarak giriş yapıldı.',
'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>.',
'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.'),
'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',
@@ -58,7 +56,7 @@ Lang::$translations = array(
'ATTACH queries are not supported.' => 'ATTACH sorguları desteklenmiyor.',
'Execute' => 'Çalıştır',
'Stop on error' => 'Hata oluşursa dur',
'Show only errors' => 'Sadece hataları göster',
'Show only errors' => 'Sadece hataları göster.',
// sprintf() format for time of the command
'%.3f s' => '%.3f s',
'History' => 'Geçmiş',
@@ -86,6 +84,7 @@ Lang::$translations = array(
'Data' => 'Veri',
'Database' => 'Veri Tabanı',
'database' => 'veri tabanı',
'DB' => 'DB',
'Use' => 'Kullan',
'Select database' => 'Veri tabanı seç',
@@ -202,7 +201,7 @@ Lang::$translations = array(
'Alter indexes' => 'İndeksleri değiştir',
'Add next' => 'Bundan sonra ekle',
'Index Type' => 'İndex Türü',
'length' => 'uzunluğu',
'Column (length)' => 'Kolon (uzunluğu)',
'Foreign keys' => 'Dış anahtarlar',
'Foreign key' => 'Dış anahtar',
@@ -225,7 +224,7 @@ Lang::$translations = array(
'Trigger has been dropped.' => 'Tetik silindi.',
'Trigger has been altered.' => 'Tetik değiştirildi.',
'Trigger has been created.' => 'Tetik oluşturuldu.',
'Alter trigger' => 'Tetiği değiştir',
'Alter trigger' => 'Tetiği değiştir.',
'Create trigger' => 'Tetik oluştur',
'Time' => 'Zaman',
'Event' => 'Olay',
@@ -286,6 +285,13 @@ Lang::$translations = array(
'Delete' => 'Sil',
'You have no privileges to update this table.' => 'Bu tabloyu güncellemek için yetkiniz yok.',
'E-mail' => 'E-posta',
'From' => 'Gönderen',
'Subject' => 'Konu',
'Attachments' => 'Ekler',
'Send' => 'Gönder',
'%d e-mail(s) have been sent.' => array('%d e-posta gönderildi.', '%d adet e-posta gönderildi.'),
// data type descriptions
'Numbers' => 'Sayılar',
'Date and time' => 'Tarih ve zaman',
@@ -300,7 +306,7 @@ Lang::$translations = array(
// date format in Editor: $1 yyyy, $2 yy, $3 mm, $4 m, $5 dd, $6 d
'$1-$3-$5' => '$6.$4.$1',
// 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
'HH:MM:SS' => 'SS:DD:ss',
'now' => 'şimdi',
@@ -334,6 +340,19 @@ Lang::$translations = array(
'Type has been dropped.' => 'Tür silindi.',
'Type has been created.' => 'Tür oluşturuldu.',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Evet',
'No' => 'Hayır',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Система Бази Даних',
'Server' => 'Сервер',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Вийти',
'Logged as: %s' => 'Ви увійшли як: %s',
'Logout successful.' => 'Ви вдало вийшли з системи.',
'Invalid credentials.' => 'Неправильні дані входу.',
'Invalid server or credentials.' => null,
'Language' => 'Мова',
'Invalid CSRF token. Send the form again.' => 'Недійсний CSRF токен. Надішліть форму ще раз.',
'No extension' => 'Нема розширень',
@@ -75,6 +73,7 @@ Lang::$translations = array(
'Data' => 'Дані',
'Database' => 'База даних',
'database' => 'база даних',
'Use' => 'Обрати',
'Select database' => 'Обрати базу даних',
'Invalid database.' => 'Погана база даних.',
@@ -184,7 +183,7 @@ Lang::$translations = array(
'Alter indexes' => 'Змінити індексування',
'Add next' => 'Додати ще',
'Index Type' => 'Тип індексу',
'length' => 'довжина',
'Column (length)' => 'Стовпець (довжина)',
'Foreign keys' => 'Зовнішні ключі',
'Foreign key' => 'Зовнішній ключ',
@@ -259,6 +258,13 @@ Lang::$translations = array(
'Clone' => 'Клонувати',
'Delete' => 'Видалити',
'E-mail' => 'E-mail',
'From' => 'Від',
'Subject' => 'Заголовок',
'Attachments' => 'Додатки',
'Send' => 'Надіслати',
'%d e-mail(s) have been sent.' => array('Було надіслано %d повідомлення.', 'Було надіслано %d повідомлення.', 'Було надіслано %d повідомлень.'),
// data type descriptions
'Numbers' => 'Числа',
'Date and time' => 'Дата і час',
@@ -337,18 +343,16 @@ Lang::$translations = array(
'Saving' => 'Збереження',
'Unknown error.' => 'Невідома помилка.',
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Так',
'No' => 'Ні',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,358 +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.',
// 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
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Hệ thống',
'Server' => 'Máy chủ',
@@ -12,7 +10,7 @@ Lang::$translations = array(
'Logout' => 'Thoát',
'Logged as: %s' => 'Vào dưới tên: %s',
'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.',
'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ữ',
@@ -61,7 +59,7 @@ Lang::$translations = array(
'File upload' => 'Tải tệp lên',
'From server' => 'Dùng tệp trên máy chủ',
'Webserver file %s' => 'Tệp trên máy chủ %s',
'Webserver file %s' => 'Tệp trên máy chủ',
'Run file' => 'Chạy tệp',
'File does not exist.' => 'Tệp không tồn tại.',
'File uploads are disabled.' => 'Chức năng tải tệp lên đã bị cấm.',
@@ -78,6 +76,7 @@ Lang::$translations = array(
'Data' => 'Dữ liệu',
'Database' => 'Cơ sở dữ liệu',
'database' => 'cơ sở dữ liệu',
'Use' => 'Sử dụng',
'Select database' => 'Chọn CSDL',
'Invalid database.' => 'CSDL sai.',
@@ -189,7 +188,7 @@ Lang::$translations = array(
'Alter indexes' => 'Sửa chỉ mục',
'Add next' => 'Thêm tiếp',
'Index Type' => 'Loại chỉ mục',
'length' => 'độ dài',
'Column (length)' => 'Cột (độ dài)',
'Foreign keys' => 'Các khoá ngoại',
'Foreign key' => 'Khoá ngoại',
@@ -271,6 +270,13 @@ Lang::$translations = array(
'Delete' => 'Xoá',
'You have no privileges to update this table.' => 'Bạn không có quyền sửa bảng này.',
'E-mail' => 'Địa chỉ email',
'From' => 'Người gửi',
'Subject' => 'Chủ đề',
'Attachments' => 'Đính kèm',
'Send' => 'Gửi',
'%d e-mail(s) have been sent.' => '%d thư đã gửi.',
// data type descriptions
'Numbers' => 'Số',
'Date and time' => 'Ngày giờ',
@@ -319,6 +325,33 @@ Lang::$translations = array(
'Type has been dropped.' => 'Đã xoá kiểu.',
'Type has been created.' => 'Đã tạo kiểu.',
'Alter type' => 'Sửa kiểu dữ liệu',
);
// run `php ../../lang.php vi` to update this file
'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,
'Columns' => null,
'Nullable' => null,
'Default' => null,
'Yes' => 'Có',
'No' => 'Không',
'One Time Password' => null,
'Invalid OTP code.' => null,
);

View File

@@ -1,7 +1,5 @@
<?php
namespace Adminer;
Lang::$translations = array(
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Xx',
'Server' => 'Xx',
@@ -13,20 +11,16 @@ Lang::$translations = array(
'Logged as: %s' => 'Xx: %s',
'Logout successful.' => 'Xx.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Xx <a href="https://www.adminer.org/en/donation/">xx</a>.',
'Loaded plugins' => 'Xx',
'%s must <a%s>return an array</a>.' => '%s xx <a%s>xx</a>.',
'<a%s>Configure</a> %s in %s.' => '<a%s>Xx</a> %s xx %s.',
'Invalid credentials.' => 'Xx.',
'Invalid server or credentials.' => 'Xx.',
'There is a space in the input password which might be the cause.' => 'Xx.',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Xx, <a href="https://www.adminer.org/en/password/"%s>xx</a>.',
'Database does not support password.' => 'Xx.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Xx %d.', 'Xx %d.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => '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',
'Invalid CSRF token. Send the form again.' => 'Xx.',
'If you did not send this request from Adminer then close this page.' => 'Xx.',
'No extension' => 'Xx',
// %s contains the list of the extensions, e.g. 'mysqli, PDO_MySQL'
'None of the supported PHP extensions (%s) are available.' => 'Xx (%s).',
'Connecting to privileged ports is not allowed.' => 'Xx.',
'Disable %s or enable %s or %s extensions.' => 'Xx %s xx %s xx %s xx.',
@@ -37,7 +31,7 @@ Lang::$translations = array(
'Refresh' => 'Xx',
// text direction - 'ltr' or 'rtl'
'ltr' => 'ltr',
'ltr' => 'xx',
'Privileges' => 'Xx',
'Create user' => 'Xx',
@@ -46,7 +40,6 @@ Lang::$translations = array(
'User has been created.' => 'Xx.',
'Hashed' => 'Xx',
'Column' => 'Xx',
'Columns' => 'Xx',
'Routine' => 'Xx',
'Grant' => 'Xx',
'Revoke' => 'Xx',
@@ -96,6 +89,7 @@ Lang::$translations = array(
'Data' => 'Xx',
'Database' => 'Xx',
'database' => 'xx',
'DB' => 'XX',
'Use' => 'Xx',
'Select database' => 'Xx',
@@ -213,7 +207,7 @@ Lang::$translations = array(
'Alter indexes' => 'Xx',
'Add next' => 'Xx',
'Index Type' => 'Xx',
'length' => 'xx',
'Column (length)' => 'Xx',
'Foreign keys' => 'Xx',
'Foreign key' => 'Xx',
@@ -259,7 +253,6 @@ Lang::$translations = array(
'Full table scan' => 'Xx',
'Unable to select the table' => 'Xx',
'No rows.' => 'Xx.',
// used in SQL query limit and it is followed by another number, e.g. '10 / 50 rows' meaning 10 of 50 rows
'%d / ' => '%d / ',
'%d row(s)' => array('%d xx', '%d xx'),
'Page' => 'Xx',
@@ -278,7 +271,7 @@ Lang::$translations = array(
'Ctrl+click on a value to modify it.' => 'Xx.',
'Use edit link to modify this value.' => 'Xx.',
// %s can contain auto-increment value, e.g. ' 123'
// %s can contain auto-increment value
'Item%s has been inserted.' => 'Xx%s.',
'Item has been deleted.' => 'Xx.',
'Item has been updated.' => 'Xx.',
@@ -298,6 +291,13 @@ Lang::$translations = array(
'Delete' => 'Xx',
'You have no privileges to update this table.' => 'Xx.',
'E-mail' => 'Xx',
'From' => 'Xx',
'Subject' => 'Xx',
'Attachments' => 'Xx',
'Send' => 'Xx',
'%d e-mail(s) have been sent.' => array('%d xx.', '%d xx.'),
// data type descriptions
'Numbers' => 'Xx',
'Date and time' => 'Xx',
@@ -347,13 +347,12 @@ Lang::$translations = array(
'Type has been created.' => '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.',
// Plugins
'Columns' => 'Xx',
'Nullable' => 'Xx',
'Default' => 'Xx',
'Yes' => 'Xx',
'No' => 'Xx',
'One Time Password' => 'Xx',
'Invalid OTP code.' => 'Xx.',
);
// run `php ../../lang.php xx` to update this file

View File

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

View File

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

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";

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