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

Compare commits

...

559 Commits

Author SHA1 Message Date
Jakub Vrana
b93d4e2882 Release 5.0.1 2025-03-07 13:17:55 +01:00
Jakub Vrana
28c171f681 PostgreSQL: Support indexes on materialized views (PR #467) 2025-03-07 13:13:58 +01:00
Jakub Vrana
22a544f71c Add missing namespace 2025-03-07 12:50:23 +01:00
Jakub Vrana
2c9f380c64 Elastic: Remove plugin for version 5 2025-03-07 12:17:14 +01:00
Jakub Vrana
9918f4155e Pass credentials to connect() 2025-03-07 12:03:29 +01:00
Jakub Vrana
95e6a65999 Remove duplicate columns from select (bug #670) 2025-03-07 11:36:36 +01:00
Jakub Vrana
94ed6f0e98 MariaDB: Fix link to status variable doc (bug #658) 2025-03-07 11:05:31 +01:00
Jakub Vrana
99eb2f95a5 Develop 2025-03-07 09:41:01 +01:00
Jakub Vrana
8d7cb5954d Release 5.0.0 2025-03-07 09:40:15 +01:00
Jakub Vrana
47700f2763 PostgreSQL: Fix exporting foreign keys 2025-03-07 08:02:06 +01:00
Jakub Vrana
a4a8f48a9c PHPCS: Ignore compiled files 2025-03-07 07:56:35 +01:00
Jakub Vrana
770a77ac33 Wrap long lines 2025-03-07 07:44:26 +01:00
Jakub Vrana
8ceaf36de7 Editor: Fix getting fields 2025-03-07 07:17:05 +01:00
Jakub Vrana
517d2d1c2f MS SQL: Support computed columns 2025-03-07 06:42:27 +01:00
Jakub Vrana
af5d519266 SQLite: Support generated columns 2025-03-07 06:07:25 +01:00
Jakub Vrana
c045b20a8e Allow creating generated columns (bug #857) 2025-03-07 05:18:56 +01:00
Jakub Vrana
874307a27f Fix undefined variable 2025-03-07 04:56:31 +01:00
Jakub Vrana
c27b91a167 MySQL: Drop support for MySQL 4 2025-03-07 03:58:42 +01:00
Jakub Vrana
afe03ef720 MySQL: Display generated value in table structure 2025-03-07 03:58:33 +01:00
Jakub Vrana
c0e2ab22d5 Syntax highlight generated expressions 2025-03-06 19:47:05 +01:00
Jakub Vrana
7351980beb Skip generated columns in multi-edit (bug #882) 2025-03-06 19:32:19 +01:00
Jakub Vrana
7b5a20334d Don't allow inline edit of generated columns 2025-03-06 18:59:20 +01:00
Jakub Vrana
6262b120f5 PostgreSQL: Skip editing generated columns 2025-03-06 18:44:18 +01:00
Jakub Vrana
bd27ca0b2b Add comment 2025-03-06 18:36:26 +01:00
Jakub Vrana
aa7cf70d25 JS: Use || 2025-03-06 18:23:20 +01:00
Jakub Vrana
94a4f61db2 PHP: Use ?: 2025-03-06 18:12:22 +01:00
Jakub Vrana
dc50bf17ea SQLite: Remove useless condition 2025-03-06 17:55:45 +01:00
Jakub Vrana
f05f4b4cbc Change $jush to constant 2025-03-06 17:51:20 +01:00
Jakub Vrana
0541680d73 Move constants to namespace 2025-03-06 17:34:21 +01:00
Jakub Vrana
5a84ff7647 PostgreSQL: Display ? instead of -1 rows in table overview (bug #883) 2025-03-06 17:08:32 +01:00
Jakub Vrana
edd7c67797 Delete incorporated plugin 2025-03-06 14:59:48 +01:00
Jakub Vrana
c6f825a786 Move $enum_length to Driver 2025-03-06 14:51:24 +01:00
Jakub Vrana
f711135574 Move $inout to Driver 2025-03-06 14:49:08 +01:00
Jakub Vrana
2b16f51933 PDO: Support search by expression.
This reverts b848764.
2025-03-06 14:40:13 +01:00
Jakub Vrana
d268e0ebb4 ClickHouse: Check for allow_url_fopen 2025-03-06 14:30:50 +01:00
Jakub Vrana
5fdaae27dc Move possible drivers and JUSH to Driver 2025-03-06 14:27:58 +01:00
Jakub Vrana
049536da90 Mongo: Use $this->_conn 2025-03-06 14:10:05 +01:00
Jakub Vrana
bddce074fa Mongo: Add Driver outside of if 2025-03-06 14:08:19 +01:00
Jakub Vrana
347d9f1f55 Move on_actions to Driver 2025-03-06 14:04:47 +01:00
Jakub Vrana
a8feb00098 Move unsigned to Driver 2025-03-06 13:58:15 +01:00
Jakub Vrana
69d7d76dc5 Move operators, functions and grouping to Driver 2025-03-06 13:51:49 +01:00
Jakub Vrana
2f0cd4185b Move edit functions to Driver 2025-03-06 13:28:04 +01:00
Jakub Vrana
37a75f3759 Move types to Driver 2025-03-06 12:35:20 +01:00
Takashi SHIRAI
d2add4dd72 Fix the primary key for MS SQL
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2025-03-06 08:54:59 +01:00
Jakub Vrana
f5d47d46a0 Use anonymous function 2025-03-05 17:08:29 +01:00
Jakub Vrana
e8d9a126be Rely on PHP 5.3 2025-03-05 17:05:19 +01:00
Jakub Vrana
12f0a4bc9a Inform about namespace use 2025-03-05 16:54:53 +01:00
Jakub Vrana
d9df9693e3 Code style: Add more checks 2025-03-05 16:33:22 +01:00
Jakub Vrana
873d6d50fd Code style: explain rules 2025-03-05 15:55:33 +01:00
Jakub Vrana
c873ceba17 Use PHP 5.3 functions 2025-03-05 15:54:13 +01:00
Jakub Vrana
0bf8861dd1 Plugins: Use namespace for driver functions 2025-03-05 15:54:08 +01:00
Jakub Vrana
137ac2396b Fix plugin autoloading 2025-03-05 15:39:48 +01:00
Jakub Vrana
755d7b47ac Code style: Check camel caps except in drivers 2025-03-05 15:37:16 +01:00
Jakub Vrana
dd947fc1ee Don't check code style in compiled files 2025-03-05 15:36:25 +01:00
Jakub Vrana
105999f62e Code style: Indent long statements 2025-03-05 15:01:21 +01:00
Jakub Vrana
ed5de27dd3 Code style: Indent long statements 2025-03-05 14:59:13 +01:00
Jakub Vrana
293e031498 Plugins: Add missing namespaces 2025-03-05 14:51:55 +01:00
Jakub Vrana
a7f097e78c Code style: Indent long statements 2025-03-05 14:51:17 +01:00
Jakub Vrana
af68e30742 Code style: Remove newline before } 2025-03-05 14:38:48 +01:00
Jakub Vrana
f820fa1c26 Mark abstract classes 2025-03-05 14:31:53 +01:00
Jakub Vrana
f468c095ae Make root namespace explicit 2025-03-05 14:25:09 +01:00
Jakub Vrana
c10b614ee1 Mongo: inline class names 2025-03-05 14:20:54 +01:00
Jakub Vrana
f5b255230b Don't require namespace in example 2025-03-05 14:15:32 +01:00
Jakub Vrana
54568ddef6 PDO: Support namespaces 2025-03-05 14:15:17 +01:00
Jakub Vrana
3da09dd31a Rename Min_ classes 2025-03-05 14:12:42 +01:00
Jakub Vrana
45ac930e06 Update todo 2025-03-05 13:45:42 +01:00
Jakub Vrana
e801753519 Remove extra newline 2025-03-05 13:45:23 +01:00
Jakub Vrana
a4e9f7b87b Fix tests 2025-03-05 13:31:50 +01:00
Jakub Vrana
35829eedaf Use namespace 2025-03-05 13:31:03 +01:00
Jakub Vrana
44c2e979f7 Compile: Support else after if (support) 2025-03-05 13:19:17 +01:00
Jakub Vrana
2a8b4009b1 Namespaces in compile 2025-03-05 13:14:21 +01:00
Jakub Vrana
6ceebc99df Add namespace in lang.php 2025-03-05 13:10:41 +01:00
Jakub Vrana
2f49bfb67e Return accidentally removed error message 2025-03-05 13:10:41 +01:00
Jakub Vrana
e1e085f312 Use namespace in callbacks 2025-03-05 13:10:40 +01:00
Jakub Vrana
50e7a65e6e Use namespaces in plugins 2025-03-05 13:10:40 +01:00
Jakub Vrana
52c5392089 PHP: Use namespace 2025-03-05 13:10:40 +01:00
Jakub Vrana
5a708df6ca Coding style: Check newline at {} 2025-03-05 13:10:40 +01:00
Jakub Vrana
c52ba0308e Specify coding style and follow it 2025-03-05 13:10:37 +01:00
Jakub Vrana
422668f2d7 Composer: Exclude drivers from classmap 2025-03-05 06:35:54 +01:00
Jakub Vrana
f0335f7f8b Hide Refresh link if it does nothing 2025-03-04 19:58:26 +01:00
Jakub Vrana
cc635acd20 Remove unnecessary function 2025-03-04 19:52:07 +01:00
Jakub Vrana
63dd38c44d PostgreSQL: Compute size of all databases (bug #881) 2025-03-04 19:40:42 +01:00
Jakub Vrana
e411c229ab Fix enum alignment 2025-03-04 18:53:01 +01:00
Jakub Vrana
b9d6529442 Remove margin from td pre 2025-03-04 18:46:28 +01:00
Jakub Vrana
0426bd4610 Designs: Fix logout button 2025-03-04 18:44:40 +01:00
Jakub Vrana
c7d283d262 Designs: Fix background of pre.jush 2025-03-04 18:34:07 +01:00
Jakub Vrana
d61678f5cb Reapply "Fix background color of <pre> used as edit field"
This reverts commit 9b25969fb2.
2025-03-04 18:11:32 +01:00
Jakub Vrana
94088474dd Design bilal-dark: Add missing icons 2025-03-04 18:10:23 +01:00
Jakub Vrana
9b25969fb2 Revert "Fix background color of <pre> used as edit field"
This reverts commit 0717bce535.
2025-03-04 11:04:26 +01:00
Jakub Vrana
996b178406 MySQL: Fix connecting with self-signed cert 2025-03-03 16:06:10 +01:00
Jakub Vrana
116827060f PostgreSQL, MS SQL, Oracle: Hide table actions for information_schema 2025-03-03 15:54:08 +01:00
Jakub Vrana
af87336116 Add TODO 2025-03-03 15:43:04 +01:00
jfonsato
17939b56c4 PostgreSQL: Show only accessible databases 2025-03-03 15:34:43 +01:00
Christian Weiske
d5a17835ff Elastic: Fix text search on boolean fields
When searching in all fields for a text value, an error was thrown
with ElasticSearch 7.17.23 when the index contains boolean fields:

> query_shard_exception: failed to create query:
> Can't parse boolean value [textvalue], expected [true] or [false]

This patch fixes that problem by skipping boolean fields when the
search word is not the string "true" or "false".
2025-03-03 10:40:38 +01:00
Matrixman
4967a40410 New version of design rmSOFT
New version of design rmSOFT
2025-03-03 09:36:21 +01:00
Jan Tojnar
4cdcb44bee Use more [] in doc-comments
Follow up to 42de70d032
2025-03-03 08:39:17 +01:00
Jakub Vrana
160beb726a MS SQL: Link help from sys tables 2025-03-03 08:18:20 +01:00
Jakub Vrana
fb3b23617d Don't autofocus computed fields in insert form 2025-03-03 06:34:02 +01:00
Jakub Vrana
dfe3cc1888 Warn about failed type export 2025-03-03 05:17:00 +01:00
Jakub Vrana
c1704d83c1 Add comment 2025-03-03 05:16:15 +01:00
Jakub Vrana
364a4bce1f Update todo 2025-02-28 17:28:35 +01:00
Jakub Vrana
d9bca2df37 Speed up with disabled output buffering 2025-02-28 15:37:18 +01:00
Jakub Vrana
315ffc9d8b CSV import: Don't unquote " in unquoted values 2025-02-28 14:40:31 +01:00
Denitz
530b3dd1e5 Add Reset button for tables-filter plugin 2025-02-28 13:52:32 +01:00
Jakub Vrana
980c22fe8d MS SQL: Don't insert identity without IDENTITY_INSERT 2025-02-27 09:42:33 +01:00
Jakub Vrana
26d1e51916 PostgreSQL: Display ENUM types 2025-02-27 09:41:31 +01:00
Jakub Vrana
6d889b9f99 Add test for check constraints 2025-02-27 08:26:05 +01:00
Jakub Vrana
7e4ee77cc0 Fix Create table test 2025-02-27 08:10:44 +01:00
Jakub Vrana
742fd7dcb6 Remove <datalist> from tests 2025-02-27 08:09:45 +01:00
Jakub Vrana
d23a0eb77e PostgreSQL: Export ENUM types (bug #587) 2025-02-26 23:55:17 +01:00
Jakub Vrana
5eac6a44bd PostgreSQL: Link enum doc 2025-02-26 23:38:07 +01:00
Jakub Vrana
db300bc38b MS SQL: Specify columns in CSV import 2025-02-26 22:49:22 +01:00
Jakub Vrana
48a680658c MS SQL: Do not update primary key in CSV import 2025-02-26 22:47:16 +01:00
Jakub Vrana
70f9ff75fc MS SQL: Fix CSV import (bug #859) 2025-02-26 22:40:28 +01:00
Jakub Vrana
81340ff7e5 MS SQL: Compute arrays in insertUpdate only once 2025-02-26 22:35:00 +01:00
Jakub Vrana
89b097c699 Don't hide import if there was an error 2025-02-26 22:28:01 +01:00
Jakub Vrana
e075f4bd8b MS SQL: Import all CSV rows with one command 2025-02-26 22:27:43 +01:00
Jakub Vrana
e8fa48a257 MS SQL: Set identity_insert in CSV import 2025-02-26 22:11:41 +01:00
Takashi SHIRAI
0ed3c5cb19 Fix insertUpdate for mssql
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2025-02-26 22:04:58 +01:00
Jakub Vrana
2f237dfa04 MS SQL export: Create foreign keys after all tables 2025-02-26 21:39:45 +01:00
Jakub Vrana
afdc78a07b PostgreSQL: Sort PRIMARY and UNIQUE indexes first 2025-02-26 21:28:02 +01:00
Jakub Vrana
3dc87c1811 PostgreSQL: Do not alter indexes with expressions 2025-02-26 21:24:47 +01:00
Jakub Vrana
de7bb79132 Remove empty string 2025-02-26 20:01:56 +01:00
Jakub Vrana
f81658ecfe PostgreSQL: Add missing CHECK in export 2025-02-26 19:56:16 +01:00
Jakub Vrana
a603de853d PostgreSQL: Move primary key in export back to table 2025-02-26 19:55:49 +01:00
Jakub Vrana
2998db57d4 PostgreSQL: Print errors in export 2025-02-26 19:37:18 +01:00
Jakub Vrana
9aaa429528 PostgreSQL: Fix export of indexes with expressions (bug #768) 2025-02-26 19:27:19 +01:00
Jakub Vrana
ba70be12a4 PostgreSQL: Fix help link to pg_catalog views 2025-02-26 19:21:13 +01:00
Jakub Vrana
4b47326ffa Use use_sql 2025-02-26 18:47:25 +01:00
Jakub Vrana
848cd482e2 MS SQL: Add support for PDO_SQLSRV extension 2025-02-26 18:08:18 +01:00
Takashi SHIRAI
15cd83fc39 Add seek() to Min_PDOStatement for mssql.
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2025-02-26 17:43:35 +01:00
Jakub Vrana
4de6e47c0a Use \W in friendly_url() 2025-02-26 16:48:02 +01:00
Jakub Vrana
45f24a8f62 Delete unused functions 2025-02-26 16:48:02 +01:00
Jakub Vrana
cf835515b1 Support compiling Elastic driver 2025-02-26 16:48:02 +01:00
Jakub Vrana
c38b967fc4 Foreign keys: Switch schema back after getting the tables 2025-02-26 16:48:02 +01:00
Jakub Vrana
efb1eb9d6b MS SQL: Remove support for MSSQL extension 2025-02-26 16:48:02 +01:00
Jakub Vrana
ce1031e017 MS SQL: Split altering foreign key to two commands 2025-02-26 16:48:02 +01:00
Jakub Vrana
d54be5ac2e MS SQL: Display foreign keys ON UPDATE and ON DELETE 2025-02-26 16:47:55 +01:00
Jakub Vrana
76cc7c6614 MS SQL: Set identity_insert in export 2025-02-26 16:47:24 +01:00
Jakub Vrana
54dd702763 Fix bug number 2025-02-26 16:47:24 +01:00
Jakub Vrana
dfd26d0704 MS SQL: Support export 2025-02-26 16:47:18 +01:00
Jakub Vrana
0f8460b5e8 PostgreSQL: Use function for exporting constraints 2025-02-26 12:35:25 +01:00
Jakub Vrana
09883aa2f5 SQLite: Remove support for SQLite version 2 2025-02-26 12:20:37 +01:00
Jakub Vrana
e3a2b1b57a SQLite: Support CHECK constraint 2025-02-26 12:20:37 +01:00
Jakub Vrana
a28d95a023 SQLite: Constraint getting view by name to views only 2025-02-26 12:20:37 +01:00
Jakub Vrana
ab025e74a3 SQLite: Display all rows of variable values 2025-02-26 12:20:37 +01:00
Jakub Vrana
8077ef41c1 SQLite: Add command Check tables 2025-02-26 12:20:36 +01:00
Jakub Vrana
9d8864a6c7 Compile: Fix removing single driver login form field 2025-02-26 12:20:36 +01:00
Jakub Vrana
e107ef52d5 Move \n to loginFormField 2025-02-26 12:20:36 +01:00
Jakub Vrana
57ec1f924d Allow compiling driver from plugins 2025-02-26 12:20:36 +01:00
Jakub Vrana
491b481b7f Use __DIR__ 2025-02-26 12:20:36 +01:00
Jakub Vrana
e327d31a08 Hide SQL export if driver doesn't support it 2025-02-26 12:20:34 +01:00
Denitz
708a4e9494 Update table-structure.php 2025-02-25 16:44:25 +01:00
Jakub Vrana
c55ad679ac Use Default setup for CodeQL analysis 2025-02-25 16:41:08 +01:00
Jakub Vrana
dccbdfde97 MongoDB: Remove support for deprecated extension mongo 2025-02-25 15:59:04 +01:00
Jakub Vrana
09091c0dac Develop 2025-02-25 07:32:48 +01:00
Jakub Vrana
bb22a965b2 Release 4.17.1 2025-02-25 07:31:42 +01:00
Jakub Vrana
4f0da70733 Move is_c_style_escapes to Min_Driver 2025-02-25 07:26:08 +01:00
Jakub Vrana
a1235f68ff SQLite: Disable backslash escapes 2025-02-25 07:15:57 +01:00
Jakub Vrana
0138f3b0a5 Oracle: Fix foreign key doc link 2025-02-25 07:09:10 +01:00
Jakub Vrana
192ae38d57 MS SQL: Link doc with current version 2025-02-25 06:58:10 +01:00
Jakub Vrana
620e147b8c Check: Add doc link 2025-02-25 06:54:07 +01:00
Jakub Vrana
644cde4855 MS SQL: Update doc_links 2025-02-25 06:52:27 +01:00
Jakub Vrana
c15576bbf8 Use get_rows() 2025-02-25 06:36:32 +01:00
Jakub Vrana
0d8028ddc5 Compile: Do not warn about functions without declared support 2025-02-25 06:30:22 +01:00
Jakub Vrana
242f5a1ed8 MySQL: Fix typo in the date type (regression from 4.17.0) 2025-02-25 05:41:41 +01:00
Jakub Vrana
d12ea17b17 Remove bogus comment 2025-02-25 05:41:12 +01:00
Jakub Vrana
a7365a50b1 Remove border-collapse: separate in designs after removing cellspacing 2025-02-24 16:41:35 +01:00
Jakub Vrana
b5beffb37c Develop 2025-02-24 12:21:15 +01:00
Jakub Vrana
6b20230d50 Release 4.17.0 2025-02-24 12:20:55 +01:00
Jakub Vrana
836dba07af Warn about missing functions only in single-driver compile 2025-02-24 10:05:31 +01:00
Jakub Vrana
883e0a6619 MySQL 9+: Support vector type 2025-02-23 23:01:43 +01:00
Jakub Vrana
5000e7dc16 Inline function 2025-02-23 18:48:50 +01:00
Jakub Vrana
798432935d PostgreSQL 8+: Fix exporting table constraints 2025-02-23 18:47:11 +01:00
Jakub Vrana
08060f3253 PostgreSQL: Export functions 2025-02-23 18:28:33 +01:00
Jakub Vrana
6d59ed6d7e Fix comment 2025-02-23 18:17:11 +01:00
Jakub Vrana
eb0d5c3c5e Print SQL errors as comments in export 2025-02-23 17:42:23 +01:00
Jakub Vrana
04d707ef94 Anonymous functions require PHP 5.3 2025-02-23 17:07:01 +01:00
Jakub Vrana
004ac1c782 Use less brackets 2025-02-23 17:04:43 +01:00
Jakub Vrana
3ad62d55c8 Show comments at routine call (bug #874) 2025-02-23 16:35:23 +01:00
Jakub Vrana
42de70d032 Use [] in doc-comments 2025-02-23 14:39:14 +01:00
Jakub Vrana
aa2907190e MS SQL: Don't support C-style escapes 2025-02-23 14:39:14 +01:00
Jakub Vrana
5c8b6a3408 Use $connection->result 2025-02-23 14:39:13 +01:00
Jakub Vrana
7f883b9302 Fit number 100 in .size (text length) 2025-02-23 13:40:41 +01:00
Jakub Vrana
27db0914ca Style auto_increment value 2025-02-23 13:40:14 +01:00
Jakub Vrana
483cbf1616 Fix indent 2025-02-23 13:36:37 +01:00
Jakub Vrana
08a956cf2a Offer original values in multi-row editing (regression from 4.16.0) 2025-02-23 13:28:21 +01:00
Jakub Vrana
9d992e4be6 MySQL: Don't offer empty enum value in edit
MySQL errors if there's an invalid value on the first row of INSERT or
UPDATE, regardless of the sql_mode variable.
2025-02-23 13:24:30 +01:00
Jakub Vrana
7ece69a8c4 Remove unused HTLM attribute 2025-02-23 11:42:05 +01:00
Jakub Vrana
1838df9465 Narrows screens: Move lang and logout under h1 2025-02-23 11:25:07 +01:00
Jakub Vrana
4e6ad13eac Move Logout button on narrow screens
This avoids overlapping Logout and breadcrumb.
The button also didn't display on far right due to width: fit-content.
2025-02-23 10:59:56 +01:00
Jakub Vrana
ba35e11bae Ignore error in dropping old constraint 2025-02-23 08:41:33 +01:00
Jakub Vrana
834f4b6c5b Specify viewport width 2025-02-23 08:35:09 +01:00
Jakub Vrana
176f2923cd Fix comment 2025-02-22 23:18:18 +01:00
Jakub Vrana
aaaca731cd MS SQL: Support CHECK constraint 2025-02-22 21:21:47 +01:00
Jakub Vrana
ee9932a0dd PostgreSQL: Support CHECK constraint 2025-02-22 21:08:23 +01:00
Jakub Vrana
c34c672df9 Support constraint checks in compile 2025-02-22 20:40:14 +01:00
Joe Koop
550289de51 MySQL: Support CHECK constraint
added list of check constraints to mysql table view

added create, alter, drop check constraints (mysql)

chore: use the correct function to sql-escape

fix: feature detection for check constraints (mysql)

fix: get check constraint info (mysql)

correct the capitalization of a section title

to be consistent with the other section titles

added a missing `</thead>`
2025-02-22 20:37:59 +01:00
Jakub Vrana
f652ff807e Update CodeQL 2025-02-22 19:01:06 +01:00
Jakub Vrana
746603bdc7 Update tests 2025-02-22 16:31:02 +01:00
Jakub Vrana
e9d9a30844 Use password in example 2025-02-22 16:21:07 +01:00
Jakub Vrana
4d5de895e2 Use new Katalon format 2025-02-22 16:20:31 +01:00
Jakub Vrana
e282ced59e PostgreSQL: Constraint enum values in editing (bug #270) 2025-02-22 13:42:28 +01:00
Jakub Vrana
20d722b882 PostgreSQL: Link user defined types 2025-02-22 12:36:58 +01:00
Jakub Vrana
c1c3b84fff Fix links to PostgreSQL docs 2025-02-22 12:18:14 +01:00
Jakub Vrana
b176a0fbd4 Add TODO 2025-02-22 12:16:15 +01:00
Jakub Vrana
8456779e18 MS SQL: Allow changing default values 2025-02-22 11:08:23 +01:00
Jakub Vrana
3b69ff4ce2 MS SQL: Fix length of nvarchar columns 2025-02-22 10:39:14 +01:00
Jakub Vrana
3a101e873f MS SQL: Allow adding default values 2025-02-22 10:36:44 +01:00
Jakub Vrana
6ecef5eca6 MS SQL: Display default values (bug #732) 2025-02-22 10:11:03 +01:00
Jakub Vrana
707958c63d Remove (beta) from MS SQL 2025-02-22 09:50:20 +01:00
Jakub Vrana
5d18df1d82 MS SQL: Allow altering table in non-default schema (bug #405) 2025-02-22 09:42:36 +01:00
Jakub Vrana
8602304d86 Hide index column options by default 2025-02-22 09:25:39 +01:00
Jakub Vrana
e744fecd98 Make space for the Use button 2025-02-22 08:12:04 +01:00
Jakub Vrana
b58e03f5fc Editor: PDO: Select value of foreign key in edit (bug #847) 2025-02-22 07:56:22 +01:00
Jakub Vrana
40a86bffa2 Add HTML newlines 2025-02-21 21:40:59 +01:00
Jakub Vrana
b7b22486b2 Fix undefined variable in SQL export 2025-02-21 21:35:25 +01:00
Jakub Vrana
cbf7373b54 Wrap long lines in designs 2025-02-21 21:31:58 +01:00
Jakub Vrana
b29767dcfb Use CSS to highlight odd rows 2025-02-21 21:27:41 +01:00
Jakub Vrana
db75be9ba7 Add TODO 2025-02-21 18:40:07 +01:00
Jakub Vrana
67c991846e Hide collations if empty 2025-02-21 18:21:41 +01:00
Jakub Vrana
7d3266b369 MySQL: Fix links to information_schema help 2025-02-21 17:31:56 +01:00
Sebastian Butsch
5f3a820571 Set body width to auto 2025-02-21 17:20:17 +01:00
Jakub Vrana
e7df6bf616 Remove CSS vendor prefixes 2025-02-21 17:01:54 +01:00
Jakub Vrana
1d8bd0a210 Wrap connection error message 2025-02-21 14:29:22 +01:00
Jakub Vrana
6fe9827eea Trim trailing whitespace 2025-02-21 13:59:17 +01:00
Jakub Vrána
7900062d4d Update funding 2025-02-21 11:57:52 +01:00
Jakub Vrana
63cffbbc8a Fix style 2025-02-21 10:57:11 +01:00
Jakub Vrana
0b3baa1e23 Fix Latvian plurals 2025-02-21 09:40:31 +01:00
Jakub Vrana
e3fbc56b6f SQLite: Show all supported pragmas in Variables 2025-02-20 18:11:18 +01:00
Jakub Vrana
00607012af Update TODO 2025-02-20 17:59:02 +01:00
Jakub Vrana
e4e5941b90 Wrap long lines 2025-02-20 17:58:00 +01:00
Jakub Vrana
097f2a1242 Develop 2025-02-20 16:40:14 +01:00
Jakub Vrana
c81bed0baa Fix indent 2025-02-20 16:27:39 +01:00
Jakub Vrana
9c9fc4a85b Release 4.16.0 2025-02-20 15:58:15 +01:00
Jakub Vrana
b46b1dd574 Fix typo in comment 2025-02-20 11:47:38 +01:00
Jakub Vrana
f248fb29b1 PostgreSQL: Support adding auto_increment (bug #761) 2025-02-20 11:13:50 +01:00
Jakub Vrana
94f75f9798 PostgreSQL: Support dropping auto_increment 2025-02-20 11:12:39 +01:00
Jakub Vrana
f2e2c6e4ac SQLite: Fix expressions in default values (bug #860) 2025-02-20 09:37:43 +01:00
Jakub Vrana
e321a26ee5 Move functions unused in Editor 2025-02-20 09:11:59 +01:00
Jakub Vrana
f35dd89c65 Fix style 2025-02-20 08:37:13 +01:00
Bilal Yameen
8f2b4ced62 Dark theme for Adminer 2025-02-19 21:22:57 +01:00
Peter Knut
5eb3446908 MSSQL: Allow to set Encrypt and TrustServerCertificate with AdminerLoginSsl plugin (issue #5)
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/connection-string-syntax#use-trustservercertificate
2025-02-19 21:20:53 +01:00
Peter Knut
a685d414ad Change version layout 2025-02-19 20:47:36 +01:00
Pavel Železný
7c9fec4e6b Fix mysqli ssl without server certificate 2025-02-19 20:17:48 +01:00
araisch
224cbfed56 MySQL SSL: Allow disabling cert verification 2025-02-19 19:20:37 +01:00
Jakub Vrana
490d274662 Update TODO 2025-02-19 19:10:36 +01:00
Peter Knut
3a27c4f64c Editor: Fix searching in tables
Thanks to ytetsuro (https://github.com/vrana/adminer/pull/473)
2025-02-19 19:04:47 +01:00
Jakub Vrana
bd6ebcaab9 Remove spaces 2025-02-19 19:00:47 +01:00
Peter Knut
1f97968e65 PostgreSQL: Allow to set connection's sslmode with AdminerLoginSsl plugin
Thanks to wodka (https://github.com/vrana/adminer/pull/427/files)
2025-02-19 18:54:24 +01:00
Vladimir
dfb33a323d Add .gitattributes, exclude tests from archive 2025-02-19 17:03:34 +01:00
Jakub Vrana
869c2b92ea Remove design submodules 2025-02-19 15:13:46 +01:00
Jakub Vrana
675dbaad73 SQLite: Fix getting result of queries with no rows 2025-02-19 15:06:55 +01:00
Jakub Vrana
a001a3a061 SQLite: Fix altering forign keys (bug #841) 2025-02-19 15:02:11 +01:00
Jakub Vrana
df451f4374 MySQL: Fix saving bit(64) values (bug #839) 2025-02-19 14:57:41 +01:00
Jakub Vrana
9def8d7f95 MS SQL: Foreign keys in non-default schema (bug #833) 2025-02-19 14:36:54 +01:00
Vladimir Goncharov
2385bf72bd support for array values in clickhouse driver 2025-02-19 14:36:07 +01:00
Jakub Vrana
12427467f7 Fix lowercase title 2025-02-19 14:36:07 +01:00
Jakub Vrana
2bec4ca11b Avoid global variables in plugins drivers 2025-02-19 14:36:07 +01:00
panji
e676303a26 MongoDB: Execute commands against the selected DB 2025-02-19 14:36:04 +01:00
Jakub Vrana
9261abc415 PostgreSQL: Preserve whitespace in EXPLAIN (bug #827) 2025-02-19 14:35:19 +01:00
Jakub Vrana
e5c05fe26c Elastic 5: Do not set Content-Type without content 2025-02-19 12:31:44 +01:00
Tim Alexander
21bf7e0570 Fix German Translation Errors 2025-02-19 12:07:19 +01:00
Jakub Vrana
93f04464a2 Oracle: Remove NOT REGEXP (bug #804) 2025-02-19 11:16:46 +01:00
Jakub Vrana
e03713ce2d Add LICENSE 2025-02-19 11:16:46 +01:00
Takashi SHIRAI
2da5683b99 Support to access tablespaces of granted tables
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2025-02-19 11:16:46 +01:00
Jakub Vrana
8ff20622fb Develop 2025-02-19 11:16:46 +01:00
Jakub Vrana
9ef14dbf77 Release 2025-02-19 11:16:46 +01:00
Jakub Vrana
274fa2259b Escape unknown field in select 2025-02-19 11:16:45 +01:00
Jakub Vrana
7541149522 Use Unicode 2025-02-19 11:16:45 +01:00
Jakub Vrana
2a3626faae SimpleDB: Disable XML entity loader 2025-02-19 11:16:45 +01:00
Jakub Vrana
d94e348f57 Use a better random string 2025-02-19 11:16:45 +01:00
Jakub Vrana
51dbfb6987 Hide error message from HTTP servers 2025-02-19 11:16:45 +01:00
Jakub Vrana
578c9fca92 Don't allow path in HTTP servers 2025-02-19 11:16:45 +01:00
Jakub Vrana
d9289355d7 Fix style 2025-02-19 11:16:45 +01:00
Jakub Vrana
874b9ee746 Use autofocus HTML attribute 2025-02-19 11:16:45 +01:00
Jakub Vrana
17974cdf76 VersionNoverify plugin: Do not block other plugins 2025-02-19 11:16:44 +01:00
Jakub Vrana
2d8b6ec771 Add PHP 8.1-8.4 2025-02-19 11:16:44 +01:00
Adrian Jones
5982060f3b Fix links to MySQL docs
It was directing to https://dev.mysql.com/doc/refman/9.2en/select.html instead of https://dev.mysql.com/doc/refman/9.2/en/select.html
2025-02-19 11:16:44 +01:00
Saiful Alam Rakib
6496ff5a47 Fix the UI of pappu687 for latest version 2025-02-19 11:16:44 +01:00
Jakub Vrana
6aa55d806b Bump version 2025-02-19 11:16:44 +01:00
Peter Knut
0ef358a6b5 Release 4.14.0 2025-02-19 11:16:44 +01:00
Peter Knut
882e9d02a0 PostgreSQL: Fix renaming database 2025-02-19 11:16:44 +01:00
Peter Knut
e346f47384 PostgreSQL: Fix starting value of exported autoincrement
Thanks to @OmlineEditor (https://github.com/adminerevo/adminerevo/issues/113)
2025-02-19 11:16:44 +01:00
Peter Knut
fdd02a5485 Modify naming of new foreign rows
Regexp is used to unify implementation with other similar situations. This also prevents false detection in CodeQL security scanning.
2025-02-19 11:16:43 +01:00
Lucas Sandery
7238bc7900 Update lucas-sandery theme
::file-selector-button got standardised.
2025-02-19 11:16:43 +01:00
Peter Knut
15ac0889c0 Bump version to 4.14-dev 2025-02-19 11:16:43 +01:00
Peter Knut
ab40931365 Fix main visual glitches in designs, remove broken designs 2025-02-19 11:16:43 +01:00
Peter Knut
5d6e9fff65 Bump version to 4.12.1-dev 2025-02-19 11:16:43 +01:00
Kian-Meng Ang
d6d86fa26a Fix some typos
https://github.com/adminerevo/adminerevo/pull/210
2025-02-19 11:16:43 +01:00
Peter Knut
f25ffb36f9 Update German translation
Thanks to wintstar (https://github.com/adminerevo/adminerevo/issues/219)
2025-02-19 11:16:43 +01:00
Peter Knut
49fd7858ac Release 4.12 2025-02-19 11:16:43 +01:00
Peter Knut
0628b8de02 MSSQL, MongoDB: Connect to localhost with default port if server is not specified 2025-02-19 11:16:42 +01:00
Peter Knut
99434644ef MongoDB: Fix parsing WHERE condition from SQL query
Thanks to herobank110 (https://github.com/vrana/adminer/pull/491)
2025-02-19 11:16:42 +01:00
vukbgit
5492b3e055 MariaDB: Add support for UUID data type
- MariaDB >= 10.7
- UUID string data type
- uuid() function for UUID type on new/edit item form
2025-02-19 11:16:42 +01:00
Peter Knut
84b69da58d Fix SQL query code direction if RTL language is used 2025-02-19 11:16:42 +01:00
Peter Knut
a51d0f4701 Bump version to 4.12.0-dev 2025-02-19 11:16:42 +01:00
Peter Knut
7cd82c8fd7 Release 4.11 2025-02-19 11:16:42 +01:00
Peter Knut
d065c9ba51 MySQL: Fix highlighting current table in menu on macOS 2025-02-19 11:16:41 +01:00
Peter Knut
f79340a0b5 Update CS and SK translations 2025-02-19 11:16:41 +01:00
HyP3r
4bc9a29f3e MS SQL: Prefix Unicode strings with 'N' so they are treated correctly 2025-02-19 11:16:41 +01:00
Peter Knut
81530227c2 MariaDB: Fix several links to documentation pages 2025-02-19 11:16:41 +01:00
Peter Knut
d8217d6ee2 Bump version to 4.10.1-dev 2025-02-19 11:16:41 +01:00
Peter Knut
02c13131e3 Release 4.10.0 2025-02-19 11:16:41 +01:00
Jakub Vrana
21c339901c PHP <5.6 compatibility 2025-02-19 11:16:41 +01:00
Peter Knut
06c4fd4855 Print username next to the logout button 2025-02-19 11:16:41 +01:00
Peter Knut
0a473cef18 Update readme.txt 2025-02-19 11:16:41 +01:00
Roy-Orbison
652a09bb91 Plugin to auto-include adminer.js when present 2025-02-19 11:16:40 +01:00
Peter Knut
47a9453ace Do not display empty action links in main menu 2025-02-19 11:16:40 +01:00
Peter Knut
d4f99d5cdc Bump version to 4.10-dev 2025-02-19 11:16:40 +01:00
Peter Knut
72ed1b5cdc Release 4.9.4 2025-02-19 11:16:40 +01:00
Peter Knut
4e825a36d3 Editor: Fix building links with array parameters
This solves a situation when enum data type has a foreign key to another table.
2025-02-19 11:16:40 +01:00
Peter Knut
927444ffdd Editor: Fix array conversion to string (issue #3) 2025-02-19 11:16:40 +01:00
Peter Knut
d9976c25fc Firefox: Fix opening a database to the new browser's tab with Ctrl+click 2025-02-19 11:16:40 +01:00
Peter Knut
c5fa212b26 Unify displaying of 'New item' action based on privileges 2025-02-19 11:16:40 +01:00
Peter Knut
edef2b1a3d Fix the width of inline edit field 2025-02-19 11:16:39 +01:00
Peter Knut
7eccd59856 Bump version to 4.9.4-dev 2025-02-19 11:16:39 +01:00
Peter Knut
476b957565 Release 4.9.3 2025-02-19 11:16:39 +01:00
Peter Knut
8e43fffe53 Hide invalid edit form if table record is not found 2025-02-19 11:16:39 +01:00
Peter Knut
d2c6ea21b6 PostgreSQL: Fix editing record that contains a field with GENERATED ALWAYS default value
Fields with GENERATED ALWAYS default values are also disabled.

Thanks to PurpleTape (https://github.com/adminerevo/adminerevo/issues/201).
2025-02-19 11:16:39 +01:00
SeaEagle
a310d52327 MySQL: Fix where clause for JSON column
Issue: https://github.com/adminerevo/adminerevo/issues/175
2025-02-19 11:16:39 +01:00
Peter Knut
0717bce535 Fix background color of <pre> used as edit field 2025-02-19 11:16:39 +01:00
Peter Knut
53aad3bb62 Do not include unchanged PARTITION BY definition into ALTER TABLE query 2025-02-19 11:16:39 +01:00
Peter Knut
99cd514a29 MariaDB: Fix comparing CURRENT_TIMESTAMP definition while altering a table 2025-02-19 11:16:39 +01:00
Peter Knut
8ea4892523 MySQL, PostgreSQL: Fix queries splitting and string constants
Thanks to alxivnov (https://github.com/vrana/adminer/pull/490).
2025-02-19 11:16:38 +01:00
Michael Graß
74e4bb9a6f Do not limit unlimited memory, fix number conversion warning 2025-02-19 11:16:38 +01:00
Peter Knut
3d2d39e7d0 Bump version to 4.9.3-dev 2025-02-19 11:16:38 +01:00
Peter Knut
06a4d294bd Release 4.9.2 2025-02-19 11:16:38 +01:00
Peter Knut
0d5e5819a0 Basic JS code cleanup 2025-02-19 11:16:38 +01:00
khoazero123
b17ffcc512 PostgreSQL: Fix exporting CREATE TABLE with sequence default value 2025-02-19 11:16:38 +01:00
Roy-Orbison
d91bd659a5 Function to retrieve driver name
Plugins cannot access $drivers global after compilation.
2025-02-19 11:16:38 +01:00
Peter Knut
1efb87fcbe PostgreSQL: Fix exporting CREATE TABLE query with GENERATED default values
Thanks to GottfriedCP (https://github.com/adminerevo/adminerevo/issues/157)
2025-02-19 11:16:38 +01:00
Peter Knut
d8f1521b60 PostreSQL: Fix search condition for network address types, add macaddr8 type
This fixes issue https://github.com/adminerevo/adminerevo/issues/115
2025-02-19 11:16:38 +01:00
Peter Knut
cb6e2f9a86 Bump version to 4.9.2-dev 2025-02-19 11:16:37 +01:00
Peter Knut
4824c578bf Release 4.9.1 2025-02-19 11:16:37 +01:00
Jakub Vrana
f4607d763c Ignore undefined property PHP warning 2025-02-19 11:16:37 +01:00
Peter Knut
12293ce215 PostgreSQL: Fix documentation link for SERIAL type
Thanks to leggiero (https://github.com/vrana/adminer/pull/432)
2025-02-19 11:16:37 +01:00
caltong
c47d933ab0 PostgreSQL: Make data length calculation more accurate 2025-02-19 11:16:37 +01:00
Thomas Daniels
6e6785ebc4 PostgreSQL: Show only accessible databases 2025-02-19 11:16:37 +01:00
Peter Knut
6d848bf165 Replace deprecated <acronym> with <abbr> 2025-02-19 11:16:37 +01:00
Peter Knut
2189947c43 AdminerLoginOtp: Autocomplete hints for OTP input field, code refactoring
Tanks to SGCBB (https://github.com/vrana/adminer/pull/488)
2025-02-19 11:16:37 +01:00
Sneda8
b6f9f58712 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.
2025-02-19 11:16:36 +01:00
Peter Knut
fdeb9557cd Improved displaying of long table names in menu 2025-02-19 11:16:36 +01:00
Peter Knut
11e1290b5b Add .editorconfig file
Thanks to cweiske (https://github.com/adminerevo/adminerevo/pull/163).
2025-02-19 11:16:36 +01:00
Peter Knut
ac9fd04f87 Fix field selection in Elasticsearch
Thanks to cweiske: https://github.com/adminerevo/adminerevo/pull/159
2025-02-19 11:16:36 +01:00
Peter Knut
2128c05e53 Bump version to 4.9.1-dev 2025-02-19 11:16:36 +01:00
Peter Knut
550db0691e Release 4.9 2025-02-19 11:16:36 +01:00
Adrian Jones
4484f5f620 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
2025-02-19 11:16:36 +01:00
Denitz
c2f8ccc8d8 Skip dump of generated columns 2025-02-19 11:16:36 +01:00
Peter Knut
bd279b2758 Update changes.txt 2025-02-19 11:16:36 +01:00
Peter Knut
76575a95f1 Move Elastic drivers to plugins, driver for Elastic 7+ is the default 2025-02-19 11:16:35 +01:00
Peter Knut
95bab4c077 Modify tables hierarchy for Elasticsearch 7
- Properly display list of databases, indexes, aliases and fields.
- Fix search and delete queries.
2025-02-19 11:16:35 +01:00
Peter Knut
e85af88227 New Elasticsearch 7 plugin as a copy of the old one 2025-02-19 11:16:35 +01:00
Peter Knut
c6bb98ad22 Improve code readability by using of empty lines 2025-02-19 11:16:35 +01:00
Peter Knut
2a0f17b6d9 Compatibility with Elasticsearch 7.14
- Removed empty body from requests.
- Fix deleting records.
2025-02-19 11:16:35 +01:00
Peter Knut
dc1ad9e8ed Fix global search in all tables 2025-02-19 11:16:35 +01:00
Peter Knut
1270748f74 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
2025-02-19 11:16:35 +01:00
Peter Knut
266fda37a1 Fix searching if "anywhere" field is selected
- Allow to search only in fields with index.
2025-02-19 11:16:35 +01:00
Peter Knut
1f14ab470f 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.
2025-02-19 11:16:35 +01:00
Peter Knut
501234c2d1 Fix undefined $sql variable 2025-02-19 11:16:34 +01:00
Peter Knut
197ab976b8 Update changes.txt 2025-02-16 18:03:17 +01:00
Peter Knut
b2759df1f9 Disable redirections in HTTP based drivers 2025-02-16 18:03:17 +01:00
Peter Knut
de07f00ccb Bump version to 4.9.0-dev 2025-02-16 18:03:16 +01:00
Peter Knut
031d2c6a34 Make jush and JsShring submodules available 2025-02-16 18:03:16 +01:00
Lucas Sandery
e2810adc05 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)
2025-02-16 18:03:16 +01:00
Peter Knut
baeeb362f7 Fix and complete Slovak translation 2025-02-16 18:03:16 +01:00
Lukáš Rajchl
347ac77bab Update Czech translation
(cherry picked from commit 7338eadd7c)
2025-02-16 18:03:16 +01:00
Anastasia
6b9eb3f446 Update Russian translation
(cherry picked from commit 33fcfbc13b)
2025-02-16 18:03:16 +01:00
Gerry Demaret
f58b13e994 Update Dutch translation
(cherry picked from commit 6024d73ae6)
2025-02-16 18:03:16 +01:00
Lionel Laffineur
fe295bc78a Update French and Italian translations
(cherry picked from commit 496ab9a262)
2025-02-16 18:03:09 +01:00
Hossain Ahmed Saiman
b39469eb9f 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)
2025-02-15 14:05:39 +01:00
@krysits.COM
20684a5166 Add Latvian language translation
(cherry picked from commit fad4ce785b)
2025-02-15 14:04:34 +01:00
Roy-Orbison
2c8dbf49cc Fix misaligned inputs
Signed-off-by: Roy-Orbison <Roy-Orbison@users.noreply.github.com>
(cherry picked from commit 2717333789)
2024-03-15 23:02:41 +01:00
Linus Törngren
88647b93e4 Improved spelling. 2021-05-23 13:40:36 +02:00
Jakub Vrana
b8c5eec46d MS SQL: Support [ in udf_unescape 2021-05-23 12:50:14 +02:00
Jakub Vrana
dadbb37f00 PostgreSQL: Don't reset table comments 2021-05-23 11:45:57 +02:00
Jakub Vrana
ea1acfc8bc Preventively escape name 2021-05-23 11:38:51 +02:00
Jakub Vrana
2dd65f0c0f Support multi-line table comments 2021-05-23 11:38:04 +02:00
Jakub Vrana
473f7264f8 PostgreSQL: Use separator in limit1 2021-05-23 11:08:29 +02:00
Benjamin Cremer
db01282e29 Use ST_SRID() in mysql driver for MySQL 8
`SRID()` is no longer available in MySQL 8 and has been replaced with `ST_SRID`
2021-05-23 09:45:55 +02:00
Jakub Vrana
1f173e18bd Release 4.8.1 2021-05-14 07:39:59 +02:00
Jakub Vrana
4043092ec2 Escape link in doc_link (bug #797) 2021-05-14 07:12:44 +02:00
Jakub Vrana
60ad161178 PostgreSQL: Fix parsing of foreign keys with non-ASCII column names (thanks to Tomas Pecina) 2021-05-14 06:21:09 +02:00
luigifab
a12d31c5a8 Fix editRowPrint for plugin 2021-03-04 10:57:55 +01:00
Vladimír Dudr
f6880b59d6 Prevent adminer to consider MariaDB sequences being views 2021-03-03 11:17:32 +01:00
Jakub Vrana
72beecc0ab PostgreSQL: Support UPDATE OF triggers (bug #789) and triggers with more events (OR) 2021-03-03 11:07:58 +01:00
Jakub Vrana
42de1051a6 Update bug numbers 2021-02-24 09:52:22 +01:00
Jakub Vrana
af1a908f56 Unsubstite constants (PHP 5 is now required) 2021-02-23 12:42:11 +01:00
Jakub Vrana
205305d6b5 Avoid PHP warnings with PDO drivers (bug #786) 2021-02-23 12:33:30 +01:00
Jaume Barber
0e5f39042a Update ca.inc.php
Minor ca translation corrections
2021-02-18 08:52:19 +01:00
Jakub Vrana
f94f29124a Oracle: Fix column name in index (thanks to Shirai Takashi) 2021-02-18 08:44:56 +01:00
Jakub Vrana
28996e2286 PostgreSQL < 10 PDO: Avoid displaying GENERATED ALWAYS BY IDENTITY everywhere (bug #785) 2021-02-15 18:33:19 +01:00
Jakub Vrana
7f8c93a6f1 SQLite: Fix displayed types (bug #784) 2021-02-15 18:33:19 +01:00
Jakub Vrana
25dda09bce Update TODO 2021-02-15 18:33:19 +01:00
Jakub Vrana
ff45b8f7a9 Save bytes 2021-02-15 18:33:19 +01:00
Konstantinos Megas
3a36112a10 Fixes greek language typos and translated strings 2021-02-15 15:40:35 +01:00
Jakub Vrana
e9e61fce26 MySQL: Allow moving views to other DB and renaming DB with views (bug #783) 2021-02-12 11:49:35 +01:00
Jakub Vrana
5a1498d160 Use common code 2021-02-12 11:28:55 +01:00
Jakub Vrana
ccb7442d1b Fix more PHP 8 warnings (bug #781) 2021-02-12 09:53:20 +01:00
Takashi SHIRAI
eebda8695b Oracle: Fix the bugs for indexes.
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2021-02-12 09:08:56 +01:00
Jakub Vrana
94d18d003e Remove version 2021-02-11 12:20:09 +01:00
Jakub Vrana
3881fc1680 Fix designs after 7db10e95 2021-02-11 08:52:33 +01:00
Jakub Vrana
9bd63a1326 Update readme 2021-02-10 19:52:55 +01:00
Jakub Vrana
92d5858b03 Link instructions 2021-02-10 19:52:55 +01:00
Jakub Vrána
d506f1e241 Enable CodeQL Analysis 2021-02-10 19:51:49 +01:00
Jakub Vrána
cd7f06c8b2 Create security policy 2021-02-10 19:43:30 +01:00
Jakub Vrana
b83c61fca3 Release 4.8.0 2021-02-10 17:21:55 +01:00
Jakub Vrana
3882bfaac1 Remove .inc extension from driver plugins 2021-02-10 11:43:56 +01:00
Jakub Vrana
29e2475b5a Oracle: Use correct DB in db_size, fix typo (thanks to Shirai Takashi) 2021-02-10 11:15:18 +01:00
Jakub Vrana
fd1dd4ecf4 MongoDB: Alpha 2021-02-10 09:50:21 +01:00
Jakub Vrana
dc9e87dbd6 MongoDB: Prefer driver used in other functions 2021-02-10 09:45:34 +01:00
Jakub Vrana
66f335fb63 Save bytes 2021-02-09 20:42:25 +01:00
Jakub Vrana
574c07b8f5 MongoDB: Fix edit operations in select 2021-02-09 20:36:23 +01:00
Jakub Vrana
84e4122225 Fix typo 2021-02-09 20:20:19 +01:00
Jakub Vrana
a61a76716b MongoDB: Use ObjectID only if used 2021-02-09 20:19:43 +01:00
Jakub Vrana
5d317111c7 MongoDB: Fix operators 2021-02-09 20:12:41 +01:00
Jakub Vrana
6af375c67d MongoDB: Handle errors 2021-02-09 20:09:11 +01:00
Jakub Vrana
609b8690ec MongoDB: Fix query 2021-02-09 19:47:51 +01:00
Jakub Vrana
13260dcb76 Save bytes 2021-02-09 16:56:16 +01:00
Jakub Vrana
e002a3bc99 MongoDB: Display error when selecting wrong table 2021-02-09 16:53:05 +01:00
Jakub Vrana
f44f186b38 MongoDB: Display arrays as JSON 2021-02-09 16:34:42 +01:00
Jakub Vrana
c24a6a6aef MongoDB: Fix executeQuery 2021-02-09 16:32:38 +01:00
Jakub Vrana
f11a31e0a9 MongoDB: Modern extension doesn't allow connecting with random user/password 2021-02-09 16:13:28 +01:00
Jakub Vrana
38e741054a MongoDB: Add operators 2021-02-09 11:31:37 +01:00
Jakub Vrana
513e1f425f MongoDB: Handle exceptions 2021-02-09 11:30:14 +01:00
Jakub Vrana
a023e98c4d MongoDB: Fix getting binary fields 2021-02-09 11:07:47 +01:00
Jakub Vrana
633e7ced9c MongoDB: Fix num_rows 2021-02-09 11:04:18 +01:00
Jakub Vrana
3a3df6962b MongoDB: Move common code to function 2021-02-09 11:04:17 +01:00
Jakub Vrana
1e4fb073b5 MongoDB: Display Authentication failed instead of exception 2021-02-09 11:04:10 +01:00
Jakub Vrana
08637cee62 Delete duplicate code 2021-02-09 10:29:19 +01:00
Jakub Vrana
4742bde873 Fix operators init 2021-02-09 10:19:05 +01:00
Jakub Vrana
7a89b5a037 PostgreSQL: Fix displaying NULL bytea fields 2021-02-09 10:08:27 +01:00
Takashi SHIRAI
c5b5b61be1 Avoid errors about 'view_trigger'
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2021-02-09 09:57:29 +01:00
Takashi SHIRAI
2b0ac4c0e1 Support unprivileged users for schema list
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2021-02-09 09:57:29 +01:00
Takashi SHIRAI
ef53494df0 Support altering indexes
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2021-02-09 09:57:27 +01:00
Takashi SHIRAI
98458f737d Avoid errors when alter table column
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2021-02-09 09:57:00 +01:00
Takashi SHIRAI
68edea54ea Avoid errors about auto increment
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2021-02-09 09:57:00 +01:00
Takashi SHIRAI
6660789d04 Support granted table to list up indexes
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2021-02-09 09:57:00 +01:00
Takashi SHIRAI
ee4ffe9b65 Correct column size with string type
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2021-02-09 09:56:55 +01:00
Takashi SHIRAI
27de0417fe Sort the DB list
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2021-02-09 09:42:23 +01:00
Takashi SHIRAI
339981b9d6 Support importing table data
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2021-02-09 09:42:18 +01:00
Takashi SHIRAI
53a8496412 The table with another scheme is deleted from the table list
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2021-02-09 09:38:47 +01:00
Takashi SHIRAI
fb38ae2ffd Support computing DB infos
Signed-off-by: Takashi SHIRAI <shirai@nintendo.co.jp>
2021-02-09 09:24:26 +01:00
salacr
91da14b15c PostgreSQL: Do not show triggers from other schemas 2021-02-09 08:59:06 +01:00
Jakub Vrana
51abdcdab9 SimpleDB, Firebird, ClickHouse: Move to plugin 2021-02-08 19:56:15 +01:00
Jakub Vrana
4038144c38 Add comments 2021-02-08 19:35:25 +01:00
Jakub Vrana
50ed4f7ce7 Prepare for moving drivers to plugins 2021-02-08 19:35:22 +01:00
Jakub Vrana
4f8ecd3c11 Support function default values in insert (bug #713) 2021-02-08 17:52:10 +01:00
Jakub Vrana
f2063c92c5 Allow SQL pseudo-function in insert 2021-02-08 17:41:59 +01:00
Jakub Vrana
5db1ea3301 Save bytes 2021-02-08 17:22:53 +01:00
Jakub Vrana
e915f73f18 PostgreSQL: Fix multi-parameter functions in default values (bug #736) 2021-02-08 16:23:36 +01:00
Jakub Vrana
92f197b7c1 Add id to <th> in select (bug #724) 2021-02-08 16:10:37 +01:00
Jakub Vrana
63484fb875 Remove newline before error message 2021-02-08 16:06:22 +01:00
Jakub Vrana
701c5cd73b Fix whitespace 2021-02-08 15:50:02 +01:00
Jakub Vrana
4310d710d9 Add bug number 2021-02-08 15:46:24 +01:00
Jakub Vrana
2bb472d7a6 PostgreSQL: Avoid exporting empty sequence last value 2021-02-08 14:12:39 +01:00
Jakub Vrana
9e74c0632f PostgreSQL: Create PRIMARY KEY for auto increment columns 2021-02-08 14:00:38 +01:00
Jakub Vrana
d4f7e04156 PostgreSQL PDO: Do not select NULL function for false values in edit (thanks to PR #380) 2021-02-08 13:23:48 +01:00
Jakub Vrana
124092fd7c MySQL 8: Fix EXPLAIN in SQL command 2021-02-08 12:26:51 +01:00
Jakub Vrana
144039d0cb Update tests 2021-02-08 11:50:02 +01:00
Jakub Vrana
a8c218f192 Add callback before edit form (bug #759) 2021-02-08 10:57:53 +01:00
Jakub Vrana
2dd3bd0e1a Skip date columns for non-date values in search anywhere (thanks to PR #408) 2021-02-08 10:53:20 +01:00
Jakub Vrana
28209301ca Fix PHP 8 warning 2021-02-08 10:40:38 +01:00
Jakub Vrana
7ccc1e3e15 Add DB version to comment in export 2021-02-08 09:47:10 +01:00
Jakub Vrana
93c7fb248c Release 4.7.9 2021-02-07 18:25:18 +01:00
Jakub Vrana
73934caec8 Reorder changes 2021-02-07 18:23:41 +01:00
Jakub Vrana
4559e7541c Editor: Avoid trailing dot in export filename
Context: https://sourceforge.net/p/adminer/discussion/960418/thread/ca36ed7b66/
2021-02-07 16:40:29 +01:00
Jakub Vrana
d847f0d1aa Skip impossible condition ($link always contains ?username=) 2021-02-07 15:27:53 +01:00
Jakub Vrana
c727231ccd Fix displayed foreign key columns from other DB (bug #766) 2021-02-07 15:19:03 +01:00
Jakub Vrana
3d92eb703b Do not display empty database in the list twice 2021-02-07 14:28:16 +01:00
Jakub Vrana
3d88cc2c8e Display CSRF logout error after connecting
Context: https://sourceforge.net/p/adminer/discussion/960418/thread/74e1d2d4bc/
2021-02-07 14:23:46 +01:00
Peter Knut
922e1d96b0 Fix displaying type mapping for Elasticsearch >= 6.0
Earlier versions of Elasticsearch (<= 5) supported multiple types per index. That meant that you could have different data mappings for each type. With Elasticsearch 6, this was removed and you can only have single mapping type.
2021-02-07 13:24:03 +01:00
Jakub Vrana
52defd6f19 MongoDB: Prefer modern extension 2021-02-07 13:09:09 +01:00
ImDong
318cece1bd Fix MongoDB connect 'Database does not support password.' tips
Add MongoDB Drivers func ping.
2021-02-07 13:08:29 +01:00
Jakub Vrana
5c2f74136c Update bug numbers 2021-02-07 11:34:47 +01:00
Josef Drabek
8c392363b1 Postgres - fix missing partitioned tables in navigation 2021-02-07 11:21:50 +01:00
Albert Peschar
66b01a4b9c Linkify URLs in SQL results 2021-02-07 11:07:56 +01:00
tiso
7db10e95d9 Title for select data link 2021-02-07 11:00:35 +01:00
Jakub Vrana
31e28fbd00 Quote values with leading and trailing zeroes in CSV export (bug #777) 2021-02-07 09:41:07 +01:00
Jakub Vrana
19f23fe9ee MySQL: Don't quote default value of text fields (bug #779) 2021-02-07 09:31:31 +01:00
David Grudl
6e5315349b fixed Unsupported operand types when $port is socket 2021-02-07 09:31:28 +01:00
Jakub Vrana
95729680ef Respect SQL command URL parameters 2021-02-06 19:09:54 +01:00
Jakub Vrana
5c395afc09 Fix XSS in browsers which don't encode URL parameters (bug #775) 2021-02-06 19:09:42 +01:00
Jakub Vrana
cde988853d SQLite: Set busy_timeout to 500 2021-02-06 18:01:39 +01:00
Jakub Vrana
f8288dd227 PostgreSQL 11: Create PRIMARY KEY for auto increment columns 2021-02-06 18:01:24 +01:00
Jakub Vrana
94194aac19 PostgreSQL: Support smallserial 2021-02-06 18:00:22 +01:00
Jakub Vrana
438c7f55be Add comment 2021-02-06 16:58:59 +01:00
Jakub Vrana
7edf80f636 PostgreSQL PDO: Support PgBouncer, unsupport PostgreSQL < 9.1 (bug #771) 2021-02-06 16:45:20 +01:00
Pőcze Bence
b2e0d9f396 fix wrong hungarian translation 2021-02-06 16:22:28 +01:00
Jakub Vrana
cc9ed0939c Editor: Cast to string when searching (bug #325) 2021-02-06 16:11:21 +01:00
Jakub Vrana
ee75df6f15 Don't syntax highlight during IME composition (bug #747) 2021-02-06 16:11:02 +01:00
Jakub Vrana
23fdbedba1 PostgreSQL: Use bigserial for bigint auto increment (bug #765, regression from 3.0.0) 2021-02-06 15:33:50 +01:00
Michal Adamec
8762895bb3 MSSQL: Don't trucate displayed comments to 30 chars (use varchar maximum of 8000 upon casting) 2021-02-06 14:52:26 +01:00
Jakub Vrana
84063fb7cd Update Korean translation (thanks to B. Cansmile Cha) 2021-02-06 14:38:38 +01:00
Douglas Damasio
eb20ba30a1 add alternative design dracula theme 2021-02-06 14:19:30 +01:00
Oliver Tušla
1ce0a9aa94 show correct collation for PostgresSQL 2021-02-06 14:15:32 +01:00
Ivan Masár
96be913994 PostgreSQL: Fix current schema in view definition 2021-02-06 14:03:59 +01:00
shiipou
6f972ff9ab Add external designs as submodules 2021-02-06 13:45:58 +01:00
Lucas Sandery
7c4718ae3d Fixes to lucas-sandery theme 2021-02-06 12:32:32 +01:00
Jakub Vrana
b558ec8ecf Do not export names in quotes with sql_mode='ANSI_QUOTES' (bug #749) 2021-02-06 12:30:39 +01:00
Sartor
5cab8eabb7 Fix PgSQL generated always as identity fix 2021-02-06 12:18:27 +01:00
makss
d888031603 Update Russian translation. 2021-02-06 11:42:57 +01:00
makss
49f365384b Update Ukrainian translation. 2021-02-06 11:42:57 +01:00
Ivan Masár
34345d8071 PostgreSQL: Export all FKs after all CREATE TABLE 2021-02-06 11:37:47 +01:00
Jakub Vrana
97ec60bb5f MySQL, MariaDB: Fix doc links 2021-02-06 11:15:33 +01:00
Jakub Vrana
5a6e5b4443 Do not display SQL function for checkbox 2021-02-06 10:45:56 +01:00
Jakub Vrana
7b524ff5d2 Fix style (bug #743) 2021-02-06 10:45:56 +01:00
Jakub Vrana
64d4818a82 PostgreSQL: Fix dollar-quoted syntax highlighting (bug #738) 2021-02-06 10:45:56 +01:00
Jakub Vrana
ccd2374b0b Elasticsearch, ClickHouse: Do not print response if HTTP code is not 200
Thanks to Adam Crosser and Brian Sizemore
2021-02-06 10:45:56 +01:00
Evgeny Chernyavskiy
1e1c46ac72 Add basic Makefile. 2021-02-06 10:45:48 +01:00
Milan Felix Šulc
75cd1c3f28 Travis: add php 7.4 && 8.0 2020-12-10 09:05:31 +01:00
Jakub Vrana
b89d418dcf Re-enable PHP warnings 2020-12-09 15:45:54 +01:00
Jakub Vrana
190146672f Release 4.7.8 2020-12-06 13:58:20 +01:00
Jakub Vrana
d6e71b5c53 MySQL: Use renamed variable 2020-12-06 13:50:44 +01:00
Jakub Vrana
0618429bce Avoid PDO exceptions in PHP 8 2020-12-06 13:50:13 +01:00
Jakub Vrana
b0a217abdd Fix method call after #406 2020-12-06 13:45:55 +01:00
Jakub Vrana
35bfaa7506 Improve check for numeric ports (bug #769) 2020-12-06 13:14:41 +01:00
Jakub Vrana
e0a3205676 Add missing method 2020-12-06 13:00:17 +01:00
David Grudl
50bb83dbf2 Fix compatibility with PHP 8 2020-12-06 12:56:01 +01:00
Jakub Vrana
697eedc6a1 Avoid each() not available in PHP 8 2020-12-06 12:53:28 +01:00
Jakub Vrana
d94adc09cc Fix style 2020-12-06 12:53:27 +01:00
Jakub Vrana
4e2a448e28 Escape : also in remove_from_param 2020-05-11 12:35:19 +02:00
Jakub Vrana
ac40be998d Release 4.7.7 2020-05-11 11:51:57 +02:00
Jakub Vrana
6a2de873e1 Fix open redirect if Adminer is accessible at //adminer.php%2F@ (thanks to Prakash Sharma) 2020-05-11 11:49:46 +02:00
Jakub Vrana
a9c1004232 Update Finnish translation 2020-03-10 16:09:25 +01:00
Theodore Tsirpanis
37fa4de650 Fix typo in Greek translation 2020-03-06 16:36:09 +01:00
Jakub Vrana
1d1f11504c Add missing translation 2020-03-06 16:12:37 +01:00
Hugues Lismonde
3f38b61366 Fix forwarded IP comparison in login-ip plugin
The issue described in #372 is the same for the HTTP_X_FORWARDED_FOR comparison. strncasecmp returns 0 when the two strings are equal which is falsey.
2020-02-04 16:58:13 +01:00
Jakub Vrana
9ab205776d Release 4.7.6 2020-01-31 11:24:45 +01:00
Lukáš Holeczy
681b5e7b7a Fix comparing IPs 2020-01-30 18:32:34 +01:00
Jakub Vrana
9c5efb9f8c Update readme 2020-01-30 18:29:47 +01:00
Jakub Vrana
2373409631 Add example for using SQLite with Editor 2020-01-30 18:03:21 +01:00
Jakub Vrana
ad16cb8581 PostgreSQL: Support exporting views 2020-01-30 17:13:50 +01:00
Jakub Vrana
0293613c21 Disallow connecting to ports > 65535 (bug #730) 2020-01-30 17:13:17 +01:00
Jakub Vrana
fe9ea18d2e Display time of procedure execution 2020-01-30 16:27:12 +01:00
Jakub Vrana
6d39f290cc Hide columns when rendering 2019-12-20 14:00:40 +01:00
Jakub Vrana
1bfffbf26b Speed up alter table form 2019-12-20 13:50:20 +01:00
Jakub Vrana
f09003ea4b Fix clicking on non-input fields in alter table 2019-12-20 13:25:08 +01:00
Jakub Vrana
2f7f0df09f Editor: Fix focusing foreign key search in select 2019-12-12 15:37:30 +01:00
Jakub Vrana
5da5b75536 MySQL: Always set foreign_key_checks in export 2019-12-09 13:20:24 +01:00
Jakub Vrana
8706bc7c0f Release 4.7.5 2019-11-13 08:17:14 +01:00
Jakub Vrana
c2b7d38f2c Re-apply https://github.com/vrana/adminer/pull/363/commits/89b6e9bb 2019-11-11 14:41:11 +01:00
popcorner
fcd90a74f6 Update zh-tw.inc.php 2019-11-11 14:41:03 +01:00
popcorner
05cddd38e5 Update zh.inc.php 2019-11-11 14:41:03 +01:00
Mike Baranski
c7550bf68f Stop using adsrc column
Was removed in V12, invalid since V8.

See https://www.postgresql.org/docs/8.3/catalog-pg-attrdef.html
2019-11-11 14:19:39 +01:00
Vladimir Goncharov
6ae81cd0ea fixed: SQL command for insert, create table, etc. new: create/rename table, add/drop/change type for column 2019-11-11 14:11:49 +01:00
Raphael de Almeida
677774405c Fix brazilian portuguese translation 2019-11-11 14:04:47 +01:00
Rasmus
39375b82d8 Swedish translation 2019-11-11 14:01:45 +01:00
Jakub Vrana
5944ca09a3 Update hever design 2019-11-11 13:45:30 +01:00
Jakub Vrana
5a507ec586 Don't overwrite variable 2019-11-11 13:40:47 +01:00
Jakub Vrana
c24dd79c22 Add id="" to cells with failed inline edit (bug #708) 2019-11-11 12:27:53 +01:00
Jakub Vrana
08c132cbea Unify dumpTable declarations (bug #707) 2019-11-11 12:27:53 +01:00
Jakub Vrana
a4e997fe60 PostgreSQL, Oracle: Set schema for EXPLAIN queries in SQL command (bug #706) 2019-11-11 12:27:53 +01:00
Jakub Vrana
0678ce1222 Initialize version-noverify sooner (bug #705) 2019-11-11 12:27:53 +01:00
Jakub Vrana
5acdc55a4a Make context in qsa() optional 2019-11-11 12:27:53 +01:00
Jakub Vrana
fd5f5b8805 Delete extra newlines 2019-11-11 12:27:53 +01:00
Lucas Sandery
d90d06e832 correct complement of responsive media query 2019-11-11 12:27:34 +01:00
Lucas Sandery
feb59fa8cf update lucas-sandery theme 2019-11-11 12:27:34 +01:00
Jakub Vrána
1bcb440698 Add funding 2019-11-08 11:51:41 +01:00
197 changed files with 10187 additions and 7269 deletions

20
.editorconfig Normal file
View File

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

6
.gitattributes vendored Normal file
View File

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

3
.github/FUNDING.yml vendored Normal file
View File

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

4
.gitmodules vendored
View File

@@ -1,6 +1,6 @@
[submodule "jush"] [submodule "jush"]
path = externals/jush path = externals/jush
url = git://github.com/vrana/jush url = https://github.com/vrana/jush
[submodule "JsShrink"] [submodule "JsShrink"]
path = externals/JsShrink path = externals/JsShrink
url = git://github.com/vrana/JsShrink url = https://github.com/vrana/JsShrink

View File

@@ -4,4 +4,10 @@ php:
- 7.1 - 7.1
- 7.2 - 7.2
- 7.3 - 7.3
- 7.4
- 8.0
- 8.1
- 8.2
- 8.3
- 8.4
script: git diff --name-only $TRAVIS_COMMIT_RANGE | grep '\.php$' | xargs -n1 -P8 php -l | grep -v 'No syntax errors'; test $? -eq 1 script: git diff --name-only $TRAVIS_COMMIT_RANGE | grep '\.php$' | xargs -n1 -P8 php -l | grep -v 'No syntax errors'; test $? -eq 1

1
LICENSE Normal file
View File

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

39
Makefile Normal file
View File

@@ -0,0 +1,39 @@
ROOT_DIRECTORY = $(shell dirname "$(realpath $(lastword $(MAKEFILE_LIST)))")
PHP := $(shell which php)
PORT := 8000
.DEFAULT_GOAL := default
.PHONY: default
default: compile
.PHONY: compile
compile:
$(PHP) $(ROOT_DIRECTORY)/compile.php
.PHONY: server
server:
php \
--server 127.0.0.1:$(PORT) \
--docroot $(ROOT_DIRECTORY)
.PHONY: initialize
initialize:
git \
-C $(ROOT_DIRECTORY) \
submodule \
update \
--init \
--recursive
.PHONY: clean
clean:
rm \
--recursive \
--force \
$(ROOT_DIRECTORY)/adminer.php
.PHONY: clean.all
clean.all: clean

11
SECURITY.md Normal file
View File

@@ -0,0 +1,11 @@
# Security Policy
## Supported Versions
I support only the last published version and the last development version (last commit).
## Reporting a Vulnerability
To report a vulnerability, create a private bug at https://sourceforge.net/p/adminer/bugs-and-features/new/?private=1.
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,5 +1,7 @@
<?php <?php
$PROCEDURE = ($_GET["name"] ? $_GET["name"] : $_GET["call"]); namespace Adminer;
$PROCEDURE = ($_GET["name"] ?: $_GET["call"]);
page_header(lang('Call') . ": " . h($PROCEDURE), $error); page_header(lang('Call') . ": " . h($PROCEDURE), $error);
$routine = routine($_GET["call"], (isset($_GET["callf"]) ? "FUNCTION" : "PROCEDURE")); $routine = routine($_GET["call"], (isset($_GET["callf"]) ? "FUNCTION" : "PROCEDURE"));
@@ -32,13 +34,13 @@ if (!$error && $_POST) {
$query = (isset($_GET["callf"]) ? "SELECT" : "CALL") . " " . table($PROCEDURE) . "(" . implode(", ", $call) . ")"; $query = (isset($_GET["callf"]) ? "SELECT" : "CALL") . " " . table($PROCEDURE) . "(" . implode(", ", $call) . ")";
$start = microtime(true); $start = microtime(true);
$result = $connection->multi_query($query); $result = $connection->multi_query($query);
$affected = $connection->affected_rows; // getting warnigns overwrites this $affected = $connection->affected_rows; // getting warnings overwrites this
echo $adminer->selectQuery($query, $start, !$result); echo $adminer->selectQuery($query, $start, !$result);
if (!$result) { if (!$result) {
echo "<p class='error'>" . error() . "\n"; echo "<p class='error'>" . error() . "\n";
} else { } else {
$connection2 = connect(); $connection2 = connect($adminer->credentials());
if (is_object($connection2)) { if (is_object($connection2)) {
$connection2->select_db(DB); $connection2->select_db(DB);
} }
@@ -48,7 +50,9 @@ if (!$error && $_POST) {
if (is_object($result)) { if (is_object($result)) {
select($result, $connection2); select($result, $connection2);
} else { } else {
echo "<p class='message'>" . lang('Routine has been called, %d row(s) affected.', $affected) . "\n"; 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());
@@ -62,7 +66,7 @@ if (!$error && $_POST) {
<form action="" method="post"> <form action="" method="post">
<?php <?php
if ($in) { if ($in) {
echo "<table cellspacing='0' class='layout'>\n"; echo "<table class='layout'>\n";
foreach ($in as $key) { foreach ($in as $key) {
$field = $routine["fields"][$key]; $field = $routine["fields"][$key];
$name = $field["field"]; $name = $field["field"];
@@ -86,3 +90,25 @@ if ($in) {
<input type="submit" value="<?php echo lang('Call'); ?>"> <input type="submit" value="<?php echo lang('Call'); ?>">
<input type="hidden" name="token" value="<?php echo $token; ?>"> <input type="hidden" name="token" value="<?php echo $token; ?>">
</form> </form>
<pre>
<?php
function pre_tr($s) {
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>

51
adminer/check.inc.php Normal file
View File

@@ -0,0 +1,51 @@
<?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(), 0, 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 } ?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form>

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$TABLE = $_GET["create"]; $TABLE = $_GET["create"];
$partition_by = array(); $partition_by = array();
foreach (array('HASH', 'LINEAR HASH', 'KEY', 'LINEAR KEY', 'RANGE', 'LIST') as $key) { foreach (array('HASH', 'LINEAR HASH', 'KEY', 'LINEAR KEY', 'RANGE', 'LIST') as $key) {
@@ -46,22 +48,19 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
$foreign_key = $foreign_keys[$field["type"]]; $foreign_key = $foreign_keys[$field["type"]];
$type_field = ($foreign_key !== null ? $referencable_primary[$foreign_key] : $field); //! can collide with user defined type $type_field = ($foreign_key !== null ? $referencable_primary[$foreign_key] : $field); //! can collide with user defined type
if ($field["field"] != "") { if ($field["field"] != "") {
if (!$field["has_default"]) { if (!$field["generated"]) {
$field["default"] = null; $field["default"] = null;
} }
if ($key == $row["auto_increment_col"]) {
$field["auto_increment"] = true;
}
$process_field = process_field($field, $type_field); $process_field = process_field($field, $type_field);
$all_fields[] = array($field["orig"], $process_field, $after); $all_fields[] = array($field["orig"], $process_field, $after);
if ($process_field != process_field($orig_field, $orig_field)) { if (!$orig_field || $process_field !== process_field($orig_field, $orig_field)) {
$fields[] = array($field["orig"], $process_field, $after); $fields[] = array($field["orig"], $process_field, $after);
if ($field["orig"] != "" || $after) { if ($field["orig"] != "" || $after) {
$use_all_fields = true; $use_all_fields = true;
} }
} }
if ($foreign_key !== null) { if ($foreign_key !== null) {
$foreign[idf_escape($field["field"])] = ($TABLE != "" && $jush != "sqlite" ? "ADD" : " ") . format_foreign_key(array( $foreign[idf_escape($field["field"])] = ($TABLE != "" && JUSH != "sqlite" ? "ADD" : " ") . format_foreign_key(array(
'table' => $foreign_keys[$field["type"]], 'table' => $foreign_keys[$field["type"]],
'source' => array($field["field"]), 'source' => array($field["field"]),
'target' => array($type_field["field"]), 'target' => array($type_field["field"]),
@@ -82,21 +81,40 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
} }
$partitioning = ""; $partitioning = "";
if ($partition_by[$row["partition_by"]]) { if (support("partitioning")) {
if (isset($partition_by[$row["partition_by"]])) {
$params = array_filter($row, function ($key) {
return preg_match('~^partition~', $key);
}, ARRAY_FILTER_USE_KEY);
foreach ($params["partition_names"] as $key => $name) {
if ($name == "") {
unset($params["partition_names"][$key]);
unset($params["partition_values"][$key]);
}
}
if ($params != get_partitions_info($TABLE)) {
$partitions = array(); $partitions = array();
if ($row["partition_by"] == 'RANGE' || $row["partition_by"] == 'LIST') { if ($params["partition_by"] == 'RANGE' || $params["partition_by"] == 'LIST') {
foreach (array_filter($row["partition_names"]) as $key => $val) { foreach ($params["partition_names"] as $key => $name) {
$value = $row["partition_values"][$key]; $value = $params["partition_values"][$key];
$partitions[] = "\n PARTITION " . idf_escape($val) . " VALUES " . ($row["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection $partitions[] = "\n PARTITION " . idf_escape($name) . " VALUES " . ($params["partition_by"] == 'RANGE' ? "LESS THAN" : "IN") . ($value != "" ? " ($value)" : " MAXVALUE"); //! SQL injection
} }
} }
$partitioning .= "\nPARTITION BY $row[partition_by]($row[partition])" . ($partitions // $row["partition"] can be expression, not only column
? " (" . implode(",", $partitions) . "\n)" // $params["partition"] can be expression, not only column
: ($row["partitions"] ? " PARTITIONS " . (+$row["partitions"]) : "") $partitioning .= "\nPARTITION BY $params[partition_by]($params[partition])";
); if ($partitions) {
} elseif (support("partitioning") && preg_match("~partitioned~", $table_status["Create_options"])) { $partitioning .= " (" . implode(",", $partitions) . "\n)";
} elseif ($params["partitions"]) {
$partitioning .= " PARTITIONS " . (+$params["partitions"]);
}
}
} elseif (preg_match("~partitioned~", $table_status["Create_options"])) {
$partitioning .= "\nREMOVE PARTITIONING"; $partitioning .= "\nREMOVE PARTITIONING";
} }
}
$message = lang('Table has been altered.'); $message = lang('Table has been altered.');
if ($TABLE == "") { if ($TABLE == "") {
@@ -108,7 +126,7 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
queries_redirect(ME . (support("table") ? "table=" : "select=") . urlencode($name), $message, alter_table( queries_redirect(ME . (support("table") ? "table=" : "select=") . urlencode($name), $message, alter_table(
$TABLE, $TABLE,
$name, $name,
($jush == "sqlite" && ($use_all_fields || $foreign) ? $all_fields : $fields), (JUSH == "sqlite" && ($use_all_fields || $foreign) ? $all_fields : $fields),
$foreign, $foreign,
($row["Comment"] != $table_status["Comment"] ? $row["Comment"] : null), ($row["Comment"] != $table_status["Comment"] ? $row["Comment"] : null),
($row["Engine"] && $row["Engine"] != $table_status["Engine"] ? $row["Engine"] : ""), ($row["Engine"] && $row["Engine"] != $table_status["Engine"] ? $row["Engine"] : ""),
@@ -122,6 +140,7 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
page_header(($TABLE != "" ? lang('Alter table') : lang('Create table')), $error, array("table" => $TABLE), h($TABLE)); page_header(($TABLE != "" ? lang('Alter table') : lang('Create table')), $error, array("table" => $TABLE), h($TABLE));
if (!$_POST) { if (!$_POST) {
$types = $driver->types();
$row = array( $row = array(
"Engine" => $_COOKIE["adminer_engine"], "Engine" => $_COOKIE["adminer_engine"],
"fields" => array(array("field" => "", "type" => (isset($types["int"]) ? "int" : (isset($types["integer"]) ? "integer" : "")), "on_update" => "")), "fields" => array(array("field" => "", "type" => (isset($types["int"]) ? "int" : (isset($types["integer"]) ? "integer" : "")), "on_update" => "")),
@@ -136,18 +155,14 @@ if (!$_POST) {
$row["Auto_increment"] = ""; $row["Auto_increment"] = "";
} }
foreach ($orig_fields as $field) { foreach ($orig_fields as $field) {
$field["has_default"] = isset($field["default"]); $field["generated"] = $field["generated"] ?: (isset($field["default"]) ? "DEFAULT" : "");
$row["fields"][] = $field; $row["fields"][] = $field;
} }
if (support("partitioning")) { if (support("partitioning")) {
$from = "FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = " . q(DB) . " AND TABLE_NAME = " . q($TABLE); $row += get_partitions_info($TABLE);
$result = $connection->query("SELECT PARTITION_METHOD, PARTITION_ORDINAL_POSITION, PARTITION_EXPRESSION $from ORDER BY PARTITION_ORDINAL_POSITION DESC LIMIT 1"); $row["partition_names"][] = "";
list($row["partition_by"], $row["partitions"], $row["partition"]) = $result->fetch_row(); $row["partition_values"][] = "";
$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);
} }
} }
} }
@@ -166,34 +181,42 @@ foreach ($engines as $engine) {
<form action="" method="post" id="form"> <form action="" method="post" id="form">
<p> <p>
<?php if (support("columns") || $TABLE == "") { ?> <?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 echo lang('Table name'); ?>: <input name="name"<?php echo ($TABLE == "" && !$_POST ? " autofocus" : ""); ?> 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 ($engines ? "<select name='Engine'>" . optionlist(array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . "</select>" . on_help("getTarget(event).value", 1) . script("qsl('select').onchange = helpClose;") : ""); ?>
<?php echo ($collations && !preg_match("~sqlite|mssql~", $jush) ? html_select("Collation", array("" => "(" . lang('collation') . ")") + $collations, $row["Collation"]) : ""); ?> <?php echo ($collations && !preg_match("~sqlite|mssql~", JUSH) ? html_select("Collation", array("" => "(" . lang('collation') . ")") + $collations, $row["Collation"]) : ""); ?>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php } ?> <?php } ?>
<?php if (support("columns")) { ?> <?php if (support("columns")) { ?>
<div class="scrollable"> <div class="scrollable">
<table cellspacing="0" id="edit-fields" class="nowrap"> <table id="edit-fields" class="nowrap">
<?php <?php
edit_fields($row["fields"], $collations, "TABLE", $foreign_keys); edit_fields($row["fields"], $collations, "TABLE", $foreign_keys);
?> ?>
</table> </table>
<?php echo script("editFields();"); ?>
</div> </div>
<p> <p>
<?php echo lang('Auto Increment'); ?>: <input type="number" name="Auto_increment" size="6" value="<?php echo h($row["Auto_increment"]); ?>"> <?php echo lang('Auto Increment'); ?>: <input type="number" name="Auto_increment" class="size" value="<?php echo h($row["Auto_increment"]); ?>">
<?php echo checkbox("defaults", 1, ($_POST ? $_POST["defaults"] : adminer_setting("defaults")), lang('Default values'), "columnShow(this.checked, 5)", "jsonly"); ?> <?php echo checkbox("defaults", 1, ($_POST ? $_POST["defaults"] : adminer_setting("defaults")), lang('Default values'), "columnShow(this.checked, 5)", "jsonly"); ?>
<?php echo (support("comment") <?php
? checkbox("comments", 1, ($_POST ? $_POST["comments"] : adminer_setting("comments")), lang('Comment'), "editingCommentsClick(this, true);", "jsonly") $comments = ($_POST ? $_POST["comments"] : adminer_setting("comments"));
. ' <input name="Comment" value="' . h($row["Comment"]) . '" data-maxlength="' . (min_version(5.5) ? 2048 : 60) . '">' 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> <p>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php } ?> <?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 <?php
if (support("partitioning")) { if (support("partitioning")) {
$partition_table = preg_match('~RANGE|LIST~', $row["partition_by"]); $partition_table = preg_match('~RANGE|LIST~', $row["partition_by"]);
@@ -203,7 +226,7 @@ if (support("partitioning")) {
<?php echo "<select name='partition_by'>" . optionlist(array("" => "") + $partition_by, $row["partition_by"]) . "</select>" . on_help("getTarget(event).value.replace(/./, 'PARTITION BY \$&')", 1) . script("qsl('select').onchange = partitionByChange;"); ?> <?php echo "<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"]); ?>">) (<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"]); ?>"> <?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'"); ?>> <table id="partition-table"<?php echo ($partition_table ? "" : " class='hidden'"); ?>>
<thead><tr><th><?php echo lang('Partition name'); ?><th><?php echo lang('Values'); ?></thead> <thead><tr><th><?php echo lang('Partition name'); ?><th><?php echo lang('Values'); ?></thead>
<?php <?php
foreach ($row["partition_names"] as $key => $val) { foreach ($row["partition_names"] as $key => $val) {
@@ -220,4 +243,3 @@ foreach ($row["partition_names"] as $key => $val) {
?> ?>
<input type="hidden" name="token" value="<?php echo $token; ?>"> <input type="hidden" name="token" value="<?php echo $token; ?>">
</form> </form>
<?php echo script("qs('#form')['defaults'].onclick();" . (support("comment") ? " editingCommentsClick(qs('#form')['comments']);" : "")); ?>

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$row = $_POST; $row = $_POST;
if ($_POST && !$error && !isset($_POST["add_x"])) { // add is an image and PHP changes add.x to add_x if ($_POST && !$error && !isset($_POST["add_x"])) { // add is an image and PHP changes add.x to add_x
@@ -44,7 +46,7 @@ if ($_POST) {
$name = $row["name"]; $name = $row["name"];
} elseif (DB != "") { } elseif (DB != "") {
$row["collation"] = db_collation(DB, $collations); $row["collation"] = db_collation(DB, $collations);
} elseif ($jush == "sql") { } elseif (JUSH == "sql") {
// propose database name with limited privileges // propose database name with limited privileges
foreach (get_vals("SHOW GRANTS") as $grant) { foreach (get_vals("SHOW GRANTS") as $grant) {
if (preg_match('~ ON (`(([^\\\\`]|``|\\\\.)*)%`\.\*)?~', $grant, $match) && $match[1]) { if (preg_match('~ ON (`(([^\\\\`]|``|\\\\.)*)%`\.\*)?~', $grant, $match) && $match[1]) {
@@ -59,14 +61,13 @@ if ($_POST) {
<p> <p>
<?php <?php
echo ($_POST["add_x"] || strpos($name, "\n") echo ($_POST["add_x"] || strpos($name, "\n")
? '<textarea id="name" name="name" rows="10" cols="40">' . h($name) . '</textarea><br>' ? '<textarea autofocus name="name" rows="10" cols="40">' . h($name) . '</textarea><br>'
: '<input name="name" id="name" value="' . h($name) . '" data-maxlength="64" autocapitalize="off">' : '<input name="name" autofocus value="' . h($name) . '" data-maxlength="64" autocapitalize="off">'
) . "\n" . ($collations ? html_select("collation", array("" => "(" . lang('collation') . ")") + $collations, $row["collation"]) . doc_link(array( ) . "\n" . ($collations ? html_select("collation", array("" => "(" . lang('collation') . ")") + $collations, $row["collation"]) . doc_link(array(
'sql' => "charset-charsets.html", 'sql' => "charset-charsets.html",
'mariadb' => "supported-character-sets-and-collations/", 'mariadb' => "supported-character-sets-and-collations/",
'mssql' => "ms187963.aspx", 'mssql' => "relational-databases/system-functions/sys-fn-helpcollations-transact-sql",
)) : ""); )) : "");
echo script("focus(qs('#name'));");
?> ?>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php <?php

View File

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

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$TABLE = $_GET["download"]; $TABLE = $_GET["download"];
$fields = fields($TABLE); $fields = fields($TABLE);
header("Content-Type: application/octet-stream"); header("Content-Type: application/octet-stream");

View File

@@ -1,354 +0,0 @@
<?php
$drivers["clickhouse"] = "ClickHouse (alpha)";
if (isset($_GET["clickhouse"])) {
define("DRIVER", "clickhouse");
class Min_DB {
var $extension = "JSON", $server_info, $errno, $_result, $error, $_url;
var $_db = 'default';
function rootQuery($db, $query) {
@ini_set('track_errors', 1); // @ - may be disabled
$file = @file_get_contents("$this->_url/?database=$db", false, stream_context_create(array('http' => array(
'method' => 'POST',
'content' => $this->isQuerySelectLike($query) ? "$query FORMAT JSONCompact" : $query,
'header' => 'Content-type: application/x-www-form-urlencoded',
'ignore_errors' => 1, // available since PHP 5.2.10
))));
if ($file === false) {
$this->error = $php_errormsg;
return $file;
}
if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) {
$this->error = $file;
return false;
}
$return = json_decode($file, true);
if ($return === null) {
$this->errno = json_last_error();
if (function_exists('json_last_error_msg')) {
$this->error = json_last_error_msg();
} else {
$constants = get_defined_constants(true);
foreach ($constants['json'] as $name => $value) {
if ($value == $this->errno && preg_match('~^JSON_ERROR_~', $name)) {
$this->error = $name;
break;
}
}
}
}
return new Min_Result($return);
}
function isQuerySelectLike($query) {
return (bool) preg_match('~^(select|show)~i', $query);
}
function query($query) {
return $this->rootQuery($this->_db, $query);
}
function connect($server, $username, $password) {
preg_match('~^(https?://)?(.*)~', $server, $match);
$this->_url = ($match[1] ? $match[1] : "http://") . "$username:$password@$match[2]";
$return = $this->query('SELECT 1');
return (bool) $return;
}
function select_db($database) {
$this->_db = $database;
return true;
}
function quote($string) {
return "'" . addcslashes($string, "\\'") . "'";
}
function multi_query($query) {
return $this->_result = $this->query($query);
}
function store_result() {
return $this->_result;
}
function next_result() {
return false;
}
function result($query, $field = 0) {
$result = $this->query($query);
return $result['data'];
}
}
class Min_Result {
var $num_rows, $_rows, $columns, $meta, $_offset = 0;
function __construct($result) {
$this->num_rows = $result['rows'];
$this->_rows = $result['data'];
$this->meta = $result['meta'];
$this->columns = array_column($this->meta, 'name');
reset($this->_rows);
}
function fetch_assoc() {
$row = current($this->_rows);
next($this->_rows);
return $row === false ? false : array_combine($this->columns, $row);
}
function fetch_row() {
$row = current($this->_rows);
next($this->_rows);
return $row;
}
function fetch_field() {
$column = $this->_offset++;
$return = new stdClass;
if ($column < count($this->columns)) {
$return->name = $this->meta[$column]['name'];
$return->orgname = $return->name;
$return->type = $this->meta[$column]['type'];
}
return $return;
}
}
class Min_Driver extends Min_SQL {
function delete($table, $queryWhere, $limit = 0) {
return queries("ALTER TABLE " . table($table) . " DELETE $queryWhere");
}
function update($table, $set, $queryWhere, $limit = 0, $separator = "\n") {
$values = array();
foreach ($set as $key => $val) {
$values[] = "$key = $val";
}
$query = $separator . implode(",$separator", $values);
return queries("ALTER TABLE " . table($table) . " UPDATE $query$queryWhere");
}
}
function idf_escape($idf) {
return "`" . str_replace("`", "``", $idf) . "`";
}
function table($idf) {
return idf_escape($idf);
}
function explain($connection, $query) {
return '';
}
function found_rows($table_status, $where) {
$rows = get_vals("SELECT COUNT(*) FROM " . idf_escape($table_status["Name"]) . ($where ? " WHERE " . implode(" AND ", $where) : ""));
return empty($rows) ? false : $rows[0];
}
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
foreach ($fields as $field) {
if ($field[1][2] === " NULL") {
$field[1][1] = " Nullable({$field[1][1]})";
}
unset($field[1][2]);
}
}
function truncate_tables($tables) {
return apply_queries("TRUNCATE TABLE", $tables);
}
function drop_views($views) {
return drop_tables($views);
}
function drop_tables($tables) {
return apply_queries("DROP TABLE", $tables);
}
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($flush) {
global $connection;
$result = get_rows('SHOW DATABASES');
$return = array();
foreach ($result as $row) {
$return[] = $row['name'];
}
sort($return);
return $return;
}
function limit($query, $where, $limit, $offset = 0, $separator = " ") {
return " $query$where" . ($limit !== null ? $separator . "LIMIT $limit" . ($offset ? ", $offset" : "") : "");
}
function limit1($table, $query, $where, $separator = "\n") {
return limit($query, $where, 1, 0, $separator);
}
function db_collation($db, $collations) {
}
function engines() {
return array('MergeTree');
}
function logged_user() {
global $adminer;
$credentials = $adminer->credentials();
return $credentials[1];
}
function tables_list() {
$result = get_rows('SHOW TABLES');
$return = array();
foreach ($result as $row) {
$return[$row['name']] = 'table';
}
ksort($return);
return $return;
}
function count_tables($databases) {
return array();
}
function table_status($name = "", $fast = false) {
global $connection;
$return = array();
$tables = get_rows("SELECT name, engine FROM system.tables WHERE database = " . q($connection->_db));
foreach ($tables as $table) {
$return[$table['name']] = array(
'Name' => $table['name'],
'Engine' => $table['engine'],
);
if ($name === $table['name']) {
return $return[$table['name']];
}
}
return $return;
}
function is_view($table_status) {
return false;
}
function fk_support($table_status) {
return false;
}
function convert_field($field) {
}
function unconvert_field($field, $return) {
if (in_array($field['type'], array("Int8", "Int16", "Int32", "Int64", "UInt8", "UInt16", "UInt32", "UInt64", "Float32", "Float64"))) {
return "to$field[type]($return)";
}
return $return;
}
function fields($table) {
$return = array();
$result = get_rows("SELECT name, type, default_expression FROM system.columns WHERE " . idf_escape('table') . " = " . q($table));
foreach($result as $row) {
$type = trim($row['type']);
$nullable = strpos($type, 'Nullable(') === 0;
$return[trim($row['name'])] = array(
"field" => trim($row['name']),
"full_type" => $type,
"type" => $type,
"default" => trim($row['default_expression']),
"null" => $nullable,
"auto_increment" => '0',
"privileges" => array("insert" => 1, "select" => 1, "update" => 0),
);
}
return $return;
}
function indexes($table, $connection2 = null) {
return array();
}
function foreign_keys($table) {
return array();
}
function collations() {
return array();
}
function information_schema($db) {
return false;
}
function error() {
global $connection;
return h($connection->error);
}
function types() {
return array();
}
function schemas() {
return array();
}
function get_schema() {
return "";
}
function set_schema($schema) {
return true;
}
function auto_increment() {
return '';
}
function last_id() {
return 0; // ClickHouse doesn't have it
}
function support($feature) {
return preg_match("~^(columns|sql|status|table)$~", $feature);
}
$jush = "clickhouse";
$types = array();
$structured_types = array();
foreach (array( //! arrays
lang('Numbers') => array("Int8" => 3, "Int16" => 5, "Int32" => 10, "Int64" => 19, "UInt8" => 3, "UInt16" => 5, "UInt32" => 10, "UInt64" => 20, "Float32" => 7, "Float64" => 16, 'Decimal' => 38, 'Decimal32' => 9, 'Decimal64' => 18, 'Decimal128' => 38),
lang('Date and time') => array("Date" => 13, "DateTime" => 20),
lang('Strings') => array("String" => 0),
lang('Binary') => array("FixedString" => 0),
) as $key => $val) {
$types += $val;
$structured_types[$key] = array_keys($val);
}
$unsigned = array();
$operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL");
$functions = array();
$grouping = array("avg", "count", "count distinct", "max", "min", "sum");
$edit_functions = array();
}

View File

@@ -1,465 +0,0 @@
<?php
$drivers["elastic"] = "Elasticsearch (beta)";
if (isset($_GET["elastic"])) {
$possible_drivers = array("json + allow_url_fopen");
define("DRIVER", "elastic");
if (function_exists('json_decode') && ini_bool('allow_url_fopen')) {
class Min_DB {
var $extension = "JSON", $server_info, $errno, $error, $_url;
/** Performs query
* @param string
* @param array
* @param string
* @return mixed
*/
function rootQuery($path, $content = array(), $method = 'GET') {
@ini_set('track_errors', 1); // @ - may be disabled
$file = @file_get_contents("$this->_url/" . ltrim($path, '/'), false, stream_context_create(array('http' => array(
'method' => $method,
'content' => $content === null ? $content : json_encode($content),
'header' => 'Content-Type: application/json',
'ignore_errors' => 1, // available since PHP 5.2.10
))));
if (!$file) {
$this->error = $php_errormsg;
return $file;
}
if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) {
$this->error = $file;
return false;
}
$return = json_decode($file, true);
if ($return === null) {
$this->errno = json_last_error();
if (function_exists('json_last_error_msg')) {
$this->error = json_last_error_msg();
} else {
$constants = get_defined_constants(true);
foreach ($constants['json'] as $name => $value) {
if ($value == $this->errno && preg_match('~^JSON_ERROR_~', $name)) {
$this->error = $name;
break;
}
}
}
}
return $return;
}
/** Performs query relative to actual selected DB
* @param string
* @param array
* @param string
* @return mixed
*/
function query($path, $content = array(), $method = 'GET') {
return $this->rootQuery(($this->_db != "" ? "$this->_db/" : "/") . ltrim($path, '/'), $content, $method);
}
function connect($server, $username, $password) {
preg_match('~^(https?://)?(.*)~', $server, $match);
$this->_url = ($match[1] ? $match[1] : "http://") . "$username:$password@$match[2]";
$return = $this->query('');
if ($return) {
$this->server_info = $return['version']['number'];
}
return (bool) $return;
}
function select_db($database) {
$this->_db = $database;
return true;
}
function quote($string) {
return $string;
}
}
class Min_Result {
var $num_rows, $_rows;
function __construct($rows) {
$this->num_rows = count($rows);
$this->_rows = $rows;
reset($this->_rows);
}
function fetch_assoc() {
$return = current($this->_rows);
next($this->_rows);
return $return;
}
function fetch_row() {
return array_values($this->fetch_assoc());
}
}
}
class Min_Driver extends Min_SQL {
function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
global $adminer;
$data = array();
$query = "$table/_search";
if ($select != array("*")) {
$data["fields"] = $select;
}
if ($order) {
$sort = array();
foreach ($order as $col) {
$col = preg_replace('~ DESC$~', '', $col, 1, $count);
$sort[] = ($count ? array($col => "desc") : $col);
}
$data["sort"] = $sort;
}
if ($limit) {
$data["size"] = +$limit;
if ($page) {
$data["from"] = ($page * $limit);
}
}
foreach ($where as $val) {
list($col, $op, $val) = explode(" ", $val, 3);
if ($col == "_id") {
$data["query"]["ids"]["values"][] = $val;
}
elseif ($col . $val != "") {
$term = array("term" => array(($col != "" ? $col : "_all") => $val));
if ($op == "=") {
$data["query"]["filtered"]["filter"]["and"][] = $term;
} else {
$data["query"]["filtered"]["query"]["bool"]["must"][] = $term;
}
}
}
if ($data["query"] && !$data["query"]["filtered"]["query"] && !$data["query"]["ids"]) {
$data["query"]["filtered"]["query"] = array("match_all" => array());
}
$start = microtime(true);
$search = $this->_conn->query($query, $data);
if ($print) {
echo $adminer->selectQuery("$query: " . json_encode($data), $start, !$search);
}
if (!$search) {
return false;
}
$return = array();
foreach ($search['hits']['hits'] as $hit) {
$row = array();
if ($select == array("*")) {
$row["_id"] = $hit["_id"];
}
$fields = $hit['_source'];
if ($select != array("*")) {
$fields = array();
foreach ($select as $key) {
$fields[$key] = $hit['fields'][$key];
}
}
foreach ($fields as $key => $val) {
if ($data["fields"]) {
$val = $val[0];
}
$row[$key] = (is_array($val) ? json_encode($val) : $val); //! display JSON and others differently
}
$return[] = $row;
}
return new Min_Result($return);
}
function update($type, $record, $queryWhere, $limit = 0, $separator = "\n") {
//! use $limit
$parts = preg_split('~ *= *~', $queryWhere);
if (count($parts) == 2) {
$id = trim($parts[1]);
$query = "$type/$id";
return $this->_conn->query($query, $record, 'POST');
}
return false;
}
function insert($type, $record) {
$id = ""; //! user should be able to inform _id
$query = "$type/$id";
$response = $this->_conn->query($query, $record, 'POST');
$this->_conn->last_id = $response['_id'];
return $response['created'];
}
function delete($type, $queryWhere, $limit = 0) {
//! use $limit
$ids = array();
if (is_array($_GET["where"]) && $_GET["where"]["_id"]) {
$ids[] = $_GET["where"]["_id"];
}
if (is_array($_POST['check'])) {
foreach ($_POST['check'] as $check) {
$parts = preg_split('~ *= *~', $check);
if (count($parts) == 2) {
$ids[] = trim($parts[1]);
}
}
}
$this->_conn->affected_rows = 0;
foreach ($ids as $id) {
$query = "{$type}/{$id}";
$response = $this->_conn->query($query, '{}', 'DELETE');
if (is_array($response) && $response['found'] == true) {
$this->_conn->affected_rows++;
}
}
return $this->_conn->affected_rows;
}
}
function connect() {
global $adminer;
$connection = new Min_DB;
list($server, $username, $password) = $adminer->credentials();
if ($password != "" && $connection->connect($server, $username, "")) {
return lang('Database does not support password.');
}
if ($connection->connect($server, $username, $password)) {
return $connection;
}
return $connection->error;
}
function support($feature) {
return preg_match("~database|table|columns~", $feature);
}
function logged_user() {
global $adminer;
$credentials = $adminer->credentials();
return $credentials[1];
}
function get_databases() {
global $connection;
$return = $connection->rootQuery('_aliases');
if ($return) {
$return = array_keys($return);
sort($return, SORT_STRING);
}
return $return;
}
function collations() {
return array();
}
function db_collation($db, $collations) {
}
function engines() {
return array();
}
function count_tables($databases) {
global $connection;
$return = array();
$result = $connection->query('_stats');
if ($result && $result['indices']) {
$indices = $result['indices'];
foreach ($indices as $indice => $stats) {
$indexing = $stats['total']['indexing'];
$return[$indice] = $indexing['index_total'];
}
}
return $return;
}
function tables_list() {
global $connection;
$return = $connection->query('_mapping');
if ($return) {
$return = array_fill_keys(array_keys($return[$connection->_db]["mappings"]), 'table');
}
return $return;
}
function table_status($name = "", $fast = false) {
global $connection;
$search = $connection->query("_search", array(
"size" => 0,
"aggregations" => array(
"count_by_type" => array(
"terms" => array(
"field" => "_type"
)
)
)
), "POST");
$return = array();
if ($search) {
$tables = $search["aggregations"]["count_by_type"]["buckets"];
foreach ($tables as $table) {
$return[$table["key"]] = array(
"Name" => $table["key"],
"Engine" => "table",
"Rows" => $table["doc_count"],
);
if ($name != "" && $name == $table["key"]) {
return $return[$name];
}
}
}
return $return;
}
function error() {
global $connection;
return h($connection->error);
}
function information_schema() {
}
function is_view($table_status) {
}
function indexes($table, $connection2 = null) {
return array(
array("type" => "PRIMARY", "columns" => array("_id")),
);
}
function fields($table) {
global $connection;
$result = $connection->query("$table/_mapping");
$return = array();
if ($result) {
$mappings = $result[$table]['properties'];
if (!$mappings) {
$mappings = $result[$connection->_db]['mappings'][$table]['properties'];
}
if ($mappings) {
foreach ($mappings as $name => $field) {
$return[$name] = array(
"field" => $name,
"full_type" => $field["type"],
"type" => $field["type"],
"privileges" => array("insert" => 1, "select" => 1, "update" => 1),
);
if ($field["properties"]) { // only leaf fields can be edited
unset($return[$name]["privileges"]["insert"]);
unset($return[$name]["privileges"]["update"]);
}
}
}
}
return $return;
}
function foreign_keys($table) {
return array();
}
function table($idf) {
return $idf;
}
function idf_escape($idf) {
return $idf;
}
function convert_field($field) {
}
function unconvert_field($field, $return) {
return $return;
}
function fk_support($table_status) {
}
function found_rows($table_status, $where) {
return null;
}
/** Create index
* @param string
* @return mixed
*/
function create_database($db) {
global $connection;
return $connection->rootQuery(urlencode($db), null, 'PUT');
}
/** Remove index
* @param array
* @return mixed
*/
function drop_databases($databases) {
global $connection;
return $connection->rootQuery(urlencode(implode(',', $databases)), array(), 'DELETE');
}
/** Alter type
* @param array
* @return mixed
*/
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
global $connection;
$properties = array();
foreach ($fields as $f) {
$field_name = trim($f[1][0]);
$field_type = trim($f[1][1] ? $f[1][1] : "text");
$properties[$field_name] = array(
'type' => $field_type
);
}
if (!empty($properties)) {
$properties = array('properties' => $properties);
}
return $connection->query("_mapping/{$name}", $properties, 'PUT');
}
/** Drop types
* @param array
* @return bool
*/
function drop_tables($tables) {
global $connection;
$return = true;
foreach ($tables as $table) { //! convert to bulk api
$return = $return && $connection->query(urlencode($table), array(), 'DELETE');
}
return $return;
}
function last_id() {
global $connection;
return $connection->last_id;
}
$jush = "elastic";
$operators = array("=", "query");
$functions = array();
$grouping = array();
$edit_functions = array(array("json"));
$types = array(); ///< @var array ($type => $maximum_unsigned_length, ...)
$structured_types = array(); ///< @var array ($description => array($type, ...), ...)
foreach (array(
lang('Numbers') => array("long" => 3, "integer" => 5, "short" => 8, "byte" => 10, "double" => 20, "float" => 66, "half_float" => 12, "scaled_float" => 21),
lang('Date and time') => array("date" => 10),
lang('Strings') => array("string" => 65535, "text" => 65535),
lang('Binary') => array("binary" => 255),
) as $key => $val) {
$types += $val;
$structured_types[$key] = array_keys($val);
}
}

View File

@@ -1,16 +1,41 @@
<?php <?php
$drivers["mongo"] = "MongoDB"; namespace Adminer;
$drivers["mongo"] = "MongoDB (alpha)";
if (isset($_GET["mongo"])) { if (isset($_GET["mongo"])) {
$possible_drivers = array("mongo", "mongodb"); define('Adminer\DRIVER', "mongo");
define("DRIVER", "mongo");
if (class_exists('MongoDB')) { if (class_exists('MongoDB\Driver\Manager')) {
class Min_DB { class Db {
var $extension = "Mongo", $server_info = MongoClient::VERSION, $error, $last_id, $_link, $_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) { function connect($uri, $options) {
return @new MongoClient($uri, $options); $this->_link = new \MongoDB\Driver\Manager($uri, $options);
$this->executeCommand($options["db"], array('ping' => 1));
}
function executeCommand($db, $command) {
try {
return $this->_link->executeCommand($db, new \MongoDB\Driver\Command($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) { function query($query) {
@@ -18,38 +43,32 @@ if (isset($_GET["mongo"])) {
} }
function select_db($database) { function select_db($database) {
try { $this->_db_name = $database;
$this->_db = $this->_link->selectDB($database);
return true; return true;
} catch (Exception $ex) {
$this->error = $ex->getMessage();
return false;
}
} }
function quote($string) { function quote($string) {
return $string; return $string;
} }
} }
class Min_Result { class Result {
var $num_rows, $_rows = array(), $_offset = 0, $_charset = array(); var $num_rows, $_rows = array(), $_offset = 0, $_charset = array();
function __construct($result) { function __construct($result) {
foreach ($result as $item) { foreach ($result as $item) {
$row = array(); $row = array();
foreach ($item as $key => $val) { foreach ($item as $key => $val) {
if (is_a($val, 'MongoBinData')) { if (is_a($val, 'MongoDB\BSON\Binary')) {
$this->_charset[$key] = 63; $this->_charset[$key] = 63;
} }
$row[$key] = $row[$key] =
(is_a($val, 'MongoId') ? 'ObjectId("' . strval($val) . '")' : (is_a($val, 'MongoDB\BSON\ObjectID') ? 'MongoDB\BSON\ObjectID("' . "$val\")" :
(is_a($val, 'MongoDate') ? gmdate("Y-m-d H:i:s", $val->sec) . " GMT" : (is_a($val, 'MongoDB\BSON\UTCDatetime') ? $val->toDateTime()->format('Y-m-d H:i:s') :
(is_a($val, 'MongoBinData') ? $val->bin : //! allow downloading (is_a($val, 'MongoDB\BSON\Binary') ? $val->getData() : //! allow downloading
(is_a($val, 'MongoRegex') ? strval($val) : (is_a($val, 'MongoDB\BSON\Regex') ? "$val" :
(is_object($val) ? get_class($val) : // MongoMinKey, MongoMaxKey (is_object($val) || is_array($val) ? json_encode($val, 256) : // 256 = JSON_UNESCAPED_UNICODE
$val $val // MongoMinKey, MongoMaxKey
))))); )))));
} }
$this->_rows[] = $row; $this->_rows[] = $row;
@@ -91,290 +110,14 @@ if (isset($_GET["mongo"])) {
'charsetnr' => $this->_charset[$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) { function get_databases($flush) {
global $connection; global $connection;
$return = array(); $return = array();
$dbs = $connection->_link->listDBs(); foreach ($connection->executeCommand($connection->_db_name, array('listDatabases' => 1)) as $dbs) {
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, $error, $last_id;
/** @var MongoDB\Driver\Manager */
var $_link;
var $_db, $_db_name;
function connect($uri, $options) {
$class = 'MongoDB\Driver\Manager';
return new $class($uri, $options);
}
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("' . strval($val) . '")' :
(is_a($val, 'MongoDB\BSON\UTCDatetime') ? $val->toDateTime()->format('Y-m-d H:i:s') :
(is_a($val, 'MongoDB\BSON\Binary') ? $val->bin : //! allow downloading
(is_a($val, 'MongoDB\BSON\Regex') ? strval($val) :
(is_object($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 = $result->count;
}
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';
$query = new $class($where, array('projection' => $select, 'limit' => $limit, 'skip' => $skip, 'sort' => $sort));
$results = $connection->_link->executeQuery("$connection->_db_name.$table", $query);
return new Min_Result($results);
}
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));
$results = $connection->_link->executeBulkWrite("$db.$table", $bulk);
$connection->affected_rows = $results->getModifiedCount();
return true;
}
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));
$results = $connection->_link->executeBulkWrite("$db.$table", $bulk);
$connection->affected_rows = $results->getDeletedCount();
return true;
}
function insert($table, $set) {
global $connection;
$db = $connection->_db_name;
$class = 'MongoDB\Driver\BulkWrite';
$bulk = new $class(array());
if (isset($set['_id']) && empty($set['_id'])) {
unset($set['_id']);
}
$bulk->insert($set);
$results = $connection->_link->executeBulkWrite("$db.$table", $bulk);
$connection->affected_rows = $results->getInsertedCount();
return true;
}
}
function get_databases($flush) {
/** @var Min_DB */
global $connection;
$return = array();
$class = 'MongoDB\Driver\Command';
$command = new $class(array('listDatabases' => 1));
$results = $connection->_link->executeCommand('admin', $command);
foreach ($results as $dbs) {
foreach ($dbs->databases as $db) { foreach ($dbs->databases as $db) {
$return[] = $db->name; $return[] = $db->name;
} }
@@ -389,11 +132,8 @@ if (isset($_GET["mongo"])) {
function tables_list() { function tables_list() {
global $connection; global $connection;
$class = 'MongoDB\Driver\Command';
$command = new $class(array('listCollections' => 1));
$results = $connection->_link->executeCommand($connection->_db_name, $command);
$collections = array(); $collections = array();
foreach ($results as $result) { foreach ($connection->executeCommand($connection->_db_name, array('listCollections' => 1)) as $result) {
$collections[$result->name] = 'table'; $collections[$result->name] = 'table';
} }
return $collections; return $collections;
@@ -406,10 +146,7 @@ if (isset($_GET["mongo"])) {
function indexes($table, $connection2 = null) { function indexes($table, $connection2 = null) {
global $connection; global $connection;
$return = array(); $return = array();
$class = 'MongoDB\Driver\Command'; foreach ($connection->executeCommand($connection->_db_name, array('listIndexes' => $table)) as $index) {
$command = new $class(array('listIndexes' => $table));
$results = $connection->_link->executeCommand($connection->_db_name, $command);
foreach ($results as $index) {
$descs = array(); $descs = array();
$columns = array(); $columns = array();
foreach (get_object_vars($index->key) as $column => $type) { foreach (get_object_vars($index->key) as $column => $type) {
@@ -427,10 +164,11 @@ if (isset($_GET["mongo"])) {
} }
function fields($table) { function fields($table) {
$fields = fields_from_edit();
if (!count($fields)) {
global $driver; global $driver;
$fields = fields_from_edit();
if (!$fields) {
$result = $driver->select($table, array("*"), null, null, array(), 10); $result = $driver->select($table, array("*"), null, null, array(), 10);
if ($result) {
while ($row = $result->fetch_assoc()) { while ($row = $result->fetch_assoc()) {
foreach ($row as $key => $val) { foreach ($row as $key => $val) {
$row[$key] = null; $row[$key] = null;
@@ -448,22 +186,23 @@ if (isset($_GET["mongo"])) {
} }
} }
} }
}
return $fields; return $fields;
} }
function found_rows($table_status, $where) { function found_rows($table_status, $where) {
global $connection; global $connection;
$where = where_to_query($where); $where = where_to_query($where);
$class = 'MongoDB\Driver\Command'; $toArray = $connection->executeCommand($connection->_db_name, array('count' => $table_status['Name'], 'query' => $where))->toArray();
$command = new $class(array('count' => $table_status['Name'], 'query' => $where));
$results = $connection->_link->executeCommand($connection->_db_name, $command);
$toArray = $results->toArray();
return $toArray[0]->n; return $toArray[0]->n;
} }
function sql_query_where_parser($queryWhere) { function sql_query_where_parser($queryWhere) {
$queryWhere = trim(preg_replace('/WHERE[\s]?[(]?\(?/', '', $queryWhere)); $queryWhere = preg_replace('~^\s*WHERE\s*~', "", $queryWhere);
$queryWhere = preg_replace('/\)\)\)$/', ')', $queryWhere); while ($queryWhere[0] == "(") {
$queryWhere = preg_replace('~^\((.*)\)$~', "$1", $queryWhere);
}
$wheres = explode(' AND ', $queryWhere); $wheres = explode(' AND ', $queryWhere);
$wheresOr = explode(') OR (', $queryWhere); $wheresOr = explode(') OR (', $queryWhere);
$where = array(); $where = array();
@@ -485,10 +224,8 @@ if (isset($_GET["mongo"])) {
if (is_array($where)) { if (is_array($where)) {
foreach ($where as $expression) { foreach ($where as $expression) {
list($col, $op, $val) = explode(" ", $expression, 3); list($col, $op, $val) = explode(" ", $expression, 3);
if ($col == "_id") { if ($col == "_id" && preg_match('~^(MongoDB\\\\BSON\\\\ObjectID)\("(.+)"\)$~', $val, $match)) {
$val = str_replace('MongoDB\BSON\ObjectID("', "", $val); list(, $class, $val) = $match;
$val = str_replace('")', "", $val);
$class = 'MongoDB\BSON\ObjectID';
$val = new $class($val); $val = new $class($val);
} }
if (!in_array($op, $adminer->operators)) { if (!in_array($op, $adminer->operators)) {
@@ -498,9 +235,8 @@ if (isset($_GET["mongo"])) {
$val = (float) $val; $val = (float) $val;
$op = $match[1]; $op = $match[1];
} elseif (preg_match('~^\(date\)(.+)~', $op, $match)) { } elseif (preg_match('~^\(date\)(.+)~', $op, $match)) {
$dateTime = new DateTime($val); $dateTime = new \DateTime($val);
$class = 'MongoDB\BSON\UTCDatetime'; $val = new \MongoDB\BSON\UTCDatetime($dateTime->getTimestamp() * 1000);
$val = new $class($dateTime->getTimestamp() * 1000);
$op = $match[1]; $op = $match[1];
} }
switch ($op) { switch ($op) {
@@ -538,8 +274,17 @@ if (isset($_GET["mongo"])) {
} }
return $data; return $data;
} }
}
$operators = array(
class Driver extends SqlDriver {
static $possibleDrivers = array("mongodb");
static $jush = "mongo";
var $editFunctions = array(array("json"));
var $operators = array(
"=", "=",
"!=", "!=",
">", ">",
@@ -560,7 +305,78 @@ if (isset($_GET["mongo"])) {
"(date)>=", "(date)>=",
"(date)<=", "(date)<=",
); );
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, 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;
try {
return new Result($this->_conn->_link->executeQuery("$connection->_db_name.$table", new \MongoDB\Driver\Query($where, array('projection' => $select, 'limit' => $limit, 'skip' => $skip, 'sort' => $sort))));
} catch (Exception $e) {
$connection->error = $e->getMessage();
return false;
}
}
function update($table, $set, $queryWhere, $limit = 0, $separator = "\n") {
$db = $this->_conn->_db_name;
$where = sql_query_where_parser($queryWhere);
$bulk = new \MongoDB\Driver\BulkWrite(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 $this->_conn->executeBulkWrite("$db.$table", $bulk, 'getModifiedCount');
}
function delete($table, $queryWhere, $limit = 0) {
$db = $this->_conn->_db_name;
$where = sql_query_where_parser($queryWhere);
$bulk = new \MongoDB\Driver\BulkWrite(array());
$bulk->delete($where, array('limit' => $limit));
return $this->_conn->executeBulkWrite("$db.$table", $bulk, 'getDeletedCount');
}
function insert($table, $set) {
$db = $this->_conn->_db_name;
$bulk = new \MongoDB\Driver\BulkWrite(array());
if ($set['_id'] == '') {
unset($set['_id']);
}
$bulk->insert($set);
return $this->_conn->executeBulkWrite("$db.$table", $bulk, 'getInsertedCount');
}
}
function table($idf) { function table($idf) {
return $idf; return $idf;
@@ -605,10 +421,15 @@ if (isset($_GET["mongo"])) {
return $credentials[1]; return $credentials[1];
} }
function connect() { function connect($credentials) {
global $adminer; global $adminer;
$connection = new Min_DB; $connection = new Db;
list($server, $username, $password) = $adminer->credentials(); list($server, $username, $password) = $credentials;
if ($server == "") {
$server = "localhost:27017";
}
$options = array(); $options = array();
if ($username . $password != "") { if ($username . $password != "") {
$options["username"] = $username; $options["username"] = $username;
@@ -621,21 +442,11 @@ if (isset($_GET["mongo"])) {
if (($auth_source = getenv("MONGO_AUTH_SOURCE"))) { if (($auth_source = getenv("MONGO_AUTH_SOURCE"))) {
$options["authSource"] = $auth_source; $options["authSource"] = $auth_source;
} }
try {
$connection->_link = $connection->connect("mongodb://$server", $options);
if ($password != "") {
$options["password"] = "";
try {
$connection->connect("mongodb://$server", $options); $connection->connect("mongodb://$server", $options);
return lang('Database does not support password.'); if ($connection->error) {
} catch (Exception $ex) { return $connection->error;
// this is what we want
}
} }
return $connection; return $connection;
} catch (Exception $ex) {
return $ex->getMessage();
}
} }
function alter_indexes($table, $alter) { function alter_indexes($table, $alter) {
@@ -724,9 +535,4 @@ if (isset($_GET["mongo"])) {
} }
return true; return true;
} }
$jush = "mongo";
$functions = array();
$grouping = array();
$edit_functions = array(array("json"));
} }

View File

@@ -5,13 +5,14 @@
* @author Jakub Vrana * @author Jakub Vrana
*/ */
$drivers["mssql"] = "MS SQL (beta)"; namespace Adminer;
$drivers["mssql"] = "MS SQL";
if (isset($_GET["mssql"])) { if (isset($_GET["mssql"])) {
$possible_drivers = array("SQLSRV", "MSSQL", "PDO_DBLIB"); define('Adminer\DRIVER', "mssql");
define("DRIVER", "mssql");
if (extension_loaded("sqlsrv")) { if (extension_loaded("sqlsrv")) {
class Min_DB { class Db {
var $extension = "sqlsrv", $_link, $_result, $server_info, $affected_rows, $errno, $error; var $extension = "sqlsrv", $_link, $_result, $server_info, $affected_rows, $errno, $error;
function _get_error() { function _get_error() {
@@ -25,8 +26,15 @@ if (isset($_GET["mssql"])) {
function connect($server, $username, $password) { function connect($server, $username, $password) {
global $adminer; global $adminer;
$db = $adminer->database();
$connection_info = array("UID" => $username, "PWD" => $password, "CharacterSet" => "UTF-8"); $connection_info = array("UID" => $username, "PWD" => $password, "CharacterSet" => "UTF-8");
$ssl = $adminer->connectSsl();
if (isset($ssl["Encrypt"])) {
$connection_info["Encrypt"] = $ssl["Encrypt"];
}
if (isset($ssl["TrustServerCertificate"])) {
$connection_info["TrustServerCertificate"] = $ssl["TrustServerCertificate"];
}
$db = $adminer->database();
if ($db != "") { if ($db != "") {
$connection_info["Database"] = $db; $connection_info["Database"] = $db;
} }
@@ -41,11 +49,12 @@ if (isset($_GET["mssql"])) {
} }
function quote($string) { function quote($string) {
return "'" . str_replace("'", "''", $string) . "'"; $unicode = strlen($string) != strlen(utf8_decode($string));
return ($unicode ? "N" : "") . "'" . str_replace("'", "''", $string) . "'";
} }
function select_db($database) { function select_db($database) {
return $this->query("USE " . idf_escape($database)); return $this->query(use_sql($database));
} }
function query($query, $unbuffered = false) { function query($query, $unbuffered = false) {
@@ -76,7 +85,7 @@ if (isset($_GET["mssql"])) {
return false; return false;
} }
if (sqlsrv_field_metadata($result)) { if (sqlsrv_field_metadata($result)) {
return new Min_Result($result); return new Result($result);
} }
$this->affected_rows = sqlsrv_rows_affected($result); $this->affected_rows = sqlsrv_rows_affected($result);
return true; return true;
@@ -96,7 +105,7 @@ if (isset($_GET["mssql"])) {
} }
} }
class Min_Result { class Result {
var $_result, $_offset = 0, $_fields, $num_rows; var $_result, $_offset = 0, $_fields, $num_rows;
function __construct($result) { function __construct($result) {
@@ -127,7 +136,7 @@ if (isset($_GET["mssql"])) {
$this->_fields = sqlsrv_field_metadata($this->_result); $this->_fields = sqlsrv_field_metadata($this->_result);
} }
$field = $this->_fields[$this->_offset++]; $field = $this->_fields[$this->_offset++];
$return = new stdClass; $return = new \stdClass;
$return->name = $field["Name"]; $return->name = $field["Name"];
$return->orgname = $field["Name"]; $return->orgname = $field["Name"];
$return->type = ($field["Type"] == 1 ? 254 : 0); $return->type = ($field["Type"] == 1 ? 254 : 0);
@@ -145,105 +154,23 @@ if (isset($_GET["mssql"])) {
} }
} }
} elseif (extension_loaded("mssql")) { } elseif (extension_loaded("pdo_sqlsrv")) {
class Min_DB { class Db extends PdoDb {
var $extension = "MSSQL", $_link, $_result, $server_info, $affected_rows, $error; var $extension = "PDO_SQLSRV";
function connect($server, $username, $password) { function connect($server, $username, $password) {
$this->_link = @mssql_connect($server, $username, $password); $this->dsn("sqlsrv:Server=" . str_replace(":", ",", $server), $username, $password);
if ($this->_link) { return true;
$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) { function select_db($database) {
return mssql_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 query($query, $unbuffered = false) {
$result = @mssql_query($query, $this->_link); //! $unbuffered
$this->error = "";
if (!$result) {
$this->error = mssql_get_last_message();
return false;
}
if ($result === true) {
$this->affected_rows = mssql_rows_affected($this->_link);
return true;
}
return new Min_Result($result);
}
function multi_query($query) {
return $this->_result = $this->query($query);
}
function store_result() {
return $this->_result;
}
function next_result() {
return mssql_next_result($this->_result->_result);
}
function result($query, $field = 0) {
$result = $this->query($query);
if (!is_object($result)) {
return false;
}
return mssql_result($result->_result, 0, $field);
}
}
class Min_Result {
var $_result, $_offset = 0, $_fields, $num_rows;
function __construct($result) {
$this->_result = $result;
$this->num_rows = mssql_num_rows($result);
}
function fetch_assoc() {
return mssql_fetch_assoc($this->_result);
}
function fetch_row() {
return mssql_fetch_row($this->_result);
}
function num_rows() {
return mssql_num_rows($this->_result);
}
function fetch_field() {
$return = mssql_fetch_field($this->_result);
$return->orgtable = $return->table;
$return->orgname = $return->name;
return $return;
}
function seek($offset) {
mssql_data_seek($this->_result, $offset);
}
function __destruct() {
mssql_free_result($this->_result);
} }
} }
} elseif (extension_loaded("pdo_dblib")) { } elseif (extension_loaded("pdo_dblib")) {
class Min_DB extends Min_PDO { class Db extends PdoDb {
var $extension = "PDO_DBLIB"; var $extension = "PDO_DBLIB";
function connect($server, $username, $password) { function connect($server, $username, $password) {
@@ -252,40 +179,95 @@ if (isset($_GET["mssql"])) {
} }
function select_db($database) { 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));
return $this->query("USE " . idf_escape($database));
} }
} }
} }
class Min_Driver extends Min_SQL { class Driver extends SqlDriver {
static $possibleDrivers = array("SQLSRV", "PDO_SQLSRV", "PDO_DBLIB");
static $jush = "mssql";
var $editFunctions = array(
array(
"date|time" => "getdate",
), array(
"int|decimal|real|float|money|datetime" => "+/-",
"char|text" => "+",
)
);
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL");
var $functions = array("len", "lower", "round", "upper");
var $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
var $onActions = "NO ACTION|CASCADE|SET NULL|SET DEFAULT";
var $generated = array("PERSISTED", "VIRTUAL");
function __construct($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($table, $rows, $primary) { function insertUpdate($table, $rows, $primary) {
foreach ($rows as $set) { $fields = fields($table);
$update = array(); $update = array();
$where = array(); $where = array();
$set = reset($rows);
$columns = "c" . implode(", c", range(1, count($set)));
$c = 0;
$insert = array();
foreach ($set as $key => $val) { foreach ($set as $key => $val) {
$update[] = "$key = $val"; $c++;
if (isset($primary[idf_unescape($key)])) { $name = idf_unescape($key);
$where[] = "$key = $val"; if (!$fields[$name]["auto_increment"]) {
$insert[$key] = "c$c";
}
if (isset($primary[$name])) {
$where[] = "$key = c$c";
} else {
$update[] = "$key = c$c";
} }
} }
//! can use only one query for all rows $values = array();
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 foreach ($rows as $set) {
. " WHEN MATCHED THEN UPDATE SET " . implode(", ", $update) $values[] = "(" . implode(", ", $set) . ")";
. " WHEN NOT MATCHED THEN INSERT (" . implode(", ", array_keys($set)) . ") VALUES (" . implode(", ", $set) . ");" // ; is mandatory
)) {
return false;
} }
if ($where) {
$identity = queries("SET IDENTITY_INSERT " . table($table) . " ON");
$return = queries(
"MERGE " . table($table) . " USING (VALUES\n\t" . implode(",\n\t", $values) . "\n) AS source ($columns) ON " . implode(" AND ", $where) //! source, c1 - possible conflict
. ($update ? "\nWHEN MATCHED THEN UPDATE SET " . implode(", ", $update) : "")
. "\nWHEN NOT MATCHED THEN INSERT (" . implode(", ", array_keys($identity ? $set : $insert)) . ") VALUES (" . ($identity ? $columns : implode(", ", $insert)) . ");" // ; is mandatory
);
if ($identity) {
queries("SET IDENTITY_INSERT " . table($table) . " OFF");
} }
return true; } else {
$return = queries("INSERT INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ") VALUES\n" . implode(",\n", $values));
}
return $return;
} }
function begin() { function begin() {
return queries("BEGIN TRANSACTION"); return queries("BEGIN TRANSACTION");
} }
function tableHelp($name, $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";
}
}
} }
@@ -298,10 +280,11 @@ if (isset($_GET["mssql"])) {
return ($_GET["ns"] != "" ? idf_escape($_GET["ns"]) . "." : "") . idf_escape($idf); return ($_GET["ns"] != "" ? idf_escape($_GET["ns"]) . "." : "") . idf_escape($idf);
} }
function connect() { function connect($credentials) {
global $adminer; $connection = new Db;
$connection = new Min_DB; if ($credentials[0] == "") {
$credentials = $adminer->credentials(); $credentials[0] = "localhost:1433";
}
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) { if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
return $connection; return $connection;
} }
@@ -350,7 +333,11 @@ if (isset($_GET["mssql"])) {
function table_status($name = "") { function table_status($name = "") {
$return = array(); $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 != "") { if ($name != "") {
return $row; return $row;
} }
@@ -368,43 +355,56 @@ if (isset($_GET["mssql"])) {
} }
function fields($table) { function fields($table) {
$comments = get_key_vals("SELECT objname, cast(value as varchar) FROM fn_listextendedproperty('MS_DESCRIPTION', 'schema', " . q(get_schema()) . ", 'table', " . q($table) . ", 'column', NULL)"); global $connection;
$comments = get_key_vals("SELECT objname, cast(value as varchar(max)) FROM fn_listextendedproperty('MS_DESCRIPTION', 'schema', " . q(get_schema()) . ", 'table', " . q($table) . ", 'column', NULL)");
$return = array(); $return = array();
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] $table_id = $connection->result("SELECT object_id FROM sys.all_objects WHERE schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND type IN ('S', 'U', 'V') AND name = " . q($table));
foreach (
get_rows("SELECT c.max_length, c.precision, c.scale, c.name, c.is_nullable, c.is_identity, c.collation_name, t.name type, CAST(d.definition as text) [default], d.name default_constraint, i.is_primary_key
FROM sys.all_columns c FROM sys.all_columns c
JOIN sys.all_objects o ON c.object_id = o.object_id
JOIN sys.types t ON c.user_type_id = t.user_type_id JOIN sys.types t ON c.user_type_id = t.user_type_id
LEFT JOIN sys.default_constraints d ON c.default_object_id = d.parent_column_id LEFT JOIN sys.default_constraints d ON c.default_object_id = d.object_id
WHERE o.schema_id = SCHEMA_ID(" . q(get_schema()) . ") AND o.type IN ('S', 'U', 'V') AND o.name = " . q($table) LEFT JOIN sys.index_columns ic ON c.object_id = ic.object_id AND c.column_id = ic.column_id
) as $row) { 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
) {
$type = $row["type"]; $type = $row["type"];
$length = (preg_match("~char|binary~", $type) ? $row["max_length"] : ($type == "decimal" ? "$row[precision],$row[scale]" : "")); $length = (preg_match("~char|binary~", $type)
? $row["max_length"] / ($type[0] == 'n' ? 2 : 1)
: ($type == "decimal" ? "$row[precision],$row[scale]" : "")
);
$return[$row["name"]] = array( $return[$row["name"]] = array(
"field" => $row["name"], "field" => $row["name"],
"full_type" => $type . ($length ? "($length)" : ""), "full_type" => $type . ($length ? "($length)" : ""),
"type" => $type, "type" => $type,
"length" => $length, "length" => $length,
"default" => $row["default"], "default" => (preg_match("~^\('(.*)'\)$~", $row["default"], $match) ? str_replace("''", "'", $match[1]) : $row["default"]),
"default_constraint" => $row["default_constraint"],
"null" => $row["is_nullable"], "null" => $row["is_nullable"],
"auto_increment" => $row["is_identity"], "auto_increment" => $row["is_identity"],
"collation" => $row["collation_name"], "collation" => $row["collation_name"],
"privileges" => array("insert" => 1, "select" => 1, "update" => 1), "privileges" => array("insert" => 1, "select" => 1, "update" => 1),
"primary" => $row["is_identity"], //! or indexes.is_primary_key "primary" => $row["is_primary_key"],
"comment" => $comments[$row["name"]], "comment" => $comments[$row["name"]],
); );
} }
foreach (get_rows("SELECT * FROM sys.computed_columns WHERE object_id = " . q($table_id)) as $row) {
$return[$row["name"]]["generated"] = ($row["is_persisted"] ? "PERSISTED" : "VIRTUAL");
$return[$row["name"]]["default"] = $row["definition"];
}
return $return; return $return;
} }
function indexes($table, $connection2 = null) { function indexes($table, $connection2 = null) {
$return = array(); $return = array();
// sp_statistics doesn't return information about primary key // sp_statistics doesn't return information about primary key
foreach (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 FROM sys.indexes i
INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
WHERE OBJECT_NAME(i.object_id) = " . q($table) WHERE OBJECT_NAME(i.object_id) = " . q($table), $connection2) as $row
, $connection2) as $row) { ) {
$name = $row["name"]; $name = $row["name"];
$return[$name]["type"] = ($row["is_primary_key"] ? "PRIMARY" : ($row["is_unique"] ? "UNIQUE" : "INDEX")); $return[$name]["type"] = ($row["is_primary_key"] ? "PRIMARY" : ($row["is_unique"] ? "UNIQUE" : "INDEX"));
$return[$name]["lengths"] = array(); $return[$name]["lengths"] = array();
@@ -428,7 +428,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
} }
function information_schema($db) { function information_schema($db) {
return false; return get_schema() == "INFORMATION_SCHEMA";
} }
function error() { function error() {
@@ -441,7 +441,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
} }
function drop_databases($databases) { function drop_databases($databases) {
return queries("DROP DATABASE " . implode(", ", array_map('idf_escape', $databases))); return queries("DROP DATABASE " . implode(", ", array_map('Adminer\idf_escape', $databases)));
} }
function rename_database($name, $collation) { function rename_database($name, $collation) {
@@ -459,6 +459,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) { function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
$alter = array(); $alter = array();
$comments = array(); $comments = array();
$orig_fields = fields($table);
foreach ($fields as $field) { foreach ($fields as $field) {
$column = idf_escape($field[0]); $column = idf_escape($field[0]);
$val = $field[1]; $val = $field[1];
@@ -468,14 +469,28 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
$val[1] = preg_replace("~( COLLATE )'(\\w+)'~", '\1\2', $val[1]); $val[1] = preg_replace("~( COLLATE )'(\\w+)'~", '\1\2', $val[1]);
$comments[$field[0]] = $val[5]; $comments[$field[0]] = $val[5];
unset($val[5]); unset($val[5]);
if (preg_match('~ AS ~', $val[3])) {
unset($val[1], $val[2]);
}
if ($field[0] == "") { if ($field[0] == "") {
$alter["ADD"][] = "\n " . implode("", $val) . ($table == "" ? substr($foreign[$val[0]], 16 + strlen($val[0])) : ""); // 16 - strlen(" FOREIGN KEY ()") $alter["ADD"][] = "\n " . implode("", $val) . ($table == "" ? substr($foreign[$val[0]], 16 + strlen($val[0])) : ""); // 16 - strlen(" FOREIGN KEY ()")
} else { } else {
$default = $val[3];
unset($val[3]); // default values are set separately
unset($val[6]); //! identity can't be removed unset($val[6]); //! identity can't be removed
if ($column != $val[0]) { if ($column != $val[0]) {
queries("EXEC sp_rename " . q(table($table) . ".$column") . ", " . q(idf_unescape($val[0])) . ", 'COLUMN'"); queries("EXEC sp_rename " . q(table($table) . ".$column") . ", " . q(idf_unescape($val[0])) . ", 'COLUMN'");
} }
$alter["ALTER COLUMN " . implode("", $val)][] = ""; $alter["ALTER COLUMN " . implode("", $val)][] = "";
$orig_field = $orig_fields[$field[0]];
if (default_value($orig_field) != $default) {
if ($orig_field["default"] !== null) {
$alter["DROP"][] = " " . idf_escape($orig_field["default_constraint"]);
}
if ($default) {
$alter["ADD"][] = "\n $default FOR $column";
}
}
} }
} }
} }
@@ -489,7 +504,7 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
$alter[""] = $foreign; $alter[""] = $foreign;
} }
foreach ($alter as $key => $val) { foreach ($alter as $key => $val) {
if (!queries("ALTER TABLE " . idf_escape($name) . " $key" . implode(",", $val))) { if (!queries("ALTER TABLE " . table($name) . " $key" . implode(",", $val))) {
return false; return false;
} }
} }
@@ -511,10 +526,12 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
} else { } else {
$index[] = idf_escape($val[1]) . " ON " . table($table); $index[] = idf_escape($val[1]) . " ON " . table($table);
} }
} elseif (!queries(($val[0] != "PRIMARY" } elseif (
!queries(($val[0] != "PRIMARY"
? "CREATE $val[0] " . ($val[0] != "INDEX" ? "INDEX " : "") . idf_escape($val[1] != "" ? $val[1] : uniqid($table . "_")) . " ON " . table($table) ? "CREATE $val[0] " . ($val[0] != "INDEX" ? "INDEX " : "") . idf_escape($val[1] != "" ? $val[1] : uniqid($table . "_")) . " ON " . table($table)
: "ALTER TABLE " . table($table) . " ADD PRIMARY KEY" : "ALTER TABLE " . table($table) . " ADD PRIMARY KEY"
) . " (" . implode(", ", $val[2]) . ")")) { ) . " (" . implode(", ", $val[2]) . ")")
) {
return false; return false;
} }
} }
@@ -540,10 +557,14 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
function foreign_keys($table) { function foreign_keys($table) {
$return = array(); $return = array();
foreach (get_rows("EXEC sp_fkeys @fktable_name = " . q($table)) as $row) { $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) {
$foreign_key = &$return[$row["FK_NAME"]]; $foreign_key = &$return[$row["FK_NAME"]];
$foreign_key["db"] = $row["PKTABLE_QUALIFIER"]; $foreign_key["db"] = $row["PKTABLE_QUALIFIER"];
$foreign_key["ns"] = $row["PKTABLE_OWNER"];
$foreign_key["table"] = $row["PKTABLE_NAME"]; $foreign_key["table"] = $row["PKTABLE_NAME"];
$foreign_key["on_update"] = $on_actions[$row["UPDATE_RULE"]];
$foreign_key["on_delete"] = $on_actions[$row["DELETE_RULE"]];
$foreign_key["source"][] = $row["FKCOLUMN_NAME"]; $foreign_key["source"][] = $row["FKCOLUMN_NAME"];
$foreign_key["target"][] = $row["PKCOLUMN_NAME"]; $foreign_key["target"][] = $row["PKCOLUMN_NAME"];
} }
@@ -555,11 +576,11 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
} }
function drop_views($views) { function drop_views($views) {
return queries("DROP VIEW " . implode(", ", array_map('table', $views))); return queries("DROP VIEW " . implode(", ", array_map('Adminer\table', $views)));
} }
function drop_tables($tables) { function drop_tables($tables) {
return queries("DROP TABLE " . implode(", ", array_map('table', $tables))); return queries("DROP TABLE " . implode(", ", array_map('Adminer\table', $tables)));
} }
function move_tables($tables, $views, $target) { function move_tables($tables, $views, $target) {
@@ -570,7 +591,8 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
if ($name == "") { if ($name == "") {
return array(); 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, 'ExecIsInsertTrigger') = 1 THEN 'INSERT' WHEN OBJECTPROPERTY(s.id, 'ExecIsUpdateTrigger') = 1 THEN 'UPDATE' WHEN OBJECTPROPERTY(s.id, 'ExecIsDeleteTrigger') = 1 THEN 'DELETE' END [Event],
CASE WHEN OBJECTPROPERTY(s.id, 'ExecIsInsteadOfTrigger') = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END [Timing], CASE WHEN OBJECTPROPERTY(s.id, 'ExecIsInsteadOfTrigger') = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END [Timing],
c.text c.text
@@ -587,13 +609,14 @@ WHERE s.xtype = 'TR' AND s.name = " . q($name)
function triggers($table) { function triggers($table) {
$return = array(); $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, 'ExecIsInsertTrigger') = 1 THEN 'INSERT' WHEN OBJECTPROPERTY(sys1.id, 'ExecIsUpdateTrigger') = 1 THEN 'UPDATE' WHEN OBJECTPROPERTY(sys1.id, 'ExecIsDeleteTrigger') = 1 THEN 'DELETE' END [Event],
CASE WHEN OBJECTPROPERTY(sys1.id, 'ExecIsInsteadOfTrigger') = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END [Timing] CASE WHEN OBJECTPROPERTY(sys1.id, 'ExecIsInsteadOfTrigger') = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END [Timing]
FROM sysobjects sys1 FROM sysobjects sys1
JOIN sysobjects sys2 ON sys1.parent_obj = sys2.id JOIN sysobjects sys2 ON sys1.parent_obj = sys2.id
WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table) WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)) as $row
) as $row) { // triggers are not schema-scoped ) { // triggers are not schema-scoped
$return[$row["name"]] = array($row["Timing"], $row["Event"]); $return[$row["name"]] = array($row["Timing"], $row["Event"]);
} }
return $return; return $return;
@@ -620,19 +643,63 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)
} }
function set_schema($schema) { function set_schema($schema) {
$_GET["ns"] = $schema;
return true; // ALTER USER is permanent return true; // ALTER USER is permanent
} }
function create_sql($table, $auto_increment, $style) {
global $driver;
if (is_view(table_status($table))) {
$view = view($table);
return "CREATE VIEW " . table($table) . " AS $view[select]";
}
$fields = array();
$primary = false;
foreach (fields($table) as $name => $field) {
$val = process_field($field, $field);
if ($val[6]) {
$primary = true;
}
$fields[] = implode("", $val);
}
foreach (indexes($table) as $name => $index) {
if (!$primary || $index["type"] != "PRIMARY") {
$columns = array();
foreach ($index["columns"] as $key => $val) {
$columns[] = idf_escape($val) . ($index["descs"][$key] ? " DESC" : "");
}
$name = idf_escape($name);
$fields[] = ($index["type"] == "INDEX" ? "INDEX $name" : "CONSTRAINT $name " . ($index["type"] == "UNIQUE" ? "UNIQUE" : "PRIMARY KEY")) . " (" . implode(", ", $columns) . ")";
}
}
foreach ($driver->checkConstraints($table) as $name => $check) {
$fields[] = "CONSTRAINT " . idf_escape($name) . " CHECK ($check)";
}
return "CREATE TABLE " . table($table) . " (\n\t" . implode(",\n\t", $fields) . "\n)";
}
function foreign_keys_sql($table) {
$fields = array();
foreach (foreign_keys($table) as $foreign) {
$fields[] = ltrim(format_foreign_key($foreign));
}
return ($fields ? "ALTER TABLE " . table($table) . " ADD\n\t" . implode(",\n\t", $fields) . ";\n\n" : "");
}
function truncate_sql($table) {
return "TRUNCATE TABLE " . table($table);
}
function use_sql($database) { function use_sql($database) {
return "USE " . idf_escape($database); return "USE " . idf_escape($database);
} }
function show_variables() { function trigger_sql($table) {
return array(); $return = "";
foreach (triggers($table) as $name => $trigger) {
$return .= create_trigger(" ON " . table($table), trigger($name)) . ";";
} }
return $return;
function show_status() {
return array();
} }
function convert_field($field) { function convert_field($field) {
@@ -643,31 +710,6 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)
} }
function support($feature) { function support($feature) {
return preg_match('~^(comment|columns|database|drop_col|indexes|descidx|scheme|sql|table|trigger|view|view_trigger)$~', $feature); //! routine| return preg_match('~^(check|comment|columns|database|drop_col|dump|indexes|descidx|scheme|sql|table|trigger|view|view_trigger)$~', $feature); //! routine|
} }
$jush = "mssql";
$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);
}
$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" => "+",
)
);
} }

View File

@@ -1,12 +1,13 @@
<?php <?php
namespace Adminer;
$drivers = array("server" => "MySQL") + $drivers; $drivers = array("server" => "MySQL") + $drivers;
if (!defined("DRIVER")) { if (!defined('Adminer\DRIVER')) {
$possible_drivers = array("MySQLi", "MySQL", "PDO_MySQL"); define('Adminer\DRIVER', "server"); // server - backwards compatibility
define("DRIVER", "server"); // server - backwards compatibility
// MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable // MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable
if (extension_loaded("mysqli")) { if (extension_loaded("mysqli")) {
class Min_DB extends MySQLi { class Db extends \MySQLi {
var $extension = "MySQLi"; var $extension = "MySQLi";
function __construct() { function __construct() {
@@ -28,7 +29,7 @@ if (!defined("DRIVER")) {
$database, $database,
(is_numeric($port) ? $port : ini_get("mysqli.default_port")), (is_numeric($port) ? $port : ini_get("mysqli.default_port")),
(!is_numeric($port) ? $port : $socket), (!is_numeric($port) ? $port : $socket),
($ssl ? 64 : 0) // 64 - MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT (not available before PHP 5.6.16) ($ssl ? ($ssl['verify'] !== false ? 2048 : 64) : 0) // 2048 - MYSQLI_CLIENT_SSL, 64 - MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT (not available before PHP 5.6.16)
); );
$this->options(MYSQLI_OPT_LOCAL_INFILE, false); $this->options(MYSQLI_OPT_LOCAL_INFILE, false);
return $return; return $return;
@@ -58,7 +59,7 @@ if (!defined("DRIVER")) {
} }
} elseif (extension_loaded("mysql") && !((ini_bool("sql.safe_mode") || ini_bool("mysql.allow_local_infile")) && extension_loaded("pdo_mysql"))) { } elseif (extension_loaded("mysql") && !((ini_bool("sql.safe_mode") || ini_bool("mysql.allow_local_infile")) && extension_loaded("pdo_mysql"))) {
class Min_DB { class Db {
var var
$extension = "MySQL", ///< @var string extension name $extension = "MySQL", ///< @var string extension name
$server_info, ///< @var string server version $server_info, ///< @var string server version
@@ -128,7 +129,7 @@ if (!defined("DRIVER")) {
/** Send query /** Send query
* @param string * @param string
* @param bool * @param bool
* @return mixed bool or Min_Result * @return mixed bool or Result
*/ */
function query($query, $unbuffered = false) { function query($query, $unbuffered = false) {
$result = @($unbuffered ? mysql_unbuffered_query($query, $this->_link) : mysql_query($query, $this->_link)); // @ - mute mysql.trace_mode $result = @($unbuffered ? mysql_unbuffered_query($query, $this->_link) : mysql_query($query, $this->_link)); // @ - mute mysql.trace_mode
@@ -143,7 +144,7 @@ if (!defined("DRIVER")) {
$this->info = mysql_info($this->_link); $this->info = mysql_info($this->_link);
return true; return true;
} }
return new Min_Result($result); return new Result($result);
} }
/** Send query with more resultsets /** Send query with more resultsets
@@ -155,7 +156,7 @@ if (!defined("DRIVER")) {
} }
/** Get current resultset /** Get current resultset
* @return Min_Result * @return Result
*/ */
function store_result() { function store_result() {
return $this->_result; return $this->_result;
@@ -183,7 +184,7 @@ if (!defined("DRIVER")) {
} }
} }
class Min_Result { class Result {
var var
$num_rows, ///< @var int number of rows in the result $num_rows, ///< @var int number of rows in the result
$_result, $_offset = 0 ///< @access private $_result, $_offset = 0 ///< @access private
@@ -230,22 +231,25 @@ if (!defined("DRIVER")) {
} }
} elseif (extension_loaded("pdo_mysql")) { } elseif (extension_loaded("pdo_mysql")) {
class Min_DB extends Min_PDO { class Db extends PdoDb {
var $extension = "PDO_MySQL"; var $extension = "PDO_MySQL";
function connect($server, $username, $password) { function connect($server, $username, $password) {
global $adminer; global $adminer;
$options = array(PDO::MYSQL_ATTR_LOCAL_INFILE => false); $options = array(\PDO::MYSQL_ATTR_LOCAL_INFILE => false);
$ssl = $adminer->connectSsl(); $ssl = $adminer->connectSsl();
if ($ssl) { if ($ssl) {
if (!empty($ssl['key'])) { if ($ssl['key']) {
$options[PDO::MYSQL_ATTR_SSL_KEY] = $ssl['key']; $options[\PDO::MYSQL_ATTR_SSL_KEY] = $ssl['key'];
} }
if (!empty($ssl['cert'])) { if ($ssl['cert']) {
$options[PDO::MYSQL_ATTR_SSL_CERT] = $ssl['cert']; $options[\PDO::MYSQL_ATTR_SSL_CERT] = $ssl['cert'];
} }
if (!empty($ssl['ca'])) { if ($ssl['ca']) {
$options[PDO::MYSQL_ATTR_SSL_CA] = $ssl['ca']; $options[\PDO::MYSQL_ATTR_SSL_CA] = $ssl['ca'];
}
if (isset($ssl['verify'])) {
$options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = $ssl['verify'];
} }
} }
$this->dsn( $this->dsn(
@@ -267,7 +271,7 @@ if (!defined("DRIVER")) {
} }
function query($query, $unbuffered = false) { function query($query, $unbuffered = false) {
$this->setAttribute(1000, !$unbuffered); // 1000 - PDO::MYSQL_ATTR_USE_BUFFERED_QUERY $this->pdo->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, !$unbuffered);
return parent::query($query, $unbuffered); return parent::query($query, $unbuffered);
} }
} }
@@ -276,7 +280,52 @@ if (!defined("DRIVER")) {
class Min_Driver extends Min_SQL { class Driver extends SqlDriver {
static $possibleDrivers = array("MySQLi", "MySQL", "PDO_MySQL");
static $jush = "sql"; ///< @var string JUSH identifier
var $unsigned = array("unsigned", "zerofill", "unsigned zerofill");
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "FIND_IN_SET", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL");
var $functions = array("char_length", "date", "from_unixtime", "lower", "round", "floor", "ceil", "sec_to_time", "time_to_sec", "upper");
var $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
function __construct($connection) {
parent::__construct($connection);
$this->types = array(
lang('Numbers') => array("tinyint" => 3, "smallint" => 5, "mediumint" => 8, "int" => 10, "bigint" => 20, "decimal" => 66, "float" => 12, "double" => 21),
lang('Date and time') => array("date" => 10, "datetime" => 19, "timestamp" => 19, "time" => 10, "year" => 4),
lang('Strings') => array("char" => 255, "varchar" => 65535, "tinytext" => 255, "text" => 65535, "mediumtext" => 16777215, "longtext" => 4294967295),
lang('Lists') => array("enum" => 65535, "set" => 64),
lang('Binary') => array("bit" => 20, "binary" => 255, "varbinary" => 65535, "tinyblob" => 255, "blob" => 65535, "mediumblob" => 16777215, "longblob" => 4294967295),
lang('Geometry') => array("geometry" => 0, "point" => 0, "linestring" => 0, "polygon" => 0, "multipoint" => 0, "multilinestring" => 0, "multipolygon" => 0, "geometrycollection" => 0),
);
$this->editFunctions = array(
array(
"char" => "md5/sha1/password/encrypt/uuid",
"binary" => "md5/sha1",
"date|time" => "now",
), array(
number_type() => "+/-",
"date" => "+ interval/- interval",
"time" => "addtime/subtime",
"char|text" => "concat",
)
);
if (min_version('5.7.8', 10.2, $connection)) {
$this->types[lang('Strings')]["json"] = 4294967295;
}
if (min_version('', 10.7, $connection)) {
$this->types[lang('Strings')]["uuid"] = 128;
$this->editFunctions[0]['uuid'] = 'uuid';
}
if (min_version(9, '', $connection)) {
$this->types[lang('Numbers')]["vector"] = 16383;
$this->editFunctions[0]['vector'] = 'string_to_vector';
}
if (min_version(5.7, 10.2, $connection)) {
$this->generated = array("STORED", "VIRTUAL");
}
}
function insert($table, $set) { function insert($table, $set) {
return ($set ? parent::insert($table, $set) : queries("INSERT INTO " . table($table) . " ()\nVALUES ()")); return ($set ? parent::insert($table, $set) : queries("INSERT INTO " . table($table) . " ()\nVALUES ()"));
@@ -333,16 +382,24 @@ if (!defined("DRIVER")) {
} }
} }
function tableHelp($name) { function tableHelp($name, $is_view = false) {
$maria = preg_match('~MariaDB~', $this->_conn->server_info); $maria = preg_match('~MariaDB~', $this->_conn->server_info);
if (information_schema(DB)) { if (information_schema(DB)) {
return strtolower(($maria ? "information-schema-$name-table/" : str_replace("_", "-", $name) . "-table.html")); return strtolower("information-schema-" . ($maria ? "$name-table/" : str_replace("_", "-", $name) . "-table.html"));
} }
if (DB == "mysql") { if (DB == "mysql") {
return ($maria ? "mysql$name-table/" : "system-database.html"); //! more precise link return ($maria ? "mysql$name-table/" : "system-schema.html"); //! more precise link
} }
} }
function hasCStyleEscapes() {
static $c_style;
if ($c_style === null) {
$sql_mode = $this->_conn->result("SHOW VARIABLES LIKE 'sql_mode'", 1);
$c_style = (strpos($sql_mode, 'NO_BACKSLASH_ESCAPES') === false);
}
return $c_style;
}
} }
@@ -364,19 +421,14 @@ if (!defined("DRIVER")) {
} }
/** Connect to the database /** Connect to the database
* @return mixed Min_DB or string for error * @param array [$server, $username, $password]
* @return mixed Db or string for error
*/ */
function connect() { function connect($credentials) {
global $adminer, $types, $structured_types; $connection = new Db;
$connection = new Min_DB;
$credentials = $adminer->credentials();
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) { if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
$connection->set_charset(charset($connection)); // available in MySQLi since PHP 5.0.5 $connection->set_charset(charset($connection)); // available in MySQLi since PHP 5.0.5
$connection->query("SET sql_quote_show_create = 1, autocommit = 1"); $connection->query("SET sql_quote_show_create = 1, autocommit = 1");
if (min_version('5.7.8', 10.2, $connection)) {
$structured_types[lang('Strings')][] = "json";
$types["json"] = 4294967295;
}
return $connection; return $connection;
} }
$return = $connection->error; $return = $connection->error;
@@ -394,10 +446,7 @@ if (!defined("DRIVER")) {
// SHOW DATABASES can take a very long time so it is cached // SHOW DATABASES can take a very long time so it is cached
$return = get_session("dbs"); $return = get_session("dbs");
if ($return === null) { if ($return === null) {
$query = (min_version(5) $query = "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA ORDER BY SCHEMA_NAME"; // SHOW DATABASES can be disabled by skip_show_database
? "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA ORDER BY SCHEMA_NAME"
: "SHOW DATABASES"
); // SHOW DATABASES can be disabled by skip_show_database
$return = ($flush ? slow_query($query) : get_vals($query)); $return = ($flush ? slow_query($query) : get_vals($query));
restart_session(); restart_session();
set_session("dbs", $return); set_session("dbs", $return);
@@ -469,18 +518,15 @@ if (!defined("DRIVER")) {
} }
/** Get tables list /** Get tables list
* @return array array($name => $type) * @return array [$name => $type]
*/ */
function tables_list() { function tables_list() {
return get_key_vals(min_version(5) return get_key_vals("SELECT TABLE_NAME, TABLE_TYPE FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() ORDER BY TABLE_NAME");
? "SELECT TABLE_NAME, TABLE_TYPE FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() ORDER BY TABLE_NAME"
: "SHOW TABLES"
);
} }
/** Count tables in all databases /** Count tables in all databases
* @param array * @param array
* @return array array($db => $tables) * @return array [$db => $tables]
*/ */
function count_tables($databases) { function count_tables($databases) {
$return = array(); $return = array();
@@ -493,14 +539,17 @@ if (!defined("DRIVER")) {
/** Get table status /** Get table status
* @param string * @param string
* @param bool return only "Name", "Engine" and "Comment" fields * @param bool return only "Name", "Engine" and "Comment" fields
* @return array array($name => array("Name" => , "Engine" => , "Comment" => , "Oid" => , "Rows" => , "Collation" => , "Auto_increment" => , "Data_length" => , "Index_length" => , "Data_free" => )) or only inner array with $name * @return array [$name => ["Name" => , "Engine" => , "Comment" => , "Oid" => , "Rows" => , "Collation" => , "Auto_increment" => , "Data_length" => , "Index_length" => , "Data_free" => ]] or only inner array with $name
*/ */
function table_status($name = "", $fast = false) { function table_status($name = "", $fast = false) {
$return = array(); $return = array();
foreach (get_rows($fast && min_version(5) foreach (
get_rows(
$fast
? "SELECT TABLE_NAME AS Name, ENGINE AS Engine, TABLE_COMMENT AS Comment FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() " . ($name != "" ? "AND TABLE_NAME = " . q($name) : "ORDER BY Name") ? "SELECT TABLE_NAME AS Name, ENGINE AS Engine, TABLE_COMMENT AS Comment FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() " . ($name != "" ? "AND TABLE_NAME = " . q($name) : "ORDER BY Name")
: "SHOW TABLE STATUS" . ($name != "" ? " LIKE " . q(addcslashes($name, "%_\\")) : "") : "SHOW TABLE STATUS" . ($name != "" ? " LIKE " . q(addcslashes($name, "%_\\")) : "")
) as $row) { ) as $row
) {
if ($row["Engine"] == "InnoDB") { if ($row["Engine"] == "InnoDB") {
// ignore internal comment, unnecessary since MySQL 5.1.21 // ignore internal comment, unnecessary since MySQL 5.1.21
$row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\1', $row["Comment"]); $row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\1', $row["Comment"]);
@@ -509,6 +558,8 @@ if (!defined("DRIVER")) {
$row["Comment"] = ""; $row["Comment"] = "";
} }
if ($name != "") { if ($name != "") {
// MariaDB: Table name is returned as lowercase on macOS, so we fix it here.
$row["Name"] = $name;
return $row; return $row;
} }
$return[$row["Name"]] = $row; $return[$row["Name"]] = $row;
@@ -535,28 +586,39 @@ if (!defined("DRIVER")) {
/** Get information about fields /** Get information about fields
* @param string * @param string
* @return array array($name => array("field" => , "full_type" => , "type" => , "length" => , "unsigned" => , "default" => , "null" => , "auto_increment" => , "on_update" => , "collation" => , "privileges" => , "comment" => , "primary" => )) * @return array [$name => ["field" => , "full_type" => , "type" => , "length" => , "unsigned" => , "default" => , "null" => , "auto_increment" => , "on_update" => , "collation" => , "privileges" => , "comment" => , "primary" => , "generated" => ]]
*/ */
function fields($table) { function fields($table) {
$return = array(); $return = array();
foreach (get_rows("SHOW FULL COLUMNS FROM " . table($table)) as $row) { foreach (get_rows("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = " . q($table) . " ORDER BY ORDINAL_POSITION") as $row) {
preg_match('~^([^( ]+)(?:\((.+)\))?( unsigned)?( zerofill)?$~', $row["Type"], $match); $field = $row["COLUMN_NAME"];
$return[$row["Field"]] = array( $default = $row["COLUMN_DEFAULT"];
"field" => $row["Field"], $type = $row["COLUMN_TYPE"];
"full_type" => $row["Type"], $extra = $row["EXTRA"];
// https://mariadb.com/kb/en/library/show-columns/, https://github.com/vrana/adminer/pull/359#pullrequestreview-276677186
preg_match('~^(VIRTUAL|PERSISTENT|STORED)~', $extra, $generated);
preg_match('~^([^( ]+)(?:\((.+)\))?( unsigned)?( zerofill)?$~', $type, $match);
$return[$field] = array(
"field" => $field,
"full_type" => $type,
"type" => $match[1], "type" => $match[1],
"length" => $match[2], "length" => $match[2],
"unsigned" => ltrim($match[3] . $match[4]), "unsigned" => ltrim($match[3] . $match[4]),
"default" => ($row["Default"] != "" || preg_match("~char|set~", $match[1]) ? $row["Default"] : null), "default" => ($generated
"null" => ($row["Null"] == "YES"), ? $row["GENERATION_EXPRESSION"]
"auto_increment" => ($row["Extra"] == "auto_increment"), : ($default != "" || preg_match("~char|set~", $match[1])
"on_update" => (preg_match('~^on update (.+)~i', $row["Extra"], $match) ? $match[1] : ""), //! available since MySQL 5.1.23 ? (preg_match('~text~', $match[1]) ? stripslashes(preg_replace("~^'(.*)'\$~", '\1', $default)) : $default)
"collation" => $row["Collation"], : null
"privileges" => array_flip(preg_split('~, *~', $row["Privileges"])), )
"comment" => $row["Comment"], ),
"primary" => ($row["Key"] == "PRI"), "null" => ($row["IS_NULLABLE"] == "YES"),
// https://mariadb.com/kb/en/library/show-columns/, https://github.com/vrana/adminer/pull/359#pullrequestreview-276677186 "auto_increment" => ($extra == "auto_increment"),
"generated" => preg_match('~^(VIRTUAL|PERSISTENT|STORED)~', $row["Extra"]), "on_update" => (preg_match('~\bon update (\w+)~i', $extra, $match) ? $match[1] : ""), //! available since MySQL 5.1.23
"collation" => $row["COLLATION_NAME"],
"privileges" => array_flip(explode(",", $row["PRIVILEGES"])),
"comment" => $row["COLUMN_COMMENT"],
"primary" => ($row["COLUMN_KEY"] == "PRI"),
"generated" => ($generated[1] == "PERSISTENT" ? "STORED" : $generated[1]),
); );
} }
return $return; return $return;
@@ -564,8 +626,8 @@ if (!defined("DRIVER")) {
/** Get table indexes /** Get table indexes
* @param string * @param string
* @param string Min_DB to use * @param string Db to use
* @return array array($key_name => array("type" => , "columns" => array(), "lengths" => array(), "descs" => array())) * @return array [$key_name => ["type" => , "columns" => [], "lengths" => [], "descs" => []]]
*/ */
function indexes($table, $connection2 = null) { function indexes($table, $connection2 = null) {
$return = array(); $return = array();
@@ -581,25 +643,25 @@ if (!defined("DRIVER")) {
/** Get foreign keys in table /** Get foreign keys in table
* @param string * @param string
* @return array array($name => array("db" => , "ns" => , "table" => , "source" => array(), "target" => array(), "on_delete" => , "on_update" => )) * @return array [$name => ["db" => , "ns" => , "table" => , "source" => [], "target" => [], "on_delete" => , "on_update" => ]]
*/ */
function foreign_keys($table) { function foreign_keys($table) {
global $connection, $on_actions; global $connection, $driver;
static $pattern = '(?:`(?:[^`]|``)+`|"(?:[^"]|"")+")'; static $pattern = '(?:`(?:[^`]|``)+`|"(?:[^"]|"")+")';
$return = array(); $return = array();
$create_table = $connection->result("SHOW CREATE TABLE " . table($table), 1); $create_table = $connection->result("SHOW CREATE TABLE " . table($table), 1);
if ($create_table) { if ($create_table) {
preg_match_all("~CONSTRAINT ($pattern) FOREIGN KEY ?\\(((?:$pattern,? ?)+)\\) REFERENCES ($pattern)(?:\\.($pattern))? \\(((?:$pattern,? ?)+)\\)(?: ON DELETE ($on_actions))?(?: ON UPDATE ($on_actions))?~", $create_table, $matches, PREG_SET_ORDER); preg_match_all("~CONSTRAINT ($pattern) FOREIGN KEY ?\\(((?:$pattern,? ?)+)\\) REFERENCES ($pattern)(?:\\.($pattern))? \\(((?:$pattern,? ?)+)\\)(?: ON DELETE ($driver->onActions))?(?: ON UPDATE ($driver->onActions))?~", $create_table, $matches, PREG_SET_ORDER);
foreach ($matches as $match) { foreach ($matches as $match) {
preg_match_all("~$pattern~", $match[2], $source); preg_match_all("~$pattern~", $match[2], $source);
preg_match_all("~$pattern~", $match[5], $target); preg_match_all("~$pattern~", $match[5], $target);
$return[idf_unescape($match[1])] = array( $return[idf_unescape($match[1])] = array(
"db" => idf_unescape($match[4] != "" ? $match[3] : $match[4]), "db" => idf_unescape($match[4] != "" ? $match[3] : $match[4]),
"table" => idf_unescape($match[4] != "" ? $match[4] : $match[3]), "table" => idf_unescape($match[4] != "" ? $match[4] : $match[3]),
"source" => array_map('idf_unescape', $source[0]), "source" => array_map('Adminer\idf_unescape', $source[0]),
"target" => array_map('idf_unescape', $target[0]), "target" => array_map('Adminer\idf_unescape', $target[0]),
"on_delete" => ($match[6] ? $match[6] : "RESTRICT"), "on_delete" => ($match[6] ?: "RESTRICT"),
"on_update" => ($match[7] ? $match[7] : "RESTRICT"), "on_update" => ($match[7] ?: "RESTRICT"),
); );
} }
} }
@@ -608,7 +670,7 @@ if (!defined("DRIVER")) {
/** Get view SELECT /** Get view SELECT
* @param string * @param string
* @return array array("select" => ) * @return array ["select" => ]
*/ */
function view($name) { function view($name) {
global $connection; global $connection;
@@ -639,7 +701,7 @@ if (!defined("DRIVER")) {
* @return bool * @return bool
*/ */
function information_schema($db) { function information_schema($db) {
return (min_version(5) && $db == "information_schema") return ($db == "information_schema")
|| (min_version(5.5) && $db == "performance_schema"); || (min_version(5.5) && $db == "performance_schema");
} }
@@ -665,7 +727,7 @@ if (!defined("DRIVER")) {
* @return bool * @return bool
*/ */
function drop_databases($databases) { function drop_databases($databases) {
$return = apply_queries("DROP DATABASE", $databases, 'idf_escape'); $return = apply_queries("DROP DATABASE", $databases, 'Adminer\idf_escape');
restart_session(); restart_session();
set_session("dbs", null); set_session("dbs", null);
return $return; return $return;
@@ -679,17 +741,17 @@ if (!defined("DRIVER")) {
function rename_database($name, $collation) { function rename_database($name, $collation) {
$return = false; $return = false;
if (create_database($name, $collation)) { if (create_database($name, $collation)) {
//! move triggers $tables = array();
$rename = array(); $views = array();
foreach (tables_list() as $table => $type) { foreach (tables_list() as $table => $type) {
$rename[] = table($table) . " TO " . idf_escape($name) . "." . table($table); if ($type == 'VIEW') {
$views[] = $table;
} else {
$tables[] = $table;
} }
$return = (!$rename || queries("RENAME TABLE " . implode(", ", $rename)));
if ($return) {
queries("DROP DATABASE " . idf_escape(DB));
} }
restart_session(); $return = (!$tables && !$views) || move_tables($tables, $views, $name);
set_session("dbs", null); drop_databases($return ? array(DB) : array());
} }
return $return; return $return;
} }
@@ -717,7 +779,7 @@ if (!defined("DRIVER")) {
/** Run commands to create or alter table /** Run commands to create or alter table
* @param string "" to create * @param string "" to create
* @param string new name * @param string new name
* @param array of array($orig, $process_field, $after) * @param array of [$orig, $process_field, $after]
* @param array of strings * @param array of strings
* @param string * @param string
* @param string * @param string
@@ -729,10 +791,16 @@ if (!defined("DRIVER")) {
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) { function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
$alter = array(); $alter = array();
foreach ($fields as $field) { foreach ($fields as $field) {
$alter[] = ($field[1] if ($field[1]) {
? ($table != "" ? ($field[0] != "" ? "CHANGE " . idf_escape($field[0]) : "ADD") : " ") . " " . implode($field[1]) . ($table != "" ? $field[2] : "") $default = $field[1][3];
: "DROP " . idf_escape($field[0]) if (preg_match('~ GENERATED~', $default)) {
); $field[1][3] = $field[1][2];
$field[1][2] = $default;
}
$alter[] = ($table != "" ? ($field[0] != "" ? "CHANGE " . idf_escape($field[0]) : "ADD") : " ") . " " . implode($field[1]) . ($table != "" ? $field[2] : "");
} else {
$alter[] = "DROP " . idf_escape($field[0]);
}
} }
$alter = array_merge($alter, $foreign); $alter = array_merge($alter, $foreign);
$status = ($comment !== null ? " COMMENT=" . q($comment) : "") $status = ($comment !== null ? " COMMENT=" . q($comment) : "")
@@ -754,7 +822,7 @@ if (!defined("DRIVER")) {
/** Run commands to alter indexes /** Run commands to alter indexes
* @param string escaped table name * @param string escaped table name
* @param array of array("index type", "name", array("column definition", ...)) or array("index type", "name", "DROP") * @param array of ["index type", "name", ["column definition", ...]] or ["index type", "name", "DROP"]
* @return bool * @return bool
*/ */
function alter_indexes($table, $alter) { function alter_indexes($table, $alter) {
@@ -780,7 +848,7 @@ if (!defined("DRIVER")) {
* @return bool * @return bool
*/ */
function drop_views($views) { function drop_views($views) {
return queries("DROP VIEW " . implode(", ", array_map('table', $views))); return queries("DROP VIEW " . implode(", ", array_map('Adminer\table', $views)));
} }
/** Drop tables /** Drop tables
@@ -788,7 +856,7 @@ if (!defined("DRIVER")) {
* @return bool * @return bool
*/ */
function drop_tables($tables) { function drop_tables($tables) {
return queries("DROP TABLE " . implode(", ", array_map('table', $tables))); return queries("DROP TABLE " . implode(", ", array_map('Adminer\table', $tables)));
} }
/** Move tables to other schema /** Move tables to other schema
@@ -798,12 +866,27 @@ if (!defined("DRIVER")) {
* @return bool * @return bool
*/ */
function move_tables($tables, $views, $target) { function move_tables($tables, $views, $target) {
global $connection;
$rename = array(); $rename = array();
foreach (array_merge($tables, $views) as $table) { // views will report SQL error foreach ($tables as $table) {
$rename[] = table($table) . " TO " . idf_escape($target) . "." . table($table); $rename[] = table($table) . " TO " . idf_escape($target) . "." . table($table);
} }
return queries("RENAME TABLE " . implode(", ", $rename)); if (!$rename || queries("RENAME TABLE " . implode(", ", $rename))) {
$definitions = array();
foreach ($views as $table) {
$definitions[table($table)] = view($table);
}
$connection->select_db($target);
$db = idf_escape(DB);
foreach ($definitions as $name => $view) {
if (!queries("CREATE VIEW $name AS " . str_replace(" $db.", " ", $view["select"])) || !queries("DROP VIEW $db.$name")) {
return false;
}
}
return true;
}
//! move triggers //! move triggers
return false;
} }
/** Copy tables to other schema /** Copy tables to other schema
@@ -816,7 +899,8 @@ if (!defined("DRIVER")) {
queries("SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'"); queries("SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'");
foreach ($tables as $table) { foreach ($tables as $table) {
$name = ($target == DB ? table("copy_$table") : idf_escape($target) . "." . table($table)); $name = ($target == DB ? table("copy_$table") : idf_escape($target) . "." . table($table));
if (($_POST["overwrite"] && !queries("\nDROP TABLE IF EXISTS $name")) if (
($_POST["overwrite"] && !queries("\nDROP TABLE IF EXISTS $name"))
|| !queries("CREATE TABLE $name LIKE " . table($table)) || !queries("CREATE TABLE $name LIKE " . table($table))
|| !queries("INSERT INTO $name SELECT * FROM " . table($table)) || !queries("INSERT INTO $name SELECT * FROM " . table($table))
) { ) {
@@ -832,8 +916,10 @@ if (!defined("DRIVER")) {
foreach ($views as $table) { foreach ($views as $table) {
$name = ($target == DB ? table("copy_$table") : idf_escape($target) . "." . table($table)); $name = ($target == DB ? table("copy_$table") : idf_escape($target) . "." . table($table));
$view = view($table); $view = view($table);
if (($_POST["overwrite"] && !queries("DROP VIEW IF EXISTS $name")) if (
|| !queries("CREATE VIEW $name AS $view[select]")) { //! USE to avoid db.table ($_POST["overwrite"] && !queries("DROP VIEW IF EXISTS $name"))
|| !queries("CREATE VIEW $name AS $view[select]") //! USE to avoid db.table
) {
return false; return false;
} }
} }
@@ -842,7 +928,7 @@ if (!defined("DRIVER")) {
/** Get information about trigger /** Get information about trigger
* @param string trigger name * @param string trigger name
* @return array array("Trigger" => , "Timing" => , "Event" => , "Of" => , "Type" => , "Statement" => ) * @return array ["Trigger" => , "Timing" => , "Event" => , "Of" => , "Type" => , "Statement" => ]
*/ */
function trigger($name) { function trigger($name) {
if ($name == "") { if ($name == "") {
@@ -854,7 +940,7 @@ if (!defined("DRIVER")) {
/** Get defined triggers /** Get defined triggers
* @param string * @param string
* @return array array($name => array($timing, $event)) * @return array [$name => [$timing, $event]]
*/ */
function triggers($table) { function triggers($table) {
$return = array(); $return = array();
@@ -865,7 +951,7 @@ if (!defined("DRIVER")) {
} }
/** Get trigger options /** Get trigger options
* @return array ("Timing" => array(), "Event" => array(), "Type" => array()) * @return array ["Timing" => [], "Event" => [], "Type" => []]
*/ */
function trigger_options() { function trigger_options() {
return array( return array(
@@ -878,24 +964,23 @@ if (!defined("DRIVER")) {
/** Get information about stored routine /** Get information about stored routine
* @param string * @param string
* @param string "FUNCTION" or "PROCEDURE" * @param string "FUNCTION" or "PROCEDURE"
* @return array ("fields" => array("field" => , "type" => , "length" => , "unsigned" => , "inout" => , "collation" => ), "returns" => , "definition" => , "language" => ) * @return array ["fields" => ["field" => , "type" => , "length" => , "unsigned" => , "inout" => , "collation" => ], "returns" => , "definition" => , "language" => ]
*/ */
function routine($name, $type) { function routine($name, $type) {
global $connection, $enum_length, $inout, $types; global $connection, $driver;
$aliases = array("bool", "boolean", "integer", "double precision", "real", "dec", "numeric", "fixed", "national char", "national varchar"); $aliases = array("bool", "boolean", "integer", "double precision", "real", "dec", "numeric", "fixed", "national char", "national varchar");
$space = "(?:\\s|/\\*[\s\S]*?\\*/|(?:#|-- )[^\n]*\n?|--\r?\n)"; $space = "(?:\\s|/\\*[\s\S]*?\\*/|(?:#|-- )[^\n]*\n?|--\r?\n)";
$type_pattern = "((" . implode("|", array_merge(array_keys($types), $aliases)) . ")\\b(?:\\s*\\(((?:[^'\")]|$enum_length)++)\\))?\\s*(zerofill\\s*)?(unsigned(?:\\s+zerofill)?)?)(?:\\s*(?:CHARSET|CHARACTER\\s+SET)\\s*['\"]?([^'\"\\s,]+)['\"]?)?"; $type_pattern = "((" . implode("|", array_merge(array_keys($driver->types()), $aliases)) . ")\\b(?:\\s*\\(((?:[^'\")]|$driver->enumLength)++)\\))?\\s*(zerofill\\s*)?(unsigned(?:\\s+zerofill)?)?)(?:\\s*(?:CHARSET|CHARACTER\\s+SET)\\s*['\"]?([^'\"\\s,]+)['\"]?)?";
$pattern = "$space*(" . ($type == "FUNCTION" ? "" : $inout) . ")?\\s*(?:`((?:[^`]|``)*)`\\s*|\\b(\\S+)\\s+)$type_pattern"; $pattern = "$space*(" . ($type == "FUNCTION" ? "" : $driver->inout) . ")?\\s*(?:`((?:[^`]|``)*)`\\s*|\\b(\\S+)\\s+)$type_pattern";
$create = $connection->result("SHOW CREATE $type " . idf_escape($name), 2); $create = $connection->result("SHOW CREATE $type " . idf_escape($name), 2);
preg_match("~\\(((?:$pattern\\s*,?)*)\\)\\s*" . ($type == "FUNCTION" ? "RETURNS\\s+$type_pattern\\s+" : "") . "(.*)~is", $create, $match); preg_match("~\\(((?:$pattern\\s*,?)*)\\)\\s*" . ($type == "FUNCTION" ? "RETURNS\\s+$type_pattern\\s+" : "") . "(.*)~is", $create, $match);
$fields = array(); $fields = array();
preg_match_all("~$pattern\\s*,?~is", $match[1], $matches, PREG_SET_ORDER); preg_match_all("~$pattern\\s*,?~is", $match[1], $matches, PREG_SET_ORDER);
foreach ($matches as $param) { foreach ($matches as $param) {
$name = str_replace("``", "`", $param[2]) . $param[3];
$fields[] = array( $fields[] = array(
"field" => $name, "field" => str_replace("``", "`", $param[2]) . $param[3],
"type" => strtolower($param[5]), "type" => strtolower($param[5]),
"length" => preg_replace_callback("~$enum_length~s", 'normalize_enum', $param[6]), "length" => preg_replace_callback("~$driver->enumLength~s", 'Adminer\normalize_enum', $param[6]),
"unsigned" => strtolower(preg_replace('~\s+~', ' ', trim("$param[8] $param[7]"))), "unsigned" => strtolower(preg_replace('~\s+~', ' ', trim("$param[8] $param[7]"))),
"null" => 1, "null" => 1,
"full_type" => $param[4], "full_type" => $param[4],
@@ -903,22 +988,21 @@ if (!defined("DRIVER")) {
"collation" => strtolower($param[9]), "collation" => strtolower($param[9]),
); );
} }
if ($type != "FUNCTION") {
return array("fields" => $fields, "definition" => $match[11]);
}
return array( return array(
"fields" => $fields, "fields" => $fields,
"comment" => $connection->result("SELECT ROUTINE_COMMENT FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = DATABASE() AND ROUTINE_NAME = " . q($name)),
) + ($type != "FUNCTION" ? array("definition" => $match[11]) : array(
"returns" => array("type" => $match[12], "length" => $match[13], "unsigned" => $match[15], "collation" => $match[16]), "returns" => array("type" => $match[12], "length" => $match[13], "unsigned" => $match[15], "collation" => $match[16]),
"definition" => $match[17], "definition" => $match[17],
"language" => "SQL", // available in information_schema.ROUTINES.PARAMETER_STYLE "language" => "SQL", // available in information_schema.ROUTINES.BODY_STYLE
); ));
} }
/** Get list of routines /** Get list of routines
* @return array ("SPECIFIC_NAME" => , "ROUTINE_NAME" => , "ROUTINE_TYPE" => , "DTD_IDENTIFIER" => ) * @return array ["SPECIFIC_NAME" => , "ROUTINE_NAME" => , "ROUTINE_TYPE" => , "DTD_IDENTIFIER" => ]
*/ */
function routines() { function routines() {
return get_rows("SELECT ROUTINE_NAME AS SPECIFIC_NAME, ROUTINE_NAME, ROUTINE_TYPE, DTD_IDENTIFIER FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = " . q(DB)); return get_rows("SELECT ROUTINE_NAME AS SPECIFIC_NAME, ROUTINE_NAME, ROUTINE_TYPE, DTD_IDENTIFIER FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = DATABASE()");
} }
/** Get list of available routine languages /** Get list of available routine languages
@@ -946,12 +1030,12 @@ if (!defined("DRIVER")) {
} }
/** Explain select /** Explain select
* @param Min_DB * @param Db
* @param string * @param string
* @return Min_Result * @return Result
*/ */
function explain($connection, $query) { function explain($connection, $query) {
return $connection->query("EXPLAIN " . (min_version(5.1) ? "PARTITIONS " : "") . $query); return $connection->query("EXPLAIN " . (min_version(5.1) && !min_version(5.7) ? "PARTITIONS " : "") . $query);
} }
/** Get approximate number of rows /** Get approximate number of rows
@@ -963,34 +1047,40 @@ if (!defined("DRIVER")) {
return ($where || $table_status["Engine"] != "InnoDB" ? null : $table_status["Rows"]); return ($where || $table_status["Engine"] != "InnoDB" ? null : $table_status["Rows"]);
} }
/* Not used is MySQL but checked in compile.php:
/** Get user defined types /** Get user defined types
* @return array * @return array [$id => $name]
*/
function types() { function types() {
return array(); return array();
} }
/** Get values of user defined type
* @param int
* @return string
function type_values($id) {
return "";
}
/** Get existing schemas /** Get existing schemas
* @return array * @return array
*/
function schemas() { function schemas() {
return array(); return array();
} }
/** Get current schema /** Get current schema
* @return string * @return string
*/
function get_schema() { function get_schema() {
return ""; return "";
} }
/** Set current schema /** Set current schema
* @param string * @param string
* @param Db
* @return bool * @return bool
*/ function set_schema($schema, $connection2 = null) {
function set_schema($schema) {
return true; return true;
} }
*/
/** Get SQL command to create table /** Get SQL command to create table
* @param string * @param string
@@ -1036,21 +1126,21 @@ if (!defined("DRIVER")) {
} }
/** Get server variables /** Get server variables
* @return array ($name => $value) * @return array [$name => $value]
*/ */
function show_variables() { function show_variables() {
return get_key_vals("SHOW VARIABLES"); return get_key_vals("SHOW VARIABLES");
} }
/** Get process list /** Get process list
* @return array ($row) * @return array [$row]
*/ */
function process_list() { function process_list() {
return get_rows("SHOW FULL PROCESSLIST"); return get_rows("SHOW FULL PROCESSLIST");
} }
/** Get status variables /** Get status variables
* @return array ($name => $value) * @return array [$name => $value]
*/ */
function show_status() { function show_status() {
return get_key_vals("SHOW STATUS"); return get_key_vals("SHOW STATUS");
@@ -1082,63 +1172,43 @@ if (!defined("DRIVER")) {
$return = "UNHEX($return)"; $return = "UNHEX($return)";
} }
if ($field["type"] == "bit") { if ($field["type"] == "bit") {
$return = "CONV($return, 2, 10) + 0"; $return = "CONVERT(b$return, UNSIGNED)";
} }
if (preg_match("~geometry|point|linestring|polygon~", $field["type"])) { if (preg_match("~geometry|point|linestring|polygon~", $field["type"])) {
$return = (min_version(8) ? "ST_" : "") . "GeomFromText($return, SRID($field[field]))"; $prefix = (min_version(8) ? "ST_" : "");
$return = $prefix . "GeomFromText($return, $prefix" . "SRID($field[field]))";
} }
return $return; return $return;
} }
/** Check whether a feature is supported /** Check whether a feature is supported
* @param string "comment", "copy", "database", "descidx", "drop_col", "dump", "event", "indexes", "kill", "materializedview", "partitioning", "privileges", "procedure", "processlist", "routine", "scheme", "sequence", "status", "table", "trigger", "type", "variables", "view", "view_trigger" * @param string "check", "comment", "copy", "database", "descidx", "drop_col", "dump", "event", "indexes", "kill", "materializedview", "partitioning", "privileges", "procedure", "processlist", "routine", "scheme", "sequence", "status", "table", "trigger", "type", "variables", "view", "view_trigger"
* @return bool * @return bool
*/ */
function support($feature) { function support($feature) {
return !preg_match("~scheme|sequence|type|view_trigger|materializedview" . (min_version(8) ? "" : "|descidx" . (min_version(5.1) ? "" : "|event|partitioning" . (min_version(5) ? "" : "|routine|trigger|view"))) . "~", $feature); return !preg_match("~scheme|sequence|type|view_trigger|materializedview" . (min_version(8) ? "" : "|descidx" . (min_version(5.1) ? "" : "|event|partitioning")) . (min_version('8.0.16', '10.2.1') ? "" : "|check") . "~", $feature);
} }
/** Kill a process
* @param int
* @return bool
*/
function kill_process($val) { function kill_process($val) {
return queries("KILL " . number($val)); return queries("KILL " . number($val));
} }
/** Return query to get connection ID
* @return string
*/
function connection_id() { function connection_id() {
return "SELECT CONNECTION_ID()"; return "SELECT CONNECTION_ID()";
} }
/** Get maximum number of connections
* @return int
*/
function max_connections() { function max_connections() {
global $connection; global $connection;
return $connection->result("SELECT @@max_connections"); return $connection->result("SELECT @@max_connections");
} }
$jush = "sql"; ///< @var string JUSH identifier
$types = array(); ///< @var array ($type => $maximum_unsigned_length, ...)
$structured_types = array(); ///< @var array ($description => array($type, ...), ...)
foreach (array(
lang('Numbers') => array("tinyint" => 3, "smallint" => 5, "mediumint" => 8, "int" => 10, "bigint" => 20, "decimal" => 66, "float" => 12, "double" => 21),
lang('Date and time') => array("date" => 10, "datetime" => 19, "timestamp" => 19, "time" => 10, "year" => 4),
lang('Strings') => array("char" => 255, "varchar" => 65535, "tinytext" => 255, "text" => 65535, "mediumtext" => 16777215, "longtext" => 4294967295),
lang('Lists') => array("enum" => 65535, "set" => 64),
lang('Binary') => array("bit" => 20, "binary" => 255, "varbinary" => 65535, "tinyblob" => 255, "blob" => 65535, "mediumblob" => 16777215, "longblob" => 4294967295),
lang('Geometry') => array("geometry" => 0, "point" => 0, "linestring" => 0, "polygon" => 0, "multipoint" => 0, "multilinestring" => 0, "multipolygon" => 0, "geometrycollection" => 0),
) as $key => $val) {
$types += $val;
$structured_types[$key] = array_keys($val);
}
$unsigned = array("unsigned", "zerofill", "unsigned zerofill"); ///< @var array number variants
$operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "FIND_IN_SET", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL"); ///< @var array operators used in select
$functions = array("char_length", "date", "from_unixtime", "lower", "round", "floor", "ceil", "sec_to_time", "time_to_sec", "upper"); ///< @var array functions used in select
$grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"); ///< @var array grouping functions used in select
$edit_functions = array( ///< @var array of array("$type|$type2" => "$function/$function2") functions used in editing, [0] - edit and insert, [1] - edit only
array(
"char" => "md5/sha1/password/encrypt/uuid",
"binary" => "md5/sha1",
"date|time" => "now",
), array(
number_type() => "+/-",
"date" => "+ interval/- interval",
"time" => "addtime/subtime",
"char|text" => "concat",
)
);
} }

View File

@@ -1,12 +1,14 @@
<?php <?php
namespace Adminer;
$drivers["oracle"] = "Oracle (beta)"; $drivers["oracle"] = "Oracle (beta)";
if (isset($_GET["oracle"])) { if (isset($_GET["oracle"])) {
$possible_drivers = array("OCI8", "PDO_OCI"); define('Adminer\DRIVER', "oracle");
define("DRIVER", "oracle");
if (extension_loaded("oci8")) { if (extension_loaded("oci8")) {
class Min_DB { class Db {
var $extension = "oci8", $_link, $_result, $server_info, $affected_rows, $errno, $error; var $extension = "oci8", $_link, $_result, $server_info, $affected_rows, $errno, $error;
var $_current_db;
function _error($errno, $error) { function _error($errno, $error) {
if (ini_bool("html_errors")) { if (ini_bool("html_errors")) {
@@ -32,6 +34,7 @@ if (isset($_GET["oracle"])) {
} }
function select_db($database) { function select_db($database) {
$this->_current_db = $database;
return true; return true;
} }
@@ -49,9 +52,10 @@ if (isset($_GET["oracle"])) {
restore_error_handler(); restore_error_handler();
if ($return) { if ($return) {
if (oci_num_fields($result)) { if (oci_num_fields($result)) {
return new Min_Result($result); return new Result($result);
} }
$this->affected_rows = oci_num_rows($result); $this->affected_rows = oci_num_rows($result);
oci_free_statement($result);
} }
return $return; return $return;
} }
@@ -77,7 +81,7 @@ if (isset($_GET["oracle"])) {
} }
} }
class Min_Result { class Result {
var $_result, $_offset = 1, $num_rows; var $_result, $_offset = 1, $num_rows;
function __construct($result) { function __construct($result) {
@@ -103,7 +107,7 @@ if (isset($_GET["oracle"])) {
function fetch_field() { function fetch_field() {
$column = $this->_offset++; $column = $this->_offset++;
$return = new stdClass; $return = new \stdClass;
$return->name = oci_field_name($this->_result, $column); $return->name = oci_field_name($this->_result, $column);
$return->orgname = $return->name; $return->orgname = $return->name;
$return->type = oci_field_type($this->_result, $column); $return->type = oci_field_type($this->_result, $column);
@@ -117,8 +121,9 @@ if (isset($_GET["oracle"])) {
} }
} elseif (extension_loaded("pdo_oci")) { } elseif (extension_loaded("pdo_oci")) {
class Min_DB extends Min_PDO { class Db extends PdoDb {
var $extension = "PDO_OCI"; var $extension = "PDO_OCI";
var $_current_db;
function connect($server, $username, $password) { function connect($server, $username, $password) {
$this->dsn("oci:dbname=//$server;charset=AL32UTF8", $username, $password); $this->dsn("oci:dbname=//$server;charset=AL32UTF8", $username, $password);
@@ -126,6 +131,7 @@ if (isset($_GET["oracle"])) {
} }
function select_db($database) { function select_db($database) {
$this->_current_db = $database;
return true; return true;
} }
} }
@@ -134,7 +140,34 @@ if (isset($_GET["oracle"])) {
class Min_Driver extends Min_SQL { class Driver extends SqlDriver {
static $possibleDrivers = array("OCI8", "PDO_OCI");
static $jush = "oracle";
var $editFunctions = array(
array( //! no parentheses
"date" => "current_date",
"timestamp" => "current_timestamp",
), array(
"number|float|double" => "+/-",
"date|timestamp" => "+ interval/- interval",
"char|clob" => "||",
)
);
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL");
var $functions = array("length", "lower", "round", "upper");
var $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
function __construct($connection) {
parent::__construct($connection);
$this->types = array(
lang('Numbers') => array("number" => 38, "binary_float" => 12, "binary_double" => 21),
lang('Date and time') => array("date" => 10, "timestamp" => 29, "interval year" => 12, "interval day" => 28), //! year(), day() to second()
lang('Strings') => array("char" => 2000, "varchar2" => 4000, "nchar" => 2000, "nvarchar2" => 4000, "clob" => 4294967295, "nclob" => 4294967295),
lang('Binary') => array("raw" => 2000, "long raw" => 2147483648, "blob" => 4294967295, "bfile" => 4294967296),
);
}
//! support empty $set in insert() //! support empty $set in insert()
@@ -142,6 +175,30 @@ if (isset($_GET["oracle"])) {
return true; // automatic start return true; // automatic start
} }
function insertUpdate($table, $rows, $primary) {
global $connection;
foreach ($rows as $set) {
$update = array();
$where = array();
foreach ($set as $key => $val) {
$update[] = "$key = $val";
if (isset($primary[idf_unescape($key)])) {
$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) . ")"))
) {
return false;
}
}
return true;
}
function hasCStyleEscapes() {
return true;
}
} }
@@ -154,10 +211,8 @@ if (isset($_GET["oracle"])) {
return idf_escape($idf); return idf_escape($idf);
} }
function connect() { function connect($credentials) {
global $adminer; $connection = new Db;
$connection = new Min_DB;
$credentials = $adminer->credentials();
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) { if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
return $connection; return $connection;
} }
@@ -165,7 +220,13 @@ if (isset($_GET["oracle"])) {
} }
function get_databases() { function get_databases() {
return get_vals("SELECT tablespace_name FROM user_tablespaces"); 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 limit($query, $where, $limit, $offset = 0, $separator = " ") { function limit($query, $where, $limit, $offset = 0, $separator = " ") {
@@ -193,24 +254,55 @@ if (isset($_GET["oracle"])) {
return $connection->result("SELECT USER FROM DUAL"); return $connection->result("SELECT USER FROM DUAL");
} }
function get_current_db() {
global $connection;
$db = $connection->_current_db ?: DB;
unset($connection->_current_db);
return $db;
}
function where_owner($prefix, $owner = "owner") {
if (!$_GET["ns"]) {
return '';
}
return "$prefix$owner = sys_context('USERENV', 'CURRENT_SCHEMA')";
}
function views_table($columns) {
$owner = where_owner('');
return "(SELECT $columns FROM all_views WHERE " . ($owner ?: "rownum < 0") . ")";
}
function tables_list() { function tables_list() {
return get_key_vals("SELECT table_name, 'table' FROM all_tables WHERE tablespace_name = " . q(DB) . " $view = views_table("view_name");
UNION SELECT view_name, 'view' FROM user_views $owner = where_owner(" AND ");
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" ORDER BY 1"
); //! views don't have schema ); //! views don't have schema
} }
function count_tables($databases) { function count_tables($databases) {
return array(); global $connection;
$return = array();
foreach ($databases as $db) {
$return[$db] = $connection->result("SELECT COUNT(*) FROM all_tables WHERE tablespace_name = " . q($db));
}
return $return;
} }
function table_status($name = "") { function table_status($name = "") {
$return = array(); $return = array();
$search = q($name); $search = q($name);
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) . ($name != "" ? " AND table_name = $search" : "") . " $db = get_current_db();
UNION SELECT view_name, 'view', 0, 0 FROM user_views" . ($name != "" ? " WHERE view_name = $search" : "") . " $view = views_table("view_name");
ORDER BY 1" $owner = where_owner(" AND ");
) as $row) { 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
) {
if ($name != "") { if ($name != "") {
return $row; return $row;
} }
@@ -229,11 +321,12 @@ ORDER BY 1"
function fields($table) { function fields($table) {
$return = array(); $return = array();
foreach (get_rows("SELECT * FROM all_tab_columns WHERE table_name = " . q($table) . " ORDER BY column_id") as $row) { $owner = where_owner(" AND ");
foreach (get_rows("SELECT * FROM all_tab_columns WHERE table_name = " . q($table) . "$owner ORDER BY column_id") as $row) {
$type = $row["DATA_TYPE"]; $type = $row["DATA_TYPE"];
$length = "$row[DATA_PRECISION],$row[DATA_SCALE]"; $length = "$row[DATA_PRECISION],$row[DATA_SCALE]";
if ($length == ",") { if ($length == ",") {
$length = $row["DATA_LENGTH"]; $length = $row["CHAR_COL_DECL_LENGTH"];
} //! int } //! int
$return[$row["COLUMN_NAME"]] = array( $return[$row["COLUMN_NAME"]] = array(
"field" => $row["COLUMN_NAME"], "field" => $row["COLUMN_NAME"],
@@ -254,22 +347,29 @@ ORDER BY 1"
function indexes($table, $connection2 = null) { function indexes($table, $connection2 = null) {
$return = array(); $return = array();
foreach (get_rows("SELECT uic.*, uc.constraint_type $owner = where_owner(" AND ", "aic.table_owner");
FROM user_ind_columns uic foreach (
LEFT JOIN user_constraints uc ON uic.index_name = uc.constraint_name AND uic.table_name = uc.table_name get_rows("SELECT aic.*, ac.constraint_type, atc.data_default
WHERE uic.table_name = " . q($table) . " FROM all_ind_columns aic
ORDER BY uc.constraint_type, uic.column_position", $connection2) as $row) { 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
) {
$index_name = $row["INDEX_NAME"]; $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
$return[$index_name]["type"] = ($row["CONSTRAINT_TYPE"] == "P" ? "PRIMARY" : ($row["CONSTRAINT_TYPE"] == "U" ? "UNIQUE" : "INDEX")); $return[$index_name]["type"] = ($row["CONSTRAINT_TYPE"] == "P" ? "PRIMARY" : ($row["CONSTRAINT_TYPE"] == "U" ? "UNIQUE" : "INDEX"));
$return[$index_name]["columns"][] = $row["COLUMN_NAME"]; $return[$index_name]["columns"][] = $column_name;
$return[$index_name]["lengths"][] = ($row["CHAR_LENGTH"] && $row["CHAR_LENGTH"] != $row["COLUMN_LENGTH"] ? $row["CHAR_LENGTH"] : null); $return[$index_name]["lengths"][] = ($row["CHAR_LENGTH"] && $row["CHAR_LENGTH"] != $row["COLUMN_LENGTH"] ? $row["CHAR_LENGTH"] : null);
$return[$index_name]["descs"][] = ($row["DESCEND"] ? '1' : null); $return[$index_name]["descs"][] = ($row["DESCEND"] && $row["DESCEND"] == "DESC" ? '1' : null);
} }
return $return; return $return;
} }
function view($name) { function view($name) {
$rows = get_rows('SELECT text "select" FROM user_views WHERE view_name = ' . q($name)); $view = views_table("view_name, text");
$rows = get_rows('SELECT text "select" FROM ' . $view . ' WHERE view_name = ' . q($name));
return reset($rows); return reset($rows);
} }
@@ -278,7 +378,7 @@ ORDER BY uc.constraint_type, uic.column_position", $connection2) as $row) {
} }
function information_schema($db) { function information_schema($db) {
return false; return get_schema() == "INFORMATION_SCHEMA";
} }
function error() { function error() {
@@ -294,13 +394,25 @@ ORDER BY uc.constraint_type, uic.column_position", $connection2) as $row) {
function found_rows($table_status, $where) { function found_rows($table_status, $where) {
} }
function auto_increment() {
return "";
}
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) { function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
$alter = $drop = array(); $alter = $drop = array();
$orig_fields = ($table ? fields($table) : array());
foreach ($fields as $field) { foreach ($fields as $field) {
$val = $field[1]; $val = $field[1];
if ($val && $field[0] != "" && idf_escape($field[0]) != $val[0]) { if ($val && $field[0] != "" && idf_escape($field[0]) != $val[0]) {
queries("ALTER TABLE " . table($table) . " RENAME COLUMN " . idf_escape($field[0]) . " TO $val[0]"); queries("ALTER TABLE " . table($table) . " RENAME COLUMN " . idf_escape($field[0]) . " TO $val[0]");
} }
$orig_field = $orig_fields[$field[0]];
if ($val && $orig_field) {
$old = process_field($orig_field, $orig_field);
if ($val[2] == $old[2]) {
$val[2] = "";
}
}
if ($val) { if ($val) {
$alter[] = ($table != "" ? ($field[0] != "" ? "MODIFY (" : "ADD (") : " ") . implode($val) . ($table != "" ? ")" : ""); //! error with name change only $alter[] = ($table != "" ? ($field[0] != "" ? "MODIFY (" : "ADD (") : " ") . implode($val) . ($table != "" ? ")" : ""); //! error with name change only
} else { } else {
@@ -316,6 +428,35 @@ ORDER BY uc.constraint_type, uic.column_position", $connection2) as $row) {
; ;
} }
function alter_indexes($table, $alter) {
$drop = array();
$queries = array();
foreach ($alter as $val) {
if ($val[0] != "INDEX") {
//! descending UNIQUE indexes results in syntax error
$val[2] = preg_replace('~ DESC$~', '', $val[2]);
$create = ($val[2] == "DROP"
? "\nDROP CONSTRAINT " . idf_escape($val[1])
: "\nADD" . ($val[1] != "" ? " CONSTRAINT " . idf_escape($val[1]) : "") . " $val[0] " . ($val[0] == "PRIMARY" ? "KEY " : "") . "(" . implode(", ", $val[2]) . ")"
);
array_unshift($queries, "ALTER TABLE " . table($table) . $create);
} elseif ($val[2] == "DROP") {
$drop[] = idf_escape($val[1]);
} else {
$queries[] = "CREATE INDEX " . idf_escape($val[1] != "" ? $val[1] : uniqid($table . "_")) . " ON " . table($table) . " (" . implode(", ", $val[2]) . ")";
}
}
if ($drop) {
array_unshift($queries, "DROP INDEX " . implode(", ", $drop));
}
foreach ($queries as $query) {
if (!queries($query)) {
return false;
}
}
return true;
}
function foreign_keys($table) { function foreign_keys($table) {
$return = array(); $return = array();
$query = "SELECT c_list.CONSTRAINT_NAME as NAME, $query = "SELECT c_list.CONSTRAINT_NAME as NAME,
@@ -359,7 +500,8 @@ AND c_src.TABLE_NAME = " . q($table);
} }
function schemas() { function schemas() {
return get_vals("SELECT DISTINCT owner FROM dba_segments WHERE owner IN (SELECT username FROM dba_users WHERE default_tablespace NOT IN ('SYSTEM','SYSAUX'))"); $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"));
} }
function get_schema() { function get_schema() {
@@ -367,9 +509,12 @@ AND c_src.TABLE_NAME = " . q($table);
return $connection->result("SELECT sys_context('USERENV', 'SESSION_USER') FROM dual"); return $connection->result("SELECT sys_context('USERENV', 'SESSION_USER') FROM dual");
} }
function set_schema($scheme) { function set_schema($scheme, $connection2 = null) {
global $connection; global $connection;
return $connection->query("ALTER SESSION SET CURRENT_SCHEMA = " . idf_escape($scheme)); if (!$connection2) {
$connection2 = $connection;
}
return $connection2->query("ALTER SESSION SET CURRENT_SCHEMA = " . idf_escape($scheme));
} }
function show_variables() { function show_variables() {
@@ -398,33 +543,6 @@ ORDER BY PROCESS
} }
function support($feature) { function support($feature) {
return preg_match('~^(columns|database|drop_col|indexes|descidx|processlist|scheme|sql|status|table|variables|view|view_trigger)$~', $feature); //! return preg_match('~^(columns|database|drop_col|indexes|descidx|processlist|scheme|sql|status|table|variables|view)$~', $feature); //!
} }
$jush = "oracle";
$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);
}
$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" => "||",
)
);
} }

View File

@@ -1,11 +1,12 @@
<?php <?php
namespace Adminer;
$drivers["pgsql"] = "PostgreSQL"; $drivers["pgsql"] = "PostgreSQL";
if (isset($_GET["pgsql"])) { if (isset($_GET["pgsql"])) {
$possible_drivers = array("PgSQL", "PDO_PgSQL"); define('Adminer\DRIVER', "pgsql");
define("DRIVER", "pgsql");
if (extension_loaded("pgsql")) { if (extension_loaded("pgsql")) {
class Min_DB { class Db {
var $extension = "PgSQL", $_link, $_result, $_string, $_database = true, $server_info, $affected_rows, $error, $timeout; var $extension = "PgSQL", $_link, $_result, $_string, $_database = true, $server_info, $affected_rows, $error, $timeout;
function _error($errno, $error) { function _error($errno, $error) {
@@ -21,6 +22,10 @@ if (isset($_GET["pgsql"])) {
$db = $adminer->database(); $db = $adminer->database();
set_error_handler(array($this, '_error')); set_error_handler(array($this, '_error'));
$this->_string = "host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' user='" . addcslashes($username, "'\\") . "' password='" . addcslashes($password, "'\\") . "'"; $this->_string = "host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' user='" . addcslashes($username, "'\\") . "' password='" . addcslashes($password, "'\\") . "'";
$ssl = $adminer->connectSsl();
if (isset($ssl["mode"])) {
$this->_string .= " sslmode='" . $ssl["mode"] . "'";
}
$this->_link = @pg_connect("$this->_string dbname='" . ($db != "" ? addcslashes($db, "'\\") : "postgres") . "'", PGSQL_CONNECT_FORCE_NEW); $this->_link = @pg_connect("$this->_string dbname='" . ($db != "" ? addcslashes($db, "'\\") : "postgres") . "'", PGSQL_CONNECT_FORCE_NEW);
if (!$this->_link && $db != "") { if (!$this->_link && $db != "") {
// try to connect directly with database for performance // try to connect directly with database for performance
@@ -37,11 +42,11 @@ if (isset($_GET["pgsql"])) {
} }
function quote($string) { function quote($string) {
return "'" . pg_escape_string($this->_link, $string) . "'"; return pg_escape_literal($this->_link, $string);
} }
function value($val, $field) { function value($val, $field) {
return ($field["type"] == "bytea" ? pg_unescape_bytea($val) : $val); return ($field["type"] == "bytea" && $val !== null ? pg_unescape_bytea($val) : $val);
} }
function quoteBinary($string) { function quoteBinary($string) {
@@ -74,7 +79,7 @@ if (isset($_GET["pgsql"])) {
$this->affected_rows = pg_affected_rows($result); $this->affected_rows = pg_affected_rows($result);
$return = true; $return = true;
} else { } else {
$return = new Min_Result($result); $return = new Result($result);
} }
if ($this->timeout) { if ($this->timeout) {
$this->timeout = 0; $this->timeout = 0;
@@ -109,7 +114,7 @@ if (isset($_GET["pgsql"])) {
} }
} }
class Min_Result { class Result {
var $_result, $_offset = 0, $num_rows; var $_result, $_offset = 0, $num_rows;
function __construct($result) { function __construct($result) {
@@ -127,7 +132,7 @@ if (isset($_GET["pgsql"])) {
function fetch_field() { function fetch_field() {
$column = $this->_offset++; $column = $this->_offset++;
$return = new stdClass; $return = new \stdClass;
if (function_exists('pg_field_table')) { if (function_exists('pg_field_table')) {
$return->orgtable = pg_field_table($this->_result, $column); $return->orgtable = pg_field_table($this->_result, $column);
} }
@@ -144,15 +149,19 @@ if (isset($_GET["pgsql"])) {
} }
} elseif (extension_loaded("pdo_pgsql")) { } elseif (extension_loaded("pdo_pgsql")) {
class Min_DB extends Min_PDO { class Db extends PdoDb {
var $extension = "PDO_PgSQL", $timeout; var $extension = "PDO_PgSQL", $timeout;
function connect($server, $username, $password) { function connect($server, $username, $password) {
global $adminer; global $adminer;
$db = $adminer->database(); $db = $adminer->database();
$string = "pgsql:host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' options='-c client_encoding=utf8'"; //! client_encoding is supported since 9.1, but we can't yet use min_version here
$this->dsn("$string dbname='" . ($db != "" ? addcslashes($db, "'\\") : "postgres") . "'", $username, $password); $dsn = "pgsql:host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' client_encoding=utf8 dbname='" . ($db != "" ? addcslashes($db, "'\\") : "postgres") . "'";
//! connect without DB in case of an error $ssl = $adminer->connectSsl();
if (isset($ssl["mode"])) {
$dsn .= " sslmode='" . $ssl["mode"] . "'";
}
$this->dsn($dsn, $username, $password);
return true; return true;
} }
@@ -186,7 +195,48 @@ if (isset($_GET["pgsql"])) {
class Min_Driver extends Min_SQL { class Driver extends SqlDriver {
static $possibleDrivers = array("PgSQL", "PDO_PgSQL");
static $jush = "pgsql";
var $operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "ILIKE", "ILIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"); // no "SQL" to avoid CSRF
var $functions = array("char_length", "lower", "round", "to_hex", "to_timestamp", "upper");
var $grouping = array("avg", "count", "count distinct", "max", "min", "sum");
function __construct($connection) {
parent::__construct($connection);
$this->types = array( //! arrays
lang('Numbers') => array("smallint" => 5, "integer" => 10, "bigint" => 19, "boolean" => 1, "numeric" => 0, "real" => 7, "double precision" => 16, "money" => 20),
lang('Date and time') => array("date" => 13, "time" => 17, "timestamp" => 20, "timestamptz" => 21, "interval" => 0),
lang('Strings') => array("character" => 0, "character varying" => 0, "text" => 0, "tsquery" => 0, "tsvector" => 0, "uuid" => 0, "xml" => 0),
lang('Binary') => array("bit" => 0, "bit varying" => 0, "bytea" => 0),
lang('Network') => array("cidr" => 43, "inet" => 43, "macaddr" => 17, "macaddr8" => 23, "txid_snapshot" => 0),
lang('Geometry') => array("box" => 0, "circle" => 0, "line" => 0, "lseg" => 0, "path" => 0, "point" => 0, "polygon" => 0),
);
if (min_version(9.2, 0, $connection)) {
$this->types[lang('Strings')]["json"] = 4294967295;
if (min_version(9.4, 0, $connection)) {
$this->types[lang('Strings')]["jsonb"] = 4294967295;
}
}
$this->editFunctions = array(
array(
"char" => "md5",
"date|time" => "now",
), array(
number_type() => "+/-",
"date|time" => "+ interval/- interval", //! escape
"char|text" => "||",
)
);
if (min_version(12, 0, $connection)) {
$this->generated = array("STORED");
}
}
function setUserTypes($types) {
$this->types[lang('User types')] = array_flip($types);
}
function insertUpdate($table, $rows, $primary) { function insertUpdate($table, $rows, $primary) {
global $connection; global $connection;
@@ -199,9 +249,10 @@ if (isset($_GET["pgsql"])) {
$where[] = "$key = $val"; $where[] = "$key = $val";
} }
} }
if (!(($where && queries("UPDATE " . table($table) . " SET " . implode(", ", $update) . " WHERE " . implode(" AND ", $where)) && $connection->affected_rows) if (
|| queries("INSERT INTO " . table($table) . " (" . implode(", ", array_keys($set)) . ") VALUES (" . implode(", ", $set) . ")") !(($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 false;
} }
} }
@@ -215,12 +266,12 @@ if (isset($_GET["pgsql"])) {
} }
function convertSearch($idf, $val, $field) { function convertSearch($idf, $val, $field) {
return (preg_match('~char|text' $textTypes = "char|text";
. (!preg_match('~LIKE~', $val["op"]) ? '|date|time(stamp)?|boolean|uuid|' . number_type() : '') if (strpos($val["op"], "LIKE") === false) {
. '~', $field["type"]) $textTypes .= "|date|time(stamp)?|boolean|uuid|inet|cidr|macaddr|" . number_type();
? $idf }
: "CAST($idf AS text)"
); return (preg_match("~$textTypes~", $field["type"]) ? $idf : "CAST($idf AS text)");
} }
function quoteBinary($s) { function quoteBinary($s) {
@@ -231,10 +282,10 @@ if (isset($_GET["pgsql"])) {
return $this->_conn->warnings(); return $this->_conn->warnings();
} }
function tableHelp($name) { function tableHelp($name, $is_view = false) {
$links = array( $links = array(
"information_schema" => "infoschema", "information_schema" => "infoschema",
"pg_catalog" => "catalog", "pg_catalog" => ($is_view ? "view" : "catalog"),
); );
$link = $links[$_GET["ns"]]; $link = $links[$_GET["ns"]];
if ($link) { if ($link) {
@@ -242,6 +293,17 @@ if (isset($_GET["pgsql"])) {
} }
} }
function supportsIndex($table_status) {
return $table_status["Engine"] != "view";
}
function hasCStyleEscapes() {
static $c_style;
if ($c_style === null) {
$c_style = ($this->_conn->result("SHOW standard_conforming_strings") == "off");
}
return $c_style;
}
} }
@@ -254,21 +316,11 @@ if (isset($_GET["pgsql"])) {
return idf_escape($idf); return idf_escape($idf);
} }
function connect() { function connect($credentials) {
global $adminer, $types, $structured_types; $connection = new Db;
$connection = new Min_DB;
$credentials = $adminer->credentials();
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) { if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
if (min_version(9, 0, $connection)) { if (min_version(9, 0, $connection)) {
$connection->query("SET application_name = 'Adminer'"); $connection->query("SET application_name = 'Adminer'");
if (min_version(9.2, 0, $connection)) {
$structured_types[lang('Strings')][] = "json";
$types["json"] = 4294967295;
if (min_version(9.4, 0, $connection)) {
$structured_types[lang('Strings')][] = "jsonb";
$types["jsonb"] = 4294967295;
}
}
} }
return $connection; return $connection;
} }
@@ -276,7 +328,9 @@ if (isset($_GET["pgsql"])) {
} }
function get_databases() { function get_databases() {
return get_vals("SELECT datname FROM pg_database WHERE has_database_privilege(datname, 'CONNECT') ORDER BY datname"); return get_vals("SELECT datname FROM pg_database
WHERE datallowconn = TRUE AND has_database_privilege(datname, 'CONNECT')
ORDER BY datname");
} }
function limit($query, $where, $limit, $offset = 0, $separator = " ") { function limit($query, $where, $limit, $offset = 0, $separator = " ") {
@@ -286,13 +340,13 @@ if (isset($_GET["pgsql"])) {
function limit1($table, $query, $where, $separator = "\n") { function limit1($table, $query, $where, $separator = "\n") {
return (preg_match('~^INTO~', $query) return (preg_match('~^INTO~', $query)
? limit($query, $where, 1, 0, $separator) ? limit($query, $where, 1, 0, $separator)
: " $query" . (is_view(table_status1($table)) ? $where : " WHERE ctid = (SELECT ctid FROM " . table($table) . $where . $separator . "LIMIT 1)") : " $query" . (is_view(table_status1($table)) ? $where : $separator . "WHERE ctid = (SELECT ctid FROM " . table($table) . $where . $separator . "LIMIT 1)")
); );
} }
function db_collation($db, $collations) { function db_collation($db, $collations) {
global $connection; global $connection;
return $connection->result("SHOW LC_COLLATE"); //! respect $db return $connection->result("SELECT datcollate FROM pg_database WHERE datname = " . q($db));
} }
function engines() { function engines() {
@@ -306,7 +360,7 @@ if (isset($_GET["pgsql"])) {
function tables_list() { function tables_list() {
$query = "SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = current_schema()"; $query = "SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = current_schema()";
if (support('materializedview')) { if (support("materializedview")) {
$query .= " $query .= "
UNION ALL UNION ALL
SELECT matviewname, 'MATERIALIZED VIEW' SELECT matviewname, 'MATERIALIZED VIEW'
@@ -319,17 +373,33 @@ ORDER BY 1";
} }
function count_tables($databases) { function count_tables($databases) {
return array(); // would require reconnect global $connection;
$return = array();
foreach ($databases as $db) {
if ($connection->select_db($db)) {
$return[$db] = count(tables_list());
}
}
return $return;
} }
function table_status($name = "") { function table_status($name = "") {
$return = array(); $return = array();
foreach (get_rows("SELECT c.relname AS \"Name\", CASE c.relkind WHEN 'r' THEN 'table' WHEN 'm' THEN 'materialized view' ELSE 'view' END AS \"Engine\", pg_relation_size(c.oid) AS \"Data_length\", pg_total_relation_size(c.oid) - pg_relation_size(c.oid) AS \"Index_length\", obj_description(c.oid, 'pg_class') AS \"Comment\", " . (min_version(12) ? "''" : "CASE WHEN c.relhasoids THEN 'oid' ELSE '' END") . " AS \"Oid\", c.reltuples as \"Rows\", n.nspname foreach (
get_rows("SELECT
c.relname AS \"Name\",
CASE c.relkind WHEN 'r' THEN 'table' WHEN 'm' THEN 'materialized view' ELSE 'view' END AS \"Engine\",
pg_table_size(c.oid) AS \"Data_length\",
pg_indexes_size(c.oid) AS \"Index_length\",
obj_description(c.oid, 'pg_class') AS \"Comment\",
" . (min_version(12) ? "''" : "CASE WHEN c.relhasoids THEN 'oid' ELSE '' END") . " AS \"Oid\",
c.reltuples as \"Rows\",
n.nspname
FROM pg_class c FROM pg_class c
JOIN pg_namespace n ON(n.nspname = current_schema() AND n.oid = c.relnamespace) JOIN pg_namespace n ON(n.nspname = current_schema() AND n.oid = c.relnamespace)
WHERE relkind IN ('r', 'm', 'v', 'f') WHERE relkind IN ('r', 'm', 'v', 'f', 'p')
" . ($name != "" ? "AND relname = " . q($name) : "ORDER BY relname") " . ($name != "" ? "AND relname = " . q($name) : "ORDER BY relname")) as $row //! Index_length, Auto_increment
) as $row) { //! Index_length, Auto_increment ) {
$return[$row["Name"]] = $row; $return[$row["Name"]] = $row;
} }
return ($name != "" ? $return[$name] : $return); return ($name != "" ? $return[$name] : $return);
@@ -349,10 +419,8 @@ WHERE relkind IN ('r', 'm', 'v', 'f')
'timestamp without time zone' => 'timestamp', 'timestamp without time zone' => 'timestamp',
'timestamp with time zone' => 'timestamptz', 'timestamp with time zone' => 'timestamptz',
); );
foreach (
$identity_column = min_version(10) ? "(a.attidentity = 'd')::int" : '0'; get_rows("SELECT a.attname AS field, format_type(a.atttypid, a.atttypmod) AS full_type, pg_get_expr(d.adbin, d.adrelid) AS default, a.attnotnull::int, col_description(c.oid, a.attnum) AS comment" . (min_version(10) ? ", a.attidentity" . (min_version(12) ? ", a.attgenerated" : "") : "") . "
foreach (get_rows("SELECT a.attname AS field, format_type(a.atttypid, a.atttypmod) AS full_type, d.adsrc AS default, a.attnotnull::int, col_description(c.oid, a.attnum) AS comment, $identity_column AS identity
FROM pg_class c FROM pg_class c
JOIN pg_namespace n ON c.relnamespace = n.oid JOIN pg_namespace n ON c.relnamespace = n.oid
JOIN pg_attribute a ON c.oid = a.attrelid JOIN pg_attribute a ON c.oid = a.attrelid
@@ -361,8 +429,8 @@ WHERE c.relname = " . q($table) . "
AND n.nspname = current_schema() AND n.nspname = current_schema()
AND NOT a.attisdropped AND NOT a.attisdropped
AND a.attnum > 0 AND a.attnum > 0
ORDER BY a.attnum" ORDER BY a.attnum") as $row
) as $row) { ) {
//! collation, primary //! collation, primary
preg_match('~([^([]+)(\((.*)\))?([a-z ]+)?((\[[0-9]*])*)$~', $row["full_type"], $match); preg_match('~([^([]+)(\((.*)\))?([a-z ]+)?((\[[0-9]*])*)$~', $row["full_type"], $match);
list(, $type, $length, $row["length"], $addon, $array) = $match; list(, $type, $length, $row["length"], $addon, $array) = $match;
@@ -375,14 +443,15 @@ ORDER BY a.attnum"
$row["type"] = $type; $row["type"] = $type;
$row["full_type"] = $row["type"] . $length . $addon . $array; $row["full_type"] = $row["type"] . $length . $addon . $array;
} }
if ($row['identity']) { if (in_array($row['attidentity'], array('a', 'd'))) {
$row['default'] = 'GENERATED BY DEFAULT AS IDENTITY'; $row['default'] = 'GENERATED ' . ($row['attidentity'] == 'd' ? 'BY DEFAULT' : 'ALWAYS') . ' AS IDENTITY';
} }
$row["generated"] = ($row["attgenerated"] == "s" ? "STORED" : "");
$row["null"] = !$row["attnotnull"]; $row["null"] = !$row["attnotnull"];
$row["auto_increment"] = $row['identity'] || preg_match('~^nextval\(~i', $row["default"]); $row["auto_increment"] = $row['attidentity'] || preg_match('~^nextval\(~i', $row["default"]);
$row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1); $row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1);
if (preg_match('~(.+)::[^)]+(.*)~', $row["default"], $match)) { if (preg_match('~(.+)::[^,)]+(.*)~', $row["default"], $match)) {
$row["default"] = ($match[1] == "NULL" ? null : (($match[1][0] == "'" ? idf_unescape($match[1]) : $match[1]) . $match[2])); $row["default"] = ($match[1] == "NULL" ? null : idf_unescape($match[1]) . $match[2]);
} }
$return[$row["field"]] = $row; $return[$row["field"]] = $row;
} }
@@ -397,39 +466,43 @@ ORDER BY a.attnum"
$return = array(); $return = array();
$table_oid = $connection2->result("SELECT oid FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema()) AND relname = " . q($table)); $table_oid = $connection2->result("SELECT oid FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema()) AND relname = " . q($table));
$columns = get_key_vals("SELECT attnum, attname FROM pg_attribute WHERE attrelid = $table_oid AND attnum > 0", $connection2); $columns = get_key_vals("SELECT attnum, attname FROM pg_attribute WHERE attrelid = $table_oid AND attnum > 0", $connection2);
foreach (get_rows("SELECT relname, indisunique::int, indisprimary::int, indkey, indoption , (indpred IS NOT NULL)::int as indispartial FROM pg_index i, pg_class ci WHERE i.indrelid = $table_oid AND ci.oid = i.indexrelid", $connection2) as $row) { foreach (get_rows("SELECT relname, indisunique::int, indisprimary::int, indkey, indoption, (indpred IS NOT NULL)::int as indispartial FROM pg_index i, pg_class ci WHERE i.indrelid = $table_oid AND ci.oid = i.indexrelid ORDER BY indisprimary DESC, indisunique DESC", $connection2) as $row) {
$relname = $row["relname"]; $relname = $row["relname"];
$return[$relname]["type"] = ($row["indispartial"] ? "INDEX" : ($row["indisprimary"] ? "PRIMARY" : ($row["indisunique"] ? "UNIQUE" : "INDEX"))); $return[$relname]["type"] = ($row["indispartial"] ? "INDEX" : ($row["indisprimary"] ? "PRIMARY" : ($row["indisunique"] ? "UNIQUE" : "INDEX")));
$return[$relname]["columns"] = array(); $return[$relname]["columns"] = array();
$return[$relname]["descs"] = array();
if ($row["indkey"]) {
foreach (explode(" ", $row["indkey"]) as $indkey) { foreach (explode(" ", $row["indkey"]) as $indkey) {
$return[$relname]["columns"][] = $columns[$indkey]; $return[$relname]["columns"][] = $columns[$indkey];
} }
$return[$relname]["descs"] = array();
foreach (explode(" ", $row["indoption"]) as $indoption) { foreach (explode(" ", $row["indoption"]) as $indoption) {
$return[$relname]["descs"][] = ($indoption & 1 ? '1' : null); // 1 - INDOPTION_DESC $return[$relname]["descs"][] = ($indoption & 1 ? '1' : null); // 1 - INDOPTION_DESC
} }
}
$return[$relname]["lengths"] = array(); $return[$relname]["lengths"] = array();
} }
return $return; return $return;
} }
function foreign_keys($table) { function foreign_keys($table) {
global $on_actions; global $driver;
$return = array(); $return = array();
foreach (get_rows("SELECT conname, condeferrable::int AS deferrable, pg_get_constraintdef(oid) AS definition foreach (
get_rows("SELECT conname, condeferrable::int AS deferrable, pg_get_constraintdef(oid) AS definition
FROM pg_constraint FROM pg_constraint
WHERE conrelid = (SELECT pc.oid FROM pg_class AS pc INNER JOIN pg_namespace AS pn ON (pn.oid = pc.relnamespace) WHERE pc.relname = " . q($table) . " AND pn.nspname = current_schema()) WHERE conrelid = (SELECT pc.oid FROM pg_class AS pc INNER JOIN pg_namespace AS pn ON (pn.oid = pc.relnamespace) WHERE pc.relname = " . q($table) . " AND pn.nspname = current_schema())
AND contype = 'f'::char AND contype = 'f'::char
ORDER BY conkey, conname") as $row) { ORDER BY conkey, conname") as $row
) {
if (preg_match('~FOREIGN KEY\s*\((.+)\)\s*REFERENCES (.+)\((.+)\)(.*)$~iA', $row['definition'], $match)) { if (preg_match('~FOREIGN KEY\s*\((.+)\)\s*REFERENCES (.+)\((.+)\)(.*)$~iA', $row['definition'], $match)) {
$row['source'] = array_map('trim', explode(',', $match[1])); $row['source'] = array_map('Adminer\idf_unescape', array_map('trim', explode(',', $match[1])));
if (preg_match('~^(("([^"]|"")+"|[^"]+)\.)?"?("([^"]|"")+"|[^"]+)$~', $match[2], $match2)) { if (preg_match('~^(("([^"]|"")+"|[^"]+)\.)?"?("([^"]|"")+"|[^"]+)$~', $match[2], $match2)) {
$row['ns'] = str_replace('""', '"', preg_replace('~^"(.+)"$~', '\1', $match2[2])); $row['ns'] = idf_unescape($match2[2]);
$row['table'] = str_replace('""', '"', preg_replace('~^"(.+)"$~', '\1', $match2[4])); $row['table'] = idf_unescape($match2[4]);
} }
$row['target'] = array_map('trim', explode(',', $match[3])); $row['target'] = array_map('Adminer\idf_unescape', array_map('trim', explode(',', $match[3])));
$row['on_delete'] = (preg_match("~ON DELETE ($on_actions)~", $match[4], $match2) ? $match2[1] : 'NO ACTION'); $row['on_delete'] = (preg_match("~ON DELETE ($driver->onActions)~", $match[4], $match2) ? $match2[1] : 'NO ACTION');
$row['on_update'] = (preg_match("~ON UPDATE ($on_actions)~", $match[4], $match2) ? $match2[1] : 'NO ACTION'); $row['on_update'] = (preg_match("~ON UPDATE ($driver->onActions)~", $match[4], $match2) ? $match2[1] : 'NO ACTION');
$return[$row['conname']] = $row; $return[$row['conname']] = $row;
} }
} }
@@ -438,7 +511,7 @@ ORDER BY conkey, conname") as $row) {
function view($name) { function view($name) {
global $connection; global $connection;
return array("select" => trim($connection->result("SELECT pg_get_viewdef(" . $connection->result("SELECT oid FROM pg_class WHERE relname = " . q($name)) . ")"))); return array("select" => trim($connection->result("SELECT pg_get_viewdef(" . $connection->result("SELECT oid FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema()) AND relname = " . q($name)) . ")")));
} }
function collations() { function collations() {
@@ -447,7 +520,7 @@ ORDER BY conkey, conname") as $row) {
} }
function information_schema($db) { function information_schema($db) {
return ($db == "information_schema"); return get_schema() == "information_schema";
} }
function error() { function error() {
@@ -466,11 +539,12 @@ ORDER BY conkey, conname") as $row) {
function drop_databases($databases) { function drop_databases($databases) {
global $connection; global $connection;
$connection->close(); $connection->close();
return apply_queries("DROP DATABASE", $databases, 'idf_escape'); return apply_queries("DROP DATABASE", $databases, 'Adminer\idf_escape');
} }
function rename_database($name, $collation) { function rename_database($name, $collation) {
//! current database cannot be renamed global $connection;
$connection->close();
return queries("ALTER DATABASE " . idf_escape(DB) . " RENAME TO " . idf_escape($name)); return queries("ALTER DATABASE " . idf_escape(DB) . " RENAME TO " . idf_escape($name));
} }
@@ -484,6 +558,7 @@ ORDER BY conkey, conname") as $row) {
if ($table != "" && $table != $name) { if ($table != "" && $table != $name) {
$queries[] = "ALTER TABLE " . table($table) . " RENAME TO " . table($name); $queries[] = "ALTER TABLE " . table($table) . " RENAME TO " . table($name);
} }
$sequence = "";
foreach ($fields as $field) { foreach ($fields as $field) {
$column = idf_escape($field[0]); $column = idf_escape($field[0]);
$val = $field[1]; $val = $field[1];
@@ -492,20 +567,28 @@ ORDER BY conkey, conname") as $row) {
} else { } else {
$val5 = $val[5]; $val5 = $val[5];
unset($val[5]); unset($val[5]);
if (isset($val[6]) && $field[0] == "") { // auto_increment
$val[1] = ($val[1] == "bigint" ? " big" : " ") . "serial";
}
if ($field[0] == "") { if ($field[0] == "") {
if (isset($val[6])) { // auto_increment
$val[1] = ($val[1] == " bigint" ? " big" : ($val[1] == " smallint" ? " small" : " ")) . "serial";
}
$alter[] = ($table != "" ? "ADD " : " ") . implode($val); $alter[] = ($table != "" ? "ADD " : " ") . implode($val);
if (isset($val[6])) {
$alter[] = ($table != "" ? "ADD" : " ") . " PRIMARY KEY ($val[0])";
}
} else { } else {
if ($column != $val[0]) { if ($column != $val[0]) {
$queries[] = "ALTER TABLE " . table($name) . " RENAME $column TO $val[0]"; $queries[] = "ALTER TABLE " . table($name) . " RENAME $column TO $val[0]";
} }
$alter[] = "ALTER $column TYPE$val[1]"; $alter[] = "ALTER $column TYPE$val[1]";
if (!$val[6]) { $sequence_name = $table . "_" . idf_unescape($val[0]) . "_seq";
$alter[] = "ALTER $column " . ($val[3] ? "SET$val[3]" : "DROP DEFAULT"); $alter[] = "ALTER $column " . ($val[3] ? "SET" . preg_replace('~GENERATED ALWAYS(.*) STORED~', 'EXPRESSION\1', $val[3])
$alter[] = "ALTER $column " . ($val[2] == " NULL" ? "DROP NOT" : "SET") . $val[2]; : (isset($val[6]) ? "SET DEFAULT nextval(" . q($sequence_name) . ")"
: "DROP DEFAULT" //! change to DROP EXPRESSION with generated columns
));
if (isset($val[6])) {
$sequence = "CREATE SEQUENCE IF NOT EXISTS " . idf_escape($sequence_name) . " OWNED BY " . idf_escape($table) . ".$val[0]";
} }
$alter[] = "ALTER $column " . ($val[2] == " NULL" ? "DROP NOT" : "SET") . $val[2];
} }
if ($field[0] != "" || $val5 != "") { if ($field[0] != "" || $val5 != "") {
$queries[] = "COMMENT ON COLUMN " . table($name) . ".$val[0] IS " . ($val5 != "" ? substr($val5, 9) : "''"); $queries[] = "COMMENT ON COLUMN " . table($name) . ".$val[0] IS " . ($val5 != "" ? substr($val5, 9) : "''");
@@ -518,12 +601,15 @@ ORDER BY conkey, conname") as $row) {
} elseif ($alter) { } elseif ($alter) {
array_unshift($queries, "ALTER TABLE " . table($table) . "\n" . implode(",\n", $alter)); array_unshift($queries, "ALTER TABLE " . table($table) . "\n" . implode(",\n", $alter));
} }
if ($table != "" || $comment != "") { if ($sequence) {
array_unshift($queries, $sequence);
}
if ($comment !== null) {
$queries[] = "COMMENT ON TABLE " . table($name) . " IS " . q($comment); $queries[] = "COMMENT ON TABLE " . table($name) . " IS " . q($comment);
} }
if ($auto_increment != "") { // if ($auto_increment != "") {
//! $queries[] = "SELECT setval(pg_get_serial_sequence(" . q($name) . ", ), $auto_increment)"; //! $queries[] = "SELECT setval(pg_get_serial_sequence(" . q($name) . ", ), $auto_increment)";
} // }
foreach ($queries as $query) { foreach ($queries as $query) {
if (!queries($query)) { if (!queries($query)) {
return false; return false;
@@ -564,7 +650,7 @@ ORDER BY conkey, conname") as $row) {
} }
function truncate_tables($tables) { function truncate_tables($tables) {
return queries("TRUNCATE " . implode(", ", array_map('table', $tables))); return queries("TRUNCATE " . implode(", ", array_map('Adminer\table', $tables)));
return true; return true;
} }
@@ -592,21 +678,34 @@ ORDER BY conkey, conname") as $row) {
return true; return true;
} }
function trigger($name, $table = null) { function trigger($name, $table) {
if ($name == "") { if ($name == "") {
return array("Statement" => "EXECUTE PROCEDURE ()"); return array("Statement" => "EXECUTE PROCEDURE ()");
} }
if ($table === null) { $columns = array();
$table = $_GET['trigger']; $where = "WHERE trigger_schema = current_schema() AND event_object_table = " . q($table) . " AND trigger_name = " . q($name);
foreach (get_rows("SELECT * FROM information_schema.triggered_update_columns $where") as $row) {
$columns[] = $row["event_object_column"];
} }
$rows = get_rows('SELECT t.trigger_name AS "Trigger", t.action_timing AS "Timing", (SELECT STRING_AGG(event_manipulation, \' OR \') FROM information_schema.triggers WHERE event_object_table = t.event_object_table AND trigger_name = t.trigger_name ) AS "Events", t.event_manipulation AS "Event", \'FOR EACH \' || t.action_orientation AS "Type", t.action_statement AS "Statement" FROM information_schema.triggers t WHERE t.event_object_table = ' . q($table) . ' AND t.trigger_name = ' . q($name)); $return = array();
return reset($rows); foreach (get_rows('SELECT trigger_name AS "Trigger", action_timing AS "Timing", event_manipulation AS "Event", \'FOR EACH \' || action_orientation AS "Type", action_statement AS "Statement" FROM information_schema.triggers ' . "$where ORDER BY event_manipulation DESC") as $row) {
if ($columns && $row["Event"] == "UPDATE") {
$row["Event"] .= " OF";
}
$row["Of"] = implode(", ", $columns);
if ($return) {
$row["Event"] .= " OR $return[Event]";
}
$return = $row;
}
return $return;
} }
function triggers($table) { function triggers($table) {
$return = array(); $return = array();
foreach (get_rows("SELECT * FROM information_schema.triggers WHERE event_object_table = " . q($table)) as $row) { foreach (get_rows("SELECT * FROM information_schema.triggers WHERE trigger_schema = current_schema() AND event_object_table = " . q($table)) as $row) {
$return[$row["trigger_name"]] = array($row["action_timing"], $row["event_manipulation"]); $trigger = trigger($row["trigger_name"], $table);
$return[$trigger["Trigger"]] = array($trigger["Timing"], $trigger["Event"]);
} }
return $return; return $return;
} }
@@ -614,7 +713,7 @@ ORDER BY conkey, conname") as $row) {
function trigger_options() { function trigger_options() {
return array( return array(
"Timing" => array("BEFORE", "AFTER"), "Timing" => array("BEFORE", "AFTER"),
"Event" => array("INSERT", "UPDATE", "DELETE"), "Event" => array("INSERT", "UPDATE", "UPDATE OF", "DELETE", "INSERT OR UPDATE", "INSERT OR UPDATE OF", "DELETE OR INSERT", "DELETE OR UPDATE", "DELETE OR UPDATE OF", "DELETE OR INSERT OR UPDATE", "DELETE OR INSERT OR UPDATE OF"),
"Type" => array("FOR EACH ROW", "FOR EACH STATEMENT"), "Type" => array("FOR EACH ROW", "FOR EACH STATEMENT"),
); );
} }
@@ -661,18 +760,15 @@ ORDER BY SPECIFIC_NAME');
function found_rows($table_status, $where) { function found_rows($table_status, $where) {
global $connection; global $connection;
if (preg_match( if (preg_match("~ rows=([0-9]+)~", $connection->result("EXPLAIN SELECT * FROM " . idf_escape($table_status["Name"]) . ($where ? " WHERE " . implode(" AND ", $where) : "")), $regs)) {
"~ rows=([0-9]+)~",
$connection->result("EXPLAIN SELECT * FROM " . idf_escape($table_status["Name"]) . ($where ? " WHERE " . implode(" AND ", $where) : "")),
$regs
)) {
return $regs[1]; return $regs[1];
} }
return false; return false;
} }
function types() { function types() {
return get_vals("SELECT typname return get_key_vals(
"SELECT oid, typname
FROM pg_type FROM pg_type
WHERE typnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema()) WHERE typnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema())
AND typtype IN ('b','d','e') AND typtype IN ('b','d','e')
@@ -680,6 +776,12 @@ AND typelem = 0"
); );
} }
function type_values($id) {
// to get values from type string: unnest(enum_range(NULL::"$type"))
$enums = get_vals("SELECT enumlabel FROM pg_enum WHERE enumtypid = $id ORDER BY enumsortorder");
return ($enums ? "'" . implode("', '", array_map('addslashes', $enums)) . "'" : "");
}
function schemas() { function schemas() {
return get_vals("SELECT nspname FROM pg_namespace ORDER BY nspname"); return get_vals("SELECT nspname FROM pg_namespace ORDER BY nspname");
} }
@@ -689,30 +791,44 @@ AND typelem = 0"
return $connection->result("SELECT current_schema()"); return $connection->result("SELECT current_schema()");
} }
function set_schema($schema) { function set_schema($schema, $connection2 = null) {
global $connection, $types, $structured_types; global $connection, $driver;
$return = $connection->query("SET search_path TO " . idf_escape($schema)); if (!$connection2) {
foreach (types() as $type) { //! get types from current_schemas('t') $connection2 = $connection;
if (!isset($types[$type])) {
$types[$type] = 0;
$structured_types[lang('User types')][] = $type;
}
} }
$return = $connection2->query("SET search_path TO " . idf_escape($schema));
$driver->setUserTypes(types()); //! get types from current_schemas('t')
return $return; return $return;
} }
// create_sql() produces CREATE TABLE without FK CONSTRAINTs
// foreign_keys_sql() produces all FK CONSTRAINTs as ALTER TABLE ... ADD CONSTRAINT
// so that all FKs can be added after all tables have been created, avoiding any need to reorder CREATE TABLE statements in order of their FK dependencies
function foreign_keys_sql($table) {
$return = "";
$status = table_status($table);
$fkeys = foreign_keys($table);
ksort($fkeys);
foreach ($fkeys as $fkey_name => $fkey) {
$return .= "ALTER TABLE ONLY " . idf_escape($status['nspname']) . "." . idf_escape($status['Name']) . " ADD CONSTRAINT " . idf_escape($fkey_name) . " $fkey[definition] " . ($fkey['deferrable'] ? 'DEFERRABLE' : 'NOT DEFERRABLE') . ";\n";
}
return ($return ? "$return\n" : $return);
}
function create_sql($table, $auto_increment, $style) { function create_sql($table, $auto_increment, $style) {
global $connection; global $driver;
$return = '';
$return_parts = array(); $return_parts = array();
$sequences = array(); $sequences = array();
$status = table_status($table); $status = table_status($table);
if (is_view($status)) {
$view = view($table);
return rtrim("CREATE VIEW " . idf_escape($table) . " AS $view[select]", ";");
}
$fields = fields($table); $fields = fields($table);
$indexes = indexes($table);
ksort($indexes);
$fkeys = foreign_keys($table);
ksort($fkeys);
if (!$status || empty($fields)) { if (!$status || empty($fields)) {
return false; return false;
@@ -721,7 +837,7 @@ AND typelem = 0"
$return = "CREATE TABLE " . idf_escape($status['nspname']) . "." . idf_escape($status['Name']) . " (\n "; $return = "CREATE TABLE " . idf_escape($status['nspname']) . "." . idf_escape($status['Name']) . " (\n ";
// fields' definitions // fields' definitions
foreach ($fields as $field_name => $field) { foreach ($fields as $field) {
$part = idf_escape($field['field']) . ' ' . $field['full_type'] $part = idf_escape($field['field']) . ' ' . $field['full_type']
. default_value($field) . default_value($field)
. ($field['attnotnull'] ? " NOT NULL" : ""); . ($field['attnotnull'] ? " NOT NULL" : "");
@@ -730,12 +846,15 @@ AND typelem = 0"
// sequences for fields // sequences for fields
if (preg_match('~nextval\(\'([^\']+)\'\)~', $field['default'], $matches)) { if (preg_match('~nextval\(\'([^\']+)\'\)~', $field['default'], $matches)) {
$sequence_name = $matches[1]; $sequence_name = $matches[1];
$sq = reset(get_rows(min_version(10) $sq = reset(get_rows((min_version(10)
? "SELECT *, cache_size AS cache_value FROM pg_sequences WHERE schemaname = current_schema() AND sequencename = " . q($sequence_name) ? "SELECT *, cache_size AS cache_value FROM pg_sequences WHERE schemaname = current_schema() AND sequencename = " . q(idf_unescape($sequence_name))
: "SELECT * FROM $sequence_name" : "SELECT * FROM $sequence_name"
)); ), null, "-- "));
$sequences[] = ($style == "DROP+CREATE" ? "DROP SEQUENCE IF EXISTS $sequence_name;\n" : "") $sequences[] = ($style == "DROP+CREATE" ? "DROP SEQUENCE IF EXISTS $sequence_name;\n" : "")
. "CREATE SEQUENCE $sequence_name INCREMENT $sq[increment_by] MINVALUE $sq[min_value] MAXVALUE $sq[max_value] START " . ($auto_increment ? $sq['last_value'] : 1) . " CACHE $sq[cache_value];"; . "CREATE SEQUENCE $sequence_name INCREMENT $sq[increment_by] MINVALUE $sq[min_value] MAXVALUE $sq[max_value]"
. ($auto_increment && $sq['last_value'] ? " START " . ($sq["last_value"] + 1) : "")
. " CACHE $sq[cache_value];"
;
} }
} }
@@ -744,33 +863,21 @@ AND typelem = 0"
$return = implode("\n\n", $sequences) . "\n\n$return"; $return = implode("\n\n", $sequences) . "\n\n$return";
} }
// primary + unique keys $primary = "";
foreach ($indexes as $index_name => $index) { foreach (indexes($table) as $index_name => $index) {
switch($index['type']) { if ($index['type'] == 'PRIMARY') {
case 'UNIQUE': $return_parts[] = "CONSTRAINT " . idf_escape($index_name) . " UNIQUE (" . implode(', ', array_map('idf_escape', $index['columns'])) . ")"; break; $primary = $index_name;
case 'PRIMARY': $return_parts[] = "CONSTRAINT " . idf_escape($index_name) . " PRIMARY KEY (" . implode(', ', array_map('idf_escape', $index['columns'])) . ")"; break; $return_parts[] = "CONSTRAINT " . idf_escape($index_name) . " PRIMARY KEY (" . implode(', ', array_map('Adminer\idf_escape', $index['columns'])) . ")";
} }
} }
// foreign keys foreach ($driver->checkConstraints($table) as $conname => $consrc) {
foreach ($fkeys as $fkey_name => $fkey) { $return_parts[] = "CONSTRAINT " . idf_escape($conname) . " CHECK $consrc";
$return_parts[] = "CONSTRAINT " . idf_escape($fkey_name) . " $fkey[definition] " . ($fkey['deferrable'] ? 'DEFERRABLE' : 'NOT DEFERRABLE');
} }
$return .= implode(",\n ", $return_parts) . "\n) WITH (oids = " . ($status['Oid'] ? 'true' : 'false') . ");"; $return .= implode(",\n ", $return_parts) . "\n) WITH (oids = " . ($status['Oid'] ? 'true' : 'false') . ");";
// "basic" indexes after table definition // comments for table & fields
foreach ($indexes as $index_name => $index) {
if ($index['type'] == 'INDEX') {
$columns = array();
foreach ($index['columns'] as $key => $val) {
$columns[] = idf_escape($val) . ($index['descs'][$key] ? " DESC" : "");
}
$return .= "\n\nCREATE INDEX " . idf_escape($index_name) . " ON " . idf_escape($status['nspname']) . "." . idf_escape($status['Name']) . " USING btree (" . implode(', ', $columns) . ");";
}
}
// coments for table & fields
if ($status['Comment']) { if ($status['Comment']) {
$return .= "\n\nCOMMENT ON TABLE " . idf_escape($status['nspname']) . "." . idf_escape($status['Name']) . " IS " . q($status['Comment']) . ";"; $return .= "\n\nCOMMENT ON TABLE " . idf_escape($status['nspname']) . "." . idf_escape($status['Name']) . " IS " . q($status['Comment']) . ";";
} }
@@ -781,6 +888,10 @@ AND typelem = 0"
} }
} }
foreach (get_rows("SELECT indexdef FROM pg_catalog.pg_indexes WHERE schemaname = current_schema() AND tablename = " . q($table) . ($primary ? " AND indexname != " . q($primary) : ""), null, "-- ") as $row) {
$return .= "\n\n$row[indexdef];";
}
return rtrim($return, ';'); return rtrim($return, ';');
} }
@@ -793,7 +904,7 @@ AND typelem = 0"
$return = ""; $return = "";
foreach (triggers($table) as $trg_id => $trg) { foreach (triggers($table) as $trg_id => $trg) {
$trigger = trigger($trg_id, $status['Name']); $trigger = trigger($trg_id, $status['Name']);
$return .= "\nCREATE TRIGGER " . idf_escape($trigger['Trigger']) . " $trigger[Timing] $trigger[Events] ON " . idf_escape($status["nspname"]) . "." . idf_escape($status['Name']) . " $trigger[Type] $trigger[Statement];;\n"; $return .= "\nCREATE TRIGGER " . idf_escape($trigger['Trigger']) . " $trigger[Timing] $trigger[Event] ON " . idf_escape($status["nspname"]) . "." . idf_escape($status['Name']) . " $trigger[Type] $trigger[Statement];;\n";
} }
return $return; return $return;
} }
@@ -811,9 +922,6 @@ AND typelem = 0"
return get_rows("SELECT * FROM pg_stat_activity ORDER BY " . (min_version(9.2) ? "pid" : "procpid")); return get_rows("SELECT * FROM pg_stat_activity ORDER BY " . (min_version(9.2) ? "pid" : "procpid"));
} }
function show_status() {
}
function convert_field($field) { function convert_field($field) {
} }
@@ -822,7 +930,7 @@ AND typelem = 0"
} }
function support($feature) { function support($feature) {
return preg_match('~^(database|table|columns|sql|indexes|descidx|comment|view|' . (min_version(9.3) ? 'materializedview|' : '') . 'scheme|routine|processlist|sequence|trigger|type|variables|drop_col|kill|dump)$~', $feature); return preg_match('~^(check|database|table|columns|sql|indexes|descidx|comment|view|' . (min_version(9.3) ? 'materializedview|' : '') . 'scheme|routine|processlist|sequence|trigger|type|variables|drop_col|kill|dump)$~', $feature);
} }
function kill_process($val) { function kill_process($val) {
@@ -837,33 +945,4 @@ AND typelem = 0"
global $connection; global $connection;
return $connection->result("SHOW max_connections"); return $connection->result("SHOW max_connections");
} }
$jush = "pgsql";
$types = array();
$structured_types = array();
foreach (array( //! arrays
lang('Numbers') => array("smallint" => 5, "integer" => 10, "bigint" => 19, "boolean" => 1, "numeric" => 0, "real" => 7, "double precision" => 16, "money" => 20),
lang('Date and time') => array("date" => 13, "time" => 17, "timestamp" => 20, "timestamptz" => 21, "interval" => 0),
lang('Strings') => array("character" => 0, "character varying" => 0, "text" => 0, "tsquery" => 0, "tsvector" => 0, "uuid" => 0, "xml" => 0),
lang('Binary') => array("bit" => 0, "bit varying" => 0, "bytea" => 0),
lang('Network') => array("cidr" => 43, "inet" => 43, "macaddr" => 17, "txid_snapshot" => 0),
lang('Geometry') => array("box" => 0, "circle" => 0, "line" => 0, "lseg" => 0, "path" => 0, "point" => 0, "polygon" => 0),
) as $key => $val) { //! can be retrieved from pg_type
$types += $val;
$structured_types[$key] = array_keys($val);
}
$unsigned = array();
$operators = array("=", "<", ">", "<=", ">=", "!=", "~", "!~", "LIKE", "LIKE %%", "ILIKE", "ILIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"); // no "SQL" to avoid CSRF
$functions = array("char_length", "lower", "round", "to_hex", "to_timestamp", "upper");
$grouping = array("avg", "count", "count distinct", "max", "min", "sum");
$edit_functions = array(
array(
"char" => "md5",
"date|time" => "now",
), array(
number_type() => "+/-",
"date|time" => "+ interval/- interval", //! escape
"char|text" => "||",
)
);
} }

View File

@@ -1,18 +1,17 @@
<?php <?php
$drivers["sqlite"] = "SQLite 3"; namespace Adminer;
$drivers["sqlite2"] = "SQLite 2";
$drivers["sqlite"] = "SQLite";
if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
$possible_drivers = array((isset($_GET["sqlite"]) ? "SQLite3" : "SQLite"), "PDO_SQLite");
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")) {
class Min_SQLite { class SqliteDb {
var $extension = "SQLite3", $server_info, $affected_rows, $errno, $error, $_link; var $extension = "SQLite3", $server_info, $affected_rows, $errno, $error, $_link;
function __construct($filename) { function __construct($filename) {
$this->_link = new SQLite3($filename); $this->_link = new \SQLite3($filename);
$version = $this->_link->version(); $version = $this->_link->version();
$this->server_info = $version["versionString"]; $this->server_info = $version["versionString"];
} }
@@ -25,7 +24,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
$this->error = $this->_link->lastErrorMsg(); $this->error = $this->_link->lastErrorMsg();
return false; return false;
} elseif ($result->numColumns()) { } elseif ($result->numColumns()) {
return new Min_Result($result); return new Result($result);
} }
$this->affected_rows = $this->_link->changes(); $this->affected_rows = $this->_link->changes();
return true; return true;
@@ -48,11 +47,11 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return false; return false;
} }
$row = $result->_result->fetchArray(); $row = $result->_result->fetchArray();
return $row[$field]; return $row ? $row[$field] : false;
} }
} }
class Min_Result { class Result {
var $_result, $_offset = 0, $num_rows; var $_result, $_offset = 0, $num_rows;
function __construct($result) { function __construct($result) {
@@ -82,105 +81,23 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
} }
} }
} else {
class Min_SQLite {
var $extension = "SQLite", $server_info, $affected_rows, $error, $_link;
function __construct($filename) {
$this->server_info = sqlite_libversion();
$this->_link = new SQLiteDatabase($filename);
}
function query($query, $unbuffered = false) {
$method = ($unbuffered ? "unbufferedQuery" : "query");
$result = @$this->_link->$method($query, SQLITE_BOTH, $error);
$this->error = "";
if (!$result) {
$this->error = $error;
return false;
} elseif ($result === true) {
$this->affected_rows = $this->changes();
return true;
}
return new Min_Result($result);
}
function quote($string) {
return "'" . sqlite_escape_string($string) . "'";
}
function store_result() {
return $this->_result;
}
function result($query, $field = 0) {
$result = $this->query($query);
if (!is_object($result)) {
return false;
}
$row = $result->_result->fetch();
return $row[$field];
}
}
class Min_Result {
var $_result, $_offset = 0, $num_rows;
function __construct($result) {
$this->_result = $result;
if (method_exists($result, 'numRows')) { // not available in unbuffered query
$this->num_rows = $result->numRows();
}
}
function fetch_assoc() {
$row = $this->_result->fetch(SQLITE_ASSOC);
if (!$row) {
return false;
}
$return = array();
foreach ($row as $key => $val) {
$return[($key[0] == '"' ? idf_unescape($key) : $key)] = $val;
}
return $return;
}
function fetch_row() {
return $this->_result->fetch(SQLITE_NUM);
}
function fetch_field() {
$name = $this->_result->fieldName($this->_offset++);
$pattern = '(\[.*]|"(?:[^"]|"")*"|(.+))';
if (preg_match("~^($pattern\\.)?$pattern\$~", $name, $match)) {
$table = ($match[3] != "" ? $match[3] : idf_unescape($match[2]));
$name = ($match[5] != "" ? $match[5] : idf_unescape($match[4]));
}
return (object) array(
"name" => $name,
"orgname" => $name,
"orgtable" => $table,
);
}
}
}
} elseif (extension_loaded("pdo_sqlite")) { } elseif (extension_loaded("pdo_sqlite")) {
class Min_SQLite extends Min_PDO { class SqliteDb extends PdoDb {
var $extension = "PDO_SQLite"; var $extension = "PDO_SQLite";
function __construct($filename) { function __construct($filename) {
$this->dsn(DRIVER . ":$filename", "", ""); $this->dsn(DRIVER . ":$filename", "", "");
} }
function select_db($db) {
return false;
}
} }
} }
if (class_exists("Min_SQLite")) { if (class_exists('Adminer\SqliteDb')) {
class Min_DB extends Min_SQLite { class Db extends SqliteDb {
function __construct() { function __construct() {
parent::__construct(":memory:"); parent::__construct(":memory:");
@@ -191,6 +108,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
if (is_readable($filename) && $this->query("ATTACH " . $this->quote(preg_match("~(^[/\\\\]|:)~", $filename) ? $filename : dirname($_SERVER["SCRIPT_FILENAME"]) . "/$filename") . " AS a")) { // is_readable - SQLite 3 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); parent::__construct($filename);
$this->query("PRAGMA foreign_keys = 1"); $this->query("PRAGMA foreign_keys = 1");
$this->query("PRAGMA busy_timeout = 500");
return true; return true;
} }
return false; return false;
@@ -208,7 +126,36 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
class Min_Driver extends Min_SQL { class Driver extends SqlDriver {
static $possibleDrivers = array("SQLite3", "PDO_SQLite");
static $jush = "sqlite";
protected $types = array(array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0));
var $editFunctions = array(
array(
// "text" => "date('now')/time('now')/datetime('now')",
), array(
"integer|real|numeric" => "+/-",
// "text" => "date/time/datetime",
"text" => "||",
)
);
var $operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"); // REGEXP can be user defined function
var $functions = array("hex", "length", "lower", "round", "unixepoch", "upper");
var $grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum");
function __construct($connection) {
parent::__construct($connection);
if (min_version(3.31, 0, $connection)) {
$this->generated = array("STORED", "VIRTUAL");
}
}
function structuredTypes() {
return array_keys($this->types[0]);
}
function insertUpdate($table, $rows, $primary) { function insertUpdate($table, $rows, $primary) {
$values = array(); $values = array();
@@ -218,7 +165,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return queries("REPLACE INTO " . table($table) . " (" . implode(", ", array_keys(reset($rows))) . ") VALUES\n" . implode(",\n", $values)); return queries("REPLACE INTO " . table($table) . " (" . implode(", ", array_keys(reset($rows))) . ") VALUES\n" . implode(",\n", $values));
} }
function tableHelp($name) { function tableHelp($name, $is_view = false) {
if ($name == "sqlite_sequence") { if ($name == "sqlite_sequence") {
return "fileformat2.html#seqtab"; return "fileformat2.html#seqtab";
} }
@@ -227,6 +174,10 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
} }
} }
function checkConstraints($table) {
preg_match_all('~ CHECK *(\( *(((?>[^()]*[^() ])|(?1))*) *\))~', $this->_conn->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table)), $matches); //! could be inside a comment
return array_combine($matches[2], $matches[2]);
}
} }
@@ -239,13 +190,12 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return idf_escape($idf); return idf_escape($idf);
} }
function connect() { function connect($credentials) {
global $adminer; list(, , $password) = $credentials;
list(, , $password) = $adminer->credentials();
if ($password != "") { if ($password != "") {
return lang('Database does not support password.'); return lang('Database does not support password.');
} }
return new Min_DB; return new Db;
} }
function get_databases() { function get_databases() {
@@ -311,7 +261,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
global $connection; global $connection;
$return = array(); $return = array();
$primary = ""; $primary = "";
foreach (get_rows("PRAGMA table_info(" . table($table) . ")") as $row) { foreach (get_rows("PRAGMA table_" . (min_version(3.31) ? "x" : "") . "info(" . table($table) . ")") as $row) {
$name = $row["name"]; $name = $row["name"];
$type = strtolower($row["type"]); $type = strtolower($row["type"]);
$default = $row["dflt_value"]; $default = $row["dflt_value"];
@@ -319,7 +269,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
"field" => $name, "field" => $name,
"type" => (preg_match('~int~i', $type) ? "integer" : (preg_match('~char|clob|text~i', $type) ? "text" : (preg_match('~blob~i', $type) ? "blob" : (preg_match('~real|floa|doub~i', $type) ? "real" : "numeric")))), "type" => (preg_match('~int~i', $type) ? "integer" : (preg_match('~char|clob|text~i', $type) ? "text" : (preg_match('~blob~i', $type) ? "blob" : (preg_match('~real|floa|doub~i', $type) ? "real" : "numeric")))),
"full_type" => $type, "full_type" => $type,
"default" => (preg_match("~'(.*)'~", $default, $match) ? str_replace("''", "'", $match[1]) : ($default == "NULL" ? null : $default)), "default" => (preg_match("~^'(.*)'$~", $default, $match) ? str_replace("''", "'", $match[1]) : ($default == "NULL" ? null : $default)),
"null" => !$row["notnull"], "null" => !$row["notnull"],
"privileges" => array("select" => 1, "insert" => 1, "update" => 1), "privileges" => array("select" => 1, "insert" => 1, "update" => 1),
"primary" => $row["pk"], "primary" => $row["pk"],
@@ -334,13 +284,20 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
} }
} }
$sql = $connection->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table)); $sql = $connection->result("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = " . q($table));
preg_match_all('~(("[^"]*+")+|[a-z0-9_]+)\s+text\s+COLLATE\s+(\'[^\']+\'|\S+)~i', $sql, $matches, PREG_SET_ORDER); $idf = '(("[^"]*+")+|[a-z0-9_]+)';
preg_match_all('~' . $idf . '\s+text\s+COLLATE\s+(\'[^\']+\'|\S+)~i', $sql, $matches, PREG_SET_ORDER);
foreach ($matches as $match) { foreach ($matches as $match) {
$name = str_replace('""', '"', preg_replace('~^"|"$~', '', $match[1])); $name = str_replace('""', '"', preg_replace('~^"|"$~', '', $match[1]));
if ($return[$name]) { if ($return[$name]) {
$return[$name]["collation"] = trim($match[3], "'"); $return[$name]["collation"] = trim($match[3], "'");
} }
} }
preg_match_all('~' . $idf . '\s.*GENERATED ALWAYS AS \((.+)\) (STORED|VIRTUAL)~i', $sql, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$name = str_replace('""', '"', preg_replace('~^"|"$~', '', $match[1]));
$return[$name]["default"] = $match[3];
$return[$name]["generated"] = strtoupper($match[4]);
}
return $return; return $return;
} }
@@ -395,7 +352,6 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
$return = array(); $return = array();
foreach (get_rows("PRAGMA foreign_key_list(" . table($table) . ")") as $row) { foreach (get_rows("PRAGMA foreign_key_list(" . table($table) . ")") as $row) {
$foreign_key = &$return[$row["id"]]; $foreign_key = &$return[$row["id"]];
//! idf_unescape in SQLite2
if (!$foreign_key) { if (!$foreign_key) {
$foreign_key = $row; $foreign_key = $row;
} }
@@ -407,7 +363,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
function view($name) { function view($name) {
global $connection; 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 [] return array("select" => preg_replace('~^(?:[^`"[]+|`[^`]*`|"[^"]*")* AS\s+~iU', '', $connection->result("SELECT sql FROM sqlite_master WHERE type = 'view' AND name = " . q($name)))); //! identifiers may be inside []
} }
function collations() { function collations() {
@@ -444,7 +400,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return false; return false;
} }
try { try {
$link = new Min_SQLite($db); $link = new SqliteDb($db);
} catch (Exception $ex) { } catch (Exception $ex) {
$connection->error = $ex->getMessage(); $connection->error = $ex->getMessage();
return false; return false;
@@ -478,7 +434,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
} }
function auto_increment() { function auto_increment() {
return " PRIMARY KEY" . (DRIVER == "sqlite" ? " AUTOINCREMENT" : ""); return " PRIMARY KEY AUTOINCREMENT";
} }
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) { function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
@@ -523,8 +479,20 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return true; return true;
} }
function recreate_table($table, $name, $fields, $originals, $foreign, $auto_increment, $indexes = array()) { /** Recreate table
global $connection; * @param string original name
* @param string new name
* @param array [process_field()], empty to preserve
* @param array [$original => idf_escape($new_column)], empty to preserve
* @param string [format_foreign_key()], empty to preserve
* @param int set auto_increment to this value, 0 to preserve
* @param array [[$type, $name, $columns]], empty to preserve
* @param string CHECK constraint to drop
* @param string CHECK constraint to add
* @return bool
*/
function recreate_table($table, $name, $fields, $originals, $foreign, $auto_increment = 0, $indexes = array(), $drop_check = "", $add_check = "") {
global $connection, $driver;
if ($table != "") { if ($table != "") {
if (!$fields) { if (!$fields) {
foreach (fields($table) as $key => $field) { foreach (fields($table) as $key => $field) {
@@ -582,16 +550,27 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
queries("BEGIN"); queries("BEGIN");
} }
foreach ($fields as $key => $field) { foreach ($fields as $key => $field) {
if (preg_match('~GENERATED~', $field[3])) {
unset($originals[array_search($field[0], $originals)]);
}
$fields[$key] = " " . implode($field); $fields[$key] = " " . implode($field);
} }
$fields = array_merge($fields, array_filter($foreign)); $fields = array_merge($fields, array_filter($foreign));
foreach ($driver->checkConstraints($table) as $check) {
if ($check != $drop_check) {
$fields[] = " CHECK ($check)";
}
}
if ($add_check) {
$fields[] = " CHECK ($add_check)";
}
$temp_name = ($table == $name ? "adminer_$name" : $name); $temp_name = ($table == $name ? "adminer_$name" : $name);
if (!queries("CREATE TABLE " . table($temp_name) . " (\n" . implode(",\n", $fields) . "\n)")) { if (!queries("CREATE TABLE " . table($temp_name) . " (\n" . implode(",\n", $fields) . "\n)")) {
// implicit ROLLBACK to not overwrite $connection->error // implicit ROLLBACK to not overwrite $connection->error
return false; return false;
} }
if ($table != "") { if ($table != "") {
if ($originals && !queries("INSERT INTO " . table($temp_name) . " (" . implode(", ", $originals) . ") SELECT " . implode(", ", array_map('idf_escape', array_keys($originals))) . " FROM " . table($table))) { if ($originals && !queries("INSERT INTO " . table($temp_name) . " (" . implode(", ", $originals) . ") SELECT " . implode(", ", array_map('Adminer\idf_escape', array_keys($originals))) . " FROM " . table($table))) {
return false; return false;
} }
$triggers = array(); $triggers = array();
@@ -600,7 +579,8 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
$triggers[] = "CREATE TRIGGER " . idf_escape($trigger_name) . " " . implode(" ", $timing_event) . " ON " . table($name) . "\n$trigger[Statement]"; $triggers[] = "CREATE TRIGGER " . idf_escape($trigger_name) . " " . implode(" ", $timing_event) . " ON " . table($name) . "\n$trigger[Statement]";
} }
$auto_increment = $auto_increment ? 0 : $connection->result("SELECT seq FROM sqlite_sequence WHERE name = " . q($table)); // if $auto_increment is set then it will be updated later $auto_increment = $auto_increment ? 0 : $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 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))) || ($table == $name && !queries("ALTER TABLE " . table($temp_name) . " RENAME TO " . table($name)))
|| !alter_indexes($name, $indexes) || !alter_indexes($name, $indexes)
) { ) {
@@ -634,10 +614,11 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
} }
} }
foreach (array_reverse($alter) as $val) { foreach (array_reverse($alter) as $val) {
if (!queries($val[2] == "DROP" if (
!queries($val[2] == "DROP"
? "DROP INDEX " . idf_escape($val[1]) ? "DROP INDEX " . idf_escape($val[1])
: index_sql($table, $val[0], $val[1], "(" . implode(", ", $val[2]) . ")") : index_sql($table, $val[0], $val[1], "(" . implode(", ", $val[2]) . ")"))
)) { ) {
return false; return false;
} }
} }
@@ -676,7 +657,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return array( return array(
"Timing" => strtoupper($match[1]), "Timing" => strtoupper($match[1]),
"Event" => strtoupper($match[2]) . ($of ? " OF" : ""), "Event" => strtoupper($match[2]) . ($of ? " OF" : ""),
"Of" => ($of[0] == '`' || $of[0] == '"' ? idf_unescape($of) : $of), "Of" => idf_unescape($of),
"Trigger" => $name, "Trigger" => $name,
"Statement" => $match[4], "Statement" => $match[4],
); );
@@ -720,18 +701,6 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return array(); return array();
} }
function schemas() {
return array();
}
function get_schema() {
return "";
}
function set_schema($scheme) {
return true;
}
function create_sql($table, $auto_increment, $style) { function create_sql($table, $auto_increment, $style) {
global $connection; global $connection;
$return = $connection->result("SELECT sql FROM sqlite_master WHERE type IN ('table', 'view') AND name = " . q($table)); $return = $connection->result("SELECT sql FROM sqlite_master WHERE type IN ('table', 'view') AND name = " . q($table));
@@ -739,7 +708,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
if ($name == '') { if ($name == '') {
continue; continue;
} }
$return .= ";\n\n" . index_sql($table, $index['type'], $name, "(" . implode(", ", array_map('idf_escape', $index['columns'])) . ")"); $return .= ";\n\n" . index_sql($table, $index['type'], $name, "(" . implode(", ", array_map('Adminer\idf_escape', $index['columns'])) . ")");
} }
return $return; return $return;
} }
@@ -756,10 +725,14 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
} }
function show_variables() { function show_variables() {
global $connection;
$return = array(); $return = array();
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) { foreach (get_rows("PRAGMA pragma_list") as $row) {
$return[$key] = $connection->result("PRAGMA $key"); $name = $row["name"];
if ($name != "pragma_list" && $name != "compile_options") {
foreach (get_rows("PRAGMA $name") as $row) {
$return[$name] .= implode(", ", $row) . "\n";
}
}
} }
return $return; return $return;
} }
@@ -781,23 +754,6 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
} }
function support($feature) { function support($feature) {
return preg_match('~^(columns|database|drop_col|dump|indexes|descidx|move_col|sql|status|table|trigger|variables|view|view_trigger)$~', $feature); return preg_match('~^(check|columns|database|drop_col|dump|indexes|descidx|move_col|sql|status|table|trigger|variables|view|view_trigger)$~', $feature);
} }
$jush = "sqlite";
$types = array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0);
$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,28 +1,32 @@
<?php <?php
namespace Adminer;
$TABLE = $_GET["dump"]; $TABLE = $_GET["dump"];
if ($_POST && !$error) { if ($_POST && !$error) {
$cookie = ""; $cookie = "";
foreach (array("output", "format", "db_style", "routines", "events", "table_style", "auto_increment", "triggers", "data_style") as $key) { foreach (array("output", "format", "db_style", "types", "routines", "events", "table_style", "auto_increment", "triggers", "data_style") as $key) {
$cookie .= "&$key=" . urlencode($_POST[$key]); $cookie .= "&$key=" . urlencode($_POST[$key]);
} }
cookie("adminer_export", substr($cookie, 1)); cookie("adminer_export", substr($cookie, 1));
$tables = array_flip((array) $_POST["tables"]) + array_flip((array) $_POST["data"]); $tables = array_flip((array) $_POST["tables"]) + array_flip((array) $_POST["data"]);
$ext = dump_headers( $ext = dump_headers(
(count($tables) == 1 ? key($tables) : DB), (count($tables) == 1 ? key($tables) : DB),
(DB == "" || count($tables) > 1)); (DB == "" || count($tables) > 1)
);
$is_sql = preg_match('~sql~', $_POST["format"]); $is_sql = preg_match('~sql~', $_POST["format"]);
if ($is_sql) { if ($is_sql) {
echo "-- Adminer $VERSION " . $drivers[DRIVER] . " dump\n\n"; echo "-- Adminer $VERSION " . $drivers[DRIVER] . " " . str_replace("\n", " ", $connection->server_info) . " dump\n\n";
if ($jush == "sql") { if (JUSH == "sql") {
echo "SET NAMES utf8; echo "SET NAMES utf8;
SET time_zone = '+00:00'; SET time_zone = '+00:00';
" . ($_POST["data_style"] ? "SET foreign_key_checks = 0; SET foreign_key_checks = 0;
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'; " . ($_POST["data_style"] ? "SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
" : "") . " " : "") . "
"; ";
$connection->query("SET time_zone = '+00:00';"); $connection->query("SET time_zone = '+00:00'");
$connection->query("SET sql_mode = ''");
} }
} }
@@ -51,16 +55,28 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
} }
$out = ""; $out = "";
if ($_POST["routines"]) { if ($_POST["types"]) {
foreach (array("FUNCTION", "PROCEDURE") as $routine) { foreach (types() as $id => $type) {
foreach (get_rows("SHOW $routine STATUS WHERE Db = " . q($db), null, "-- ") as $row) { $enums = type_values($id);
$create = remove_definer($connection->result("SHOW CREATE $routine " . idf_escape($row["Name"]), 2)); if ($enums) {
set_utf8mb4($create); $out .= ($style != 'DROP+CREATE' ? "DROP TYPE IF EXISTS " . idf_escape($type) . ";;\n" : "") . "CREATE TYPE " . idf_escape($type) . " AS ENUM ($enums);\n\n";
$out .= ($style != 'DROP+CREATE' ? "DROP $routine IF EXISTS " . idf_escape($row["Name"]) . ";;\n" : "") . "$create;;\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";
}
}
if ($_POST["events"]) { if ($_POST["events"]) {
foreach (get_rows("SHOW EVENTS", null, "-- ") as $row) { foreach (get_rows("SHOW EVENTS", null, "-- ") as $row) {
$create = remove_definer($connection->result("SHOW CREATE EVENT " . idf_escape($row["Name"]), 3)); $create = remove_definer($connection->result("SHOW CREATE EVENT " . idf_escape($row["Name"]), 3));
@@ -69,9 +85,7 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
} }
} }
if ($out) { echo ($out && JUSH == 'sql' ? "DELIMITER ;;\n\n$out" . "DELIMITER ;\n\n" : $out);
echo "DELIMITER ;;\n\n$out" . "DELIMITER ;\n\n";
}
} }
if ($_POST["table_style"] || $_POST["data_style"]) { if ($_POST["table_style"] || $_POST["data_style"]) {
@@ -105,6 +119,16 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
} }
} }
// add FKs after creating tables (except in MySQL which uses SET FOREIGN_KEY_CHECKS=0)
if (function_exists('Adminer\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)) {
echo foreign_keys_sql($name);
}
}
}
foreach ($views as $view) { foreach ($views as $view) {
$adminer->dumpTable($view, $_POST["table_style"], 1); $adminer->dumpTable($view, $_POST["table_style"], 1);
} }
@@ -117,7 +141,7 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
} }
if ($is_sql) { if ($is_sql) {
echo "-- " . $connection->result("SELECT NOW()") . "\n"; echo "-- " . gmdate("Y-m-d H:i:s e") . "\n";
} }
exit; exit;
} }
@@ -126,12 +150,12 @@ page_header(lang('Export'), $error, ($_GET["export"] != "" ? array("table" => $_
?> ?>
<form action="" method="post"> <form action="" method="post">
<table cellspacing="0" class="layout"> <table class="layout">
<?php <?php
$db_style = array('', 'USE', 'DROP+CREATE', 'CREATE'); $db_style = array('', 'USE', 'DROP+CREATE', 'CREATE');
$table_style = array('', 'DROP+CREATE', 'CREATE'); $table_style = array('', 'DROP+CREATE', 'CREATE');
$data_style = array('', 'TRUNCATE+INSERT', 'INSERT'); $data_style = array('', 'TRUNCATE+INSERT', 'INSERT');
if ($jush == "sql") { //! use insertUpdate() in all drivers if (JUSH == "sql") { //! use insertUpdate() in all drivers
$data_style[] = 'INSERT+UPDATE'; $data_style[] = 'INSERT+UPDATE';
} }
parse_str($_COOKIE["adminer_export"], $row); parse_str($_COOKIE["adminer_export"], $row);
@@ -147,7 +171,8 @@ echo "<tr><th>" . lang('Output') . "<td>" . html_select("output", $adminer->dump
echo "<tr><th>" . lang('Format') . "<td>" . html_select("format", $adminer->dumpFormat(), $row["format"], 0) . "\n"; // 0 - radio echo "<tr><th>" . lang('Format') . "<td>" . html_select("format", $adminer->dumpFormat(), $row["format"], 0) . "\n"; // 0 - radio
echo ($jush == "sqlite" ? "" : "<tr><th>" . lang('Database') . "<td>" . html_select('db_style', $db_style, $row["db_style"]) echo (JUSH == "sqlite" ? "" : "<tr><th>" . lang('Database') . "<td>" . html_select('db_style', $db_style, $row["db_style"])
. (support("type") ? checkbox("types", 1, $row["types"], lang('User types')) : "")
. (support("routine") ? checkbox("routines", 1, $row["routines"], lang('Routines')) : "") . (support("routine") ? checkbox("routines", 1, $row["routines"], lang('Routines')) : "")
. (support("event") ? checkbox("events", 1, $row["events"], lang('Events')) : "") . (support("event") ? checkbox("events", 1, $row["events"], lang('Events')) : "")
); );
@@ -163,7 +188,7 @@ echo "<tr><th>" . lang('Data') . "<td>" . html_select('data_style', $data_style,
<p><input type="submit" value="<?php echo lang('Export'); ?>"> <p><input type="submit" value="<?php echo lang('Export'); ?>">
<input type="hidden" name="token" value="<?php echo $token; ?>"> <input type="hidden" name="token" value="<?php echo $token; ?>">
<table cellspacing="0"> <table>
<?php <?php
echo script("qsl('table').onclick = dumpClick;"); echo script("qsl('table').onclick = dumpClick;");
$prefixes = array(); $prefixes = array();

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$TABLE = $_GET["edit"]; $TABLE = $_GET["edit"];
$fields = fields($TABLE); $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));
@@ -70,7 +72,7 @@ if ($_POST["save"]) {
if ($_POST["clone"] && $field["auto_increment"]) { if ($_POST["clone"] && $field["auto_increment"]) {
$as = "''"; $as = "''";
} }
if ($jush == "sql" && preg_match("~enum|set~", $field["type"])) { if (JUSH == "sql" && preg_match("~enum|set~", $field["type"])) {
$as = "1*" . idf_escape($name); $as = "1*" . idf_escape($name);
} }
$select[] = ($as ? "$as AS " : "") . idf_escape($name); $select[] = ($as ? "$as AS " : "") . idf_escape($name);

9
adminer/elastic.php Normal file
View File

@@ -0,0 +1,9 @@
<?php
// To create Adminer just for Elasticsearch, run `../compile.php elastic`.
function adminer_object() {
include_once "../plugins/drivers/elastic.php";
return new Adminer\Adminer;
}
include "./index.php";

View File

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

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
// caching headers added in compile.php // caching headers added in compile.php
if ($_GET["file"] == "favicon.ico") { if ($_GET["file"] == "favicon.ico") {
@@ -12,15 +14,34 @@ if ($_GET["file"] == "favicon.ico") {
echo lzw_decompress(compile_file('../adminer/static/functions.js;static/editing.js', 'minify_js')); echo lzw_decompress(compile_file('../adminer/static/functions.js;static/editing.js', 'minify_js'));
} elseif ($_GET["file"] == "jush.js") { } elseif ($_GET["file"] == "jush.js") {
header("Content-Type: text/javascript; charset=utf-8"); header("Content-Type: text/javascript; charset=utf-8");
echo lzw_decompress(compile_file('../externals/jush/modules/jush.js;../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')); echo lzw_decompress(compile_file('../externals/jush/modules/jush.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'));
} else { } else {
header("Content-Type: image/gif"); header("Content-Type: image/gif");
switch ($_GET["file"]) { switch ($_GET["file"]) {
case "plus.gif": echo compile_file('../adminer/static/plus.gif'); break; case "plus.gif":
case "cross.gif": echo compile_file('../adminer/static/cross.gif'); break; echo compile_file('../adminer/static/plus.gif');
case "up.gif": echo compile_file('../adminer/static/up.gif'); break; break;
case "down.gif": echo compile_file('../adminer/static/down.gif'); break; case "cross.gif":
case "arrow.gif": echo compile_file('../adminer/static/arrow.gif'); break; 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; exit;

View File

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

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
// any method change in this file should be transferred to editor/include/adminer.inc.php and plugins/plugin.php // any method change in this file should be transferred to editor/include/adminer.inc.php and plugins/plugin.php
class Adminer { class Adminer {
@@ -13,14 +15,14 @@ class Adminer {
} }
/** Connection parameters /** Connection parameters
* @return array ($server, $username, $password) * @return array [$server, $username, $password]
*/ */
function credentials() { function credentials() {
return array(SERVER, $_GET["username"], get_password()); return array(SERVER, $_GET["username"], get_password());
} }
/** Get SSL connection options /** Get SSL connection options
* @return array array("key" => filename, "cert" => filename, "ca" => filename) or null * @return array ["key" => filename, "cert" => filename, "ca" => filename] or null
*/ */
function connectSsl() { function connectSsl() {
} }
@@ -118,12 +120,12 @@ class Adminer {
*/ */
function loginForm() { function loginForm() {
global $drivers; global $drivers;
echo "<table cellspacing='0' class='layout'>\n"; echo "<table class='layout'>\n";
echo $this->loginFormField('driver', '<tr><th>' . lang('System') . '<td>', html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);") . "\n"); echo $this->loginFormField('driver', '<tr><th>' . lang('System') . '<td>', html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);"));
echo $this->loginFormField('server', '<tr><th>' . lang('Server') . '<td>', '<input name="auth[server]" value="' . h(SERVER) . '" title="hostname[:port]" placeholder="localhost" autocapitalize="off">' . "\n"); echo $this->loginFormField('server', '<tr><th>' . lang('Server') . '<td>', '<input name="auth[server]" value="' . h(SERVER) . '" title="hostname[:port]" placeholder="localhost" autocapitalize="off">');
echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocomplete="username" autocapitalize="off">' . script("focus(qs('#username')); qs('#username').form['auth[driver]'].onchange();")); echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input name="auth[username]" id="username" autofocus value="' . h($_GET["username"]) . '" autocomplete="username" autocapitalize="off">' . script("qs('#username').form['auth[driver]'].onchange();"));
echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td>', '<input type="password" name="auth[password]" autocomplete="current-password">' . "\n"); echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td>', '<input type="password" name="auth[password]" autocomplete="current-password">');
echo $this->loginFormField('db', '<tr><th>' . lang('Database') . '<td>', '<input name="auth[db]" value="' . h($_GET["db"]) . '" autocapitalize="off">' . "\n"); echo $this->loginFormField('db', '<tr><th>' . lang('Database') . '<td>', '<input name="auth[db]" value="' . h($_GET["db"]) . '" autocapitalize="off">');
echo "</table>\n"; echo "</table>\n";
echo "<p><input type='submit' value='" . lang('Login') . "'>\n"; echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
echo checkbox("auth[permanent]", 1, $_COOKIE["adminer_permanent"], lang('Permanent login')) . "\n"; echo checkbox("auth[permanent]", 1, $_COOKIE["adminer_permanent"], lang('Permanent login')) . "\n";
@@ -136,7 +138,7 @@ class Adminer {
* @return string * @return string
*/ */
function loginFormField($name, $heading, $value) { function loginFormField($name, $heading, $value) {
return $heading . $value; return $heading . $value . "\n";
} }
/** Authorize the user /** Authorize the user
@@ -174,14 +176,16 @@ class Adminer {
* @return null * @return null
*/ */
function selectLinks($tableStatus, $set = "") { function selectLinks($tableStatus, $set = "") {
global $jush, $driver; global $driver;
echo '<p class="links">'; echo '<p class="links">';
$links = array("select" => lang('Select data')); $links = array("select" => lang('Select data'));
if (support("table") || support("indexes")) { if (support("table") || support("indexes")) {
$links["table"] = lang('Show structure'); $links["table"] = lang('Show structure');
} }
$is_view = false;
if (support("table")) { if (support("table")) {
if (is_view($tableStatus)) { $is_view = is_view($tableStatus);
if ($is_view) {
$links["view"] = lang('Alter view'); $links["view"] = lang('Alter view');
} else { } else {
$links["create"] = lang('Alter table'); $links["create"] = lang('Alter table');
@@ -194,7 +198,7 @@ class Adminer {
foreach ($links as $key => $val) { foreach ($links as $key => $val) {
echo " <a href='" . h(ME) . "$key=" . urlencode($name) . ($key == "edit" ? $set : "") . "'" . bold(isset($_GET[$key])) . ">$val</a>"; echo " <a href='" . h(ME) . "$key=" . urlencode($name) . ($key == "edit" ? $set : "") . "'" . bold(isset($_GET[$key])) . ">$val</a>";
} }
echo doc_link(array($jush => $driver->tableHelp($name)), "?"); echo doc_link(array(JUSH => $driver->tableHelp($name, $is_view)), "?");
echo "\n"; echo "\n";
} }
@@ -230,7 +234,7 @@ class Adminer {
* @return string * @return string
*/ */
function selectQuery($query, $start, $failed = false) { function selectQuery($query, $start, $failed = false) {
global $jush, $driver; global $driver;
$return = "</p>\n"; // required for IE9 inline edit $return = "</p>\n"; // required for IE9 inline edit
if (!$failed && ($warnings = $driver->warnings())) { if (!$failed && ($warnings = $driver->warnings())) {
$id = "warnings"; $id = "warnings";
@@ -238,7 +242,7 @@ class Adminer {
. "$return<div id='$id' class='hidden'>\n$warnings</div>\n" . "$return<div id='$id' class='hidden'>\n$warnings</div>\n"
; ;
} }
return "<p><code class='jush-$jush'>" . h(str_replace("\n", " ", $query)) . "</code> <span class='time'>(" . format_time($start) . ")</span>" return "<p><code class='jush-" . JUSH . "'>" . h(str_replace("\n", " ", $query)) . "</code> <span class='time'>(" . format_time($start) . ")</span>"
. (support("sql") ? " <a href='" . h(ME) . "sql=" . urlencode($query) . "'>" . lang('Edit') . "</a>" : "") . (support("sql") ? " <a href='" . h(ME) . "sql=" . urlencode($query) . "'>" . lang('Edit') . "</a>" : "")
. $return . $return
; ;
@@ -248,8 +252,7 @@ class Adminer {
* @param string query to be executed * @param string query to be executed
* @return string escaped query to be printed * @return string escaped query to be printed
*/ */
function sqlCommandQuery($query) function sqlCommandQuery($query) {
{
return shorten_utf8(trim($query), 1000); return shorten_utf8(trim($query), 1000);
} }
@@ -310,15 +313,22 @@ class Adminer {
* @return null * @return null
*/ */
function tableStructurePrint($fields) { function tableStructurePrint($fields) {
global $driver;
echo "<div class='scrollable'>\n"; echo "<div class='scrollable'>\n";
echo "<table cellspacing='0' class='nowrap'>\n"; echo "<table class='nowrap odds'>\n";
echo "<thead><tr><th>" . lang('Column') . "<td>" . lang('Type') . (support("comment") ? "<td>" . lang('Comment') : "") . "</thead>\n"; echo "<thead><tr><th>" . lang('Column') . "<td>" . lang('Type') . (support("comment") ? "<td>" . lang('Comment') : "") . "</thead>\n";
$structured_types = $driver->structuredTypes();
foreach ($fields as $field) { foreach ($fields as $field) {
echo "<tr" . odd() . "><th>" . h($field["field"]); echo "<tr><th>" . h($field["field"]);
echo "<td><span title='" . h($field["collation"]) . "'>" . h($field["full_type"]) . "</span>"; $type = h($field["full_type"]);
echo "<td><span title='" . h($field["collation"]) . "'>"
. (in_array($type, (array) $structured_types[lang('User types')]) ? "<a href='" . h(ME . 'type=' . urlencode($type)) . "'>$type</a>" : $type)
. "</span>"
;
echo ($field["null"] ? " <i>NULL</i>" : ""); echo ($field["null"] ? " <i>NULL</i>" : "");
echo ($field["auto_increment"] ? " <i>" . lang('Auto Increment') . "</i>" : ""); echo ($field["auto_increment"] ? " <i>" . lang('Auto Increment') . "</i>" : "");
echo (isset($field["default"]) ? " <span title='" . lang('Default value') . "'>[<b>" . h($field["default"]) . "</b>]</span>" : ""); $default = h($field["default"]);
echo (isset($field["default"]) ? " <span title='" . lang('Default value') . "'>[<b>" . ($field["generated"] ? "<code class='jush-" . JUSH . "'>$default</code>" : $default) . "</b>]</span>" : "");
echo (support("comment") ? "<td>" . h($field["comment"]) : ""); echo (support("comment") ? "<td>" . h($field["comment"]) : "");
echo "\n"; echo "\n";
} }
@@ -331,7 +341,7 @@ class Adminer {
* @return null * @return null
*/ */
function tableIndexesPrint($indexes) { function tableIndexesPrint($indexes) {
echo "<table cellspacing='0'>\n"; echo "<table>\n";
foreach ($indexes as $name => $index) { foreach ($indexes as $name => $index) {
ksort($index["columns"]); // enforce correct columns order ksort($index["columns"]); // enforce correct columns order
$print = array(); $print = array();
@@ -352,7 +362,7 @@ class Adminer {
* @return null * @return null
*/ */
function selectColumnsPrint($select, $columns) { function selectColumnsPrint($select, $columns) {
global $functions, $grouping; global $driver;
print_fieldset("select", lang('Select'), $select); print_fieldset("select", lang('Select'), $select);
$i = 0; $i = 0;
$select[""] = array(); $select[""] = array();
@@ -364,8 +374,8 @@ class Adminer {
$val["col"], $val["col"],
($key !== "" ? "selectFieldChange" : "selectAddRow") ($key !== "" ? "selectFieldChange" : "selectAddRow")
); );
echo "<div>" . ($functions || $grouping ? "<select name='columns[$i][fun]'>" echo "<div>" . ($driver->functions || $driver->grouping ? "<select name='columns[$i][fun]'>"
. optionlist(array(-1 => "") + array_filter(array(lang('Functions') => $functions, lang('Aggregation') => $grouping)), $val["fun"]) . "</select>" . optionlist(array(-1 => "") + array_filter(array(lang('Functions') => $driver->functions, lang('Aggregation') => $driver->grouping)), $val["fun"]) . "</select>"
. on_help("getTarget(event).value && getTarget(event).value.replace(/ |\$/, '(') + ')'", 1) . on_help("getTarget(event).value && getTarget(event).value.replace(/ |\$/, '(') + ')'", 1)
. script("qsl('select').onchange = function () { helpClose();" . ($key !== "" ? "" : " qsl('select, input', this.parentNode).onchange();") . " };", "") . script("qsl('select').onchange = function () { helpClose();" . ($key !== "" ? "" : " qsl('select, input', this.parentNode).onchange();") . " };", "")
. "($column)" : $column) . "</div>\n"; . "($column)" : $column) . "</div>\n";
@@ -384,7 +394,7 @@ class Adminer {
print_fieldset("search", lang('Search'), $where); print_fieldset("search", lang('Search'), $where);
foreach ($indexes as $i => $index) { foreach ($indexes as $i => $index) {
if ($index["type"] == "FULLTEXT") { if ($index["type"] == "FULLTEXT") {
echo "<div>(<i>" . implode("</i>, <i>", array_map('h', $index["columns"])) . "</i>) AGAINST"; echo "<div>(<i>" . implode("</i>, <i>", array_map('Adminer\h', $index["columns"])) . "</i>) AGAINST";
echo " <input type='search' name='fulltext[$i]' value='" . h($_GET["fulltext"][$i]) . "'>"; echo " <input type='search' name='fulltext[$i]' value='" . h($_GET["fulltext"][$i]) . "'>";
echo script("qsl('input').oninput = selectFieldChange;", ""); echo script("qsl('input').oninput = selectFieldChange;", "");
echo checkbox("boolean[$i]", 1, isset($_GET["boolean"][$i]), "BOOL"); echo checkbox("boolean[$i]", 1, isset($_GET["boolean"][$i]), "BOOL");
@@ -506,16 +516,16 @@ class Adminer {
/** Process columns box in select /** Process columns box in select
* @param array selectable columns * @param array selectable columns
* @param array * @param array
* @return array (array(select_expressions), array(group_expressions)) * @return array [[select_expressions], [group_expressions]]
*/ */
function selectColumnsProcess($columns, $indexes) { function selectColumnsProcess($columns, $indexes) {
global $functions, $grouping; global $driver;
$select = array(); // select expressions, empty for * $select = array(); // select expressions, empty for *
$group = array(); // expressions without aggregation - will be used for GROUP BY if an aggregation function is used $group = array(); // expressions without aggregation - will be used for GROUP BY if an aggregation function is used
foreach ((array) $_GET["columns"] as $key => $val) { foreach ((array) $_GET["columns"] as $key => $val) {
if ($val["fun"] == "count" || ($val["col"] != "" && (!$val["fun"] || in_array($val["fun"], $functions) || in_array($val["fun"], $grouping)))) { if ($val["fun"] == "count" || ($val["col"] != "" && (!$val["fun"] || in_array($val["fun"], $driver->functions) || in_array($val["fun"], $driver->grouping)))) {
$select[$key] = apply_sql_function($val["fun"], ($val["col"] != "" ? idf_escape($val["col"]) : "*")); $select[$key] = apply_sql_function($val["fun"], ($val["col"] != "" ? idf_escape($val["col"]) : "*"));
if (!in_array($val["fun"], $grouping)) { if (!in_array($val["fun"], $driver->grouping)) {
$group[] = $select[$key]; $group[] = $select[$key];
} }
} }
@@ -533,7 +543,7 @@ class Adminer {
$return = array(); $return = array();
foreach ($indexes as $i => $index) { foreach ($indexes as $i => $index) {
if ($index["type"] == "FULLTEXT" && $_GET["fulltext"][$i] != "") { if ($index["type"] == "FULLTEXT" && $_GET["fulltext"][$i] != "") {
$return[] = "MATCH (" . implode(", ", array_map('idf_escape', $index["columns"])) . ") AGAINST (" . q($_GET["fulltext"][$i]) . (isset($_GET["boolean"][$i]) ? " IN BOOLEAN MODE" : "") . ")"; $return[] = "MATCH (" . implode(", ", array_map('Adminer\idf_escape', $index["columns"])) . ") AGAINST (" . q($_GET["fulltext"][$i]) . (isset($_GET["boolean"][$i]) ? " IN BOOLEAN MODE" : "") . ")";
} }
} }
foreach ((array) $_GET["where"] as $key => $val) { foreach ((array) $_GET["where"] as $key => $val) {
@@ -561,8 +571,10 @@ class Adminer {
// find anywhere // find anywhere
$cols = array(); $cols = array();
foreach ($fields as $name => $field) { foreach ($fields as $name => $field) {
if ((preg_match('~^[-\d.' . (preg_match('~IN$~', $val["op"]) ? ',' : '') . ']+$~', $val["val"]) || !preg_match('~' . number_type() . '|bit~', $field["type"])) if (
(preg_match('~^[-\d.' . (preg_match('~IN$~', $val["op"]) ? ',' : '') . ']+$~', $val["val"]) || !preg_match('~' . number_type() . '|bit~', $field["type"]))
&& (!preg_match("~[\x80-\xFF]~", $val["val"]) || preg_match('~char|text|enum|set~', $field["type"])) && (!preg_match("~[\x80-\xFF]~", $val["val"]) || preg_match('~char|text|enum|set~', $field["type"]))
&& (!preg_match('~date|timestamp~', $field["type"]) || preg_match('~^\d+-\d+-\d+~', $val["val"]))
) { ) {
$cols[] = $prefix . $driver->convertSearch(idf_escape($name), $val, $field) . $cond; $cols[] = $prefix . $driver->convertSearch(idf_escape($name), $val, $field) . $cond;
} }
@@ -634,7 +646,7 @@ class Adminer {
* @return string * @return string
*/ */
function messageQuery($query, $time, $failed = false) { function messageQuery($query, $time, $failed = false) {
global $jush, $driver; global $driver;
restart_session(); restart_session();
$history = &get_session("queries"); $history = &get_session("queries");
if (!$history[$_GET["db"]]) { if (!$history[$_GET["db"]]) {
@@ -651,33 +663,44 @@ class Adminer {
$return = "<a href='#$id' class='toggle'>" . lang('Warnings') . "</a>, $return<div id='$id' class='hidden'>\n$warnings</div>\n"; $return = "<a href='#$id' class='toggle'>" . lang('Warnings') . "</a>, $return<div id='$id' class='hidden'>\n$warnings</div>\n";
} }
return " <span class='time'>" . @date("H:i:s") . "</span>" // @ - time zone may be not set return " <span class='time'>" . @date("H:i:s") . "</span>" // @ - time zone may be not set
. " $return<div id='$sql_id' class='hidden'><pre><code class='jush-$jush'>" . shorten_utf8($query, 1000) . "</code></pre>" . " $return<div id='$sql_id' class='hidden'><pre><code class='jush-" . JUSH . "'>" . shorten_utf8($query, 1000) . "</code></pre>"
. ($time ? " <span class='time'>($time)</span>" : '') . ($time ? " <span class='time'>($time)</span>" : '')
. (support("sql") ? '<p><a href="' . h(str_replace("db=" . urlencode(DB), "db=" . urlencode($_GET["db"]), ME) . 'sql=&history=' . (count($history[$_GET["db"]]) - 1)) . '">' . lang('Edit') . '</a>' : '') . (support("sql") ? '<p><a href="' . h(str_replace("db=" . urlencode(DB), "db=" . urlencode($_GET["db"]), ME) . 'sql=&history=' . (count($history[$_GET["db"]]) - 1)) . '">' . lang('Edit') . '</a>' : '')
. '</div>' . '</div>'
; ;
} }
/** Print before edit form
* @param string
* @param array
* @param mixed
* @param bool
* @return null
*/
function editRowPrint($table, $fields, $row, $update) {
}
/** Functions displayed in edit form /** Functions displayed in edit form
* @param array single field from fields() * @param array single field from fields()
* @return array * @return array
*/ */
function editFunctions($field) { function editFunctions($field) {
global $edit_functions; global $driver;
$return = ($field["null"] ? "NULL/" : ""); $return = ($field["null"] ? "NULL/" : "");
foreach ($edit_functions as $key => $functions) { $update = isset($_GET["select"]) || where($_GET);
if (!$key || (!isset($_GET["call"]) && (isset($_GET["select"]) || where($_GET)))) { // relative functions foreach ($driver->editFunctions as $key => $functions) {
if (!$key || (!isset($_GET["call"]) && $update)) { // relative functions
foreach ($functions as $pattern => $val) { foreach ($functions as $pattern => $val) {
if (!$pattern || preg_match("~$pattern~", $field["type"])) { if (!$pattern || preg_match("~$pattern~", $field["type"])) {
$return .= "/$val"; $return .= "/$val";
} }
} }
if ($key && !preg_match('~set|blob|bytea|raw|file~', $field["type"])) { }
if ($key && !preg_match('~set|blob|bytea|raw|file|bool~', $field["type"])) {
$return .= "/SQL"; $return .= "/SQL";
} }
} }
} if ($field["auto_increment"] && !$update) {
if ($field["auto_increment"] && !isset($_GET["select"]) && !where($_GET)) {
$return = lang('Auto Increment'); $return = lang('Auto Increment');
} }
return explode("/", $return); return explode("/", $return);
@@ -694,7 +717,7 @@ class Adminer {
if ($field["type"] == "enum") { if ($field["type"] == "enum") {
return (isset($_GET["select"]) ? "<label><input type='radio'$attrs value='-1' checked><i>" . lang('original') . "</i></label> " : "") return (isset($_GET["select"]) ? "<label><input type='radio'$attrs value='-1' checked><i>" . lang('original') . "</i></label> " : "")
. ($field["null"] ? "<label><input type='radio'$attrs value=''" . ($value !== null || isset($_GET["select"]) ? "" : " checked") . "><i>NULL</i></label> " : "") . ($field["null"] ? "<label><input type='radio'$attrs value=''" . ($value !== null || isset($_GET["select"]) ? "" : " checked") . "><i>NULL</i></label> " : "")
. enum_input("radio", $attrs, $field, $value, 0) // 0 - empty . enum_input("radio", $attrs, $field, $value, $value === 0 ? 0 : null) // 0 - empty value
; ;
} }
return ""; return "";
@@ -753,7 +776,7 @@ class Adminer {
* @return array empty to disable export * @return array empty to disable export
*/ */
function dumpFormat() { function dumpFormat() {
return array('sql' => 'SQL', 'csv' => 'CSV,', 'csv;' => 'CSV;', 'tsv' => 'TSV'); return (support("dump") ? array('sql' => 'SQL') : array()) + array('csv' => 'CSV,', 'csv;' => 'CSV;', 'tsv' => 'TSV');
} }
/** Export database structure /** Export database structure
@@ -805,20 +828,32 @@ class Adminer {
* @return null prints data * @return null prints data
*/ */
function dumpData($table, $style, $query) { function dumpData($table, $style, $query) {
global $connection, $jush; global $connection;
$max_packet = ($jush == "sqlite" ? 0 : 1048576); // default, minimum is 1024
if ($style) { if ($style) {
$max_packet = (JUSH == "sqlite" ? 0 : 1048576); // default, minimum is 1024
$fields = array();
$identity_insert = false;
if ($_POST["format"] == "sql") { if ($_POST["format"] == "sql") {
if ($style == "TRUNCATE+INSERT") { if ($style == "TRUNCATE+INSERT") {
echo truncate_sql($table) . ";\n"; echo truncate_sql($table) . ";\n";
} }
$fields = fields($table); $fields = fields($table);
if (JUSH == "mssql") {
foreach ($fields as $field) {
if ($field["auto_increment"]) {
echo "SET IDENTITY_INSERT " . table($table) . " ON;\n";
$identity_insert = true;
break;
}
}
}
} }
$result = $connection->query($query, 1); // 1 - MYSQLI_USE_RESULT //! enum and set as numbers $result = $connection->query($query, 1); // 1 - MYSQLI_USE_RESULT //! enum and set as numbers
if ($result) { if ($result) {
$insert = ""; $insert = "";
$buffer = ""; $buffer = "";
$keys = array(); $keys = array();
$generated = array();
$suffix = ""; $suffix = "";
$fetch_function = ($table != '' ? 'fetch_assoc' : 'fetch_row'); $fetch_function = ($table != '' ? 'fetch_assoc' : 'fetch_row');
while ($row = $result->$fetch_function()) { while ($row = $result->$fetch_function()) {
@@ -826,6 +861,10 @@ class Adminer {
$values = array(); $values = array();
foreach ($row as $val) { foreach ($row as $val) {
$field = $result->fetch_field(); $field = $result->fetch_field();
if ($fields[$field->name]['generated']) {
$generated[$field->name] = true;
continue;
}
$keys[] = $field->name; $keys[] = $field->name;
$key = idf_escape($field->name); $key = idf_escape($field->name);
$values[] = "$key = VALUES($key)"; $values[] = "$key = VALUES($key)";
@@ -840,9 +879,13 @@ class Adminer {
dump_csv($row); dump_csv($row);
} else { } else {
if (!$insert) { if (!$insert) {
$insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('idf_escape', $keys)) . ") VALUES"; $insert = "INSERT INTO " . table($table) . " (" . implode(", ", array_map('Adminer\idf_escape', $keys)) . ") VALUES";
} }
foreach ($row as $key => $val) { foreach ($row as $key => $val) {
if ($generated[$key]) {
unset($row[$key]);
continue;
}
$field = $fields[$key]; $field = $fields[$key];
$row[$key] = ($val !== null $row[$key] = ($val !== null
? unconvert_field($field, preg_match(number_type(), $field["type"]) && !preg_match('~\[~', $field["full_type"]) && is_numeric($val) ? $val : q(($val === false ? 0 : $val))) ? unconvert_field($field, preg_match(number_type(), $field["type"]) && !preg_match('~\[~', $field["full_type"]) && is_numeric($val) ? $val : q(($val === false ? 0 : $val)))
@@ -866,6 +909,9 @@ class Adminer {
} elseif ($_POST["format"] == "sql") { } elseif ($_POST["format"] == "sql") {
echo "-- " . str_replace("\n", " ", $connection->error) . "\n"; echo "-- " . str_replace("\n", " ", $connection->error) . "\n";
} }
if ($identity_insert) {
echo "SET IDENTITY_INSERT " . table($table) . " OFF;\n";
}
} }
} }
@@ -919,13 +965,17 @@ class Adminer {
* @return null * @return null
*/ */
function navigation($missing) { function navigation($missing) {
global $VERSION, $jush, $drivers, $connection; global $VERSION, $drivers, $connection;
?> ?>
<h1> <h1>
<?php echo $this->name(); ?> <span class="version"><?php echo $VERSION; ?></span> <?php echo $this->name(); ?>
<span class="version">
<?php echo $VERSION; ?>
<a href="https://www.adminer.org/#download"<?php echo target_blank(); ?> id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?></a> <a href="https://www.adminer.org/#download"<?php echo target_blank(); ?> id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?></a>
</span>
</h1> </h1>
<?php <?php
switch_lang();
if ($missing == "auth") { if ($missing == "auth") {
$output = ""; $output = "";
foreach ((array) $_SESSION["pwds"] as $vendor => $servers) { foreach ((array) $_SESSION["pwds"] as $vendor => $servers) {
@@ -944,6 +994,7 @@ class Adminer {
echo "<ul id='logins'>\n$output</ul>\n" . script("mixin(qs('#logins'), {onmouseover: menuOver, onmouseout: menuOut});"); echo "<ul id='logins'>\n$output</ul>\n" . script("mixin(qs('#logins'), {onmouseover: menuOver, onmouseout: menuOut});");
} }
} else { } else {
$tables = array();
if ($_GET["ns"] !== "" && !$missing && DB != "") { if ($_GET["ns"] !== "" && !$missing && DB != "") {
$connection->select_db(DB); $connection->select_db(DB);
$tables = table_status('', true); $tables = table_status('', true);
@@ -953,7 +1004,7 @@ class Adminer {
echo script_src("../externals/jush/modules/jush-txt.js"); echo script_src("../externals/jush/modules/jush-txt.js");
echo script_src("../externals/jush/modules/jush-js.js"); echo script_src("../externals/jush/modules/jush-js.js");
if (support("sql")) { if (support("sql")) {
echo script_src("../externals/jush/modules/jush-$jush.js"); echo script_src("../externals/jush/modules/jush-" . JUSH . ".js");
?> ?>
<script<?php echo nonce(); ?>> <script<?php echo nonce(); ?>>
<?php <?php
@@ -962,9 +1013,9 @@ class Adminer {
foreach ($tables as $table => $type) { foreach ($tables as $table => $type) {
$links[] = preg_quote($table, '/'); $links[] = preg_quote($table, '/');
} }
echo "var jushLinks = { $jush: [ '" . js_escape(ME) . (support("table") ? "table=" : "select=") . "\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n"; echo "var jushLinks = { " . JUSH . ": [ '" . js_escape(ME) . (support("table") ? "table=" : "select=") . "\$&', /\\b(" . implode("|", $links) . ")\\b/g ] };\n";
foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) { foreach (array("bac", "bra", "sqlite_quo", "mssql_bra") as $val) {
echo "jushLinks.$val = jushLinks.$jush;\n"; echo "jushLinks.$val = jushLinks." . JUSH . ";\n";
} }
} }
$server_info = $connection->server_info; $server_info = $connection->server_info;
@@ -974,18 +1025,24 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
<?php <?php
} }
$this->databasesPrint($missing); $this->databasesPrint($missing);
$actions = array();
if (DB == "" || !$missing) { if (DB == "" || !$missing) {
echo "<p class='links'>" . (support("sql") ? "<a href='" . h(ME) . "sql='" . bold(isset($_GET["sql"]) && !isset($_GET["import"])) . ">" . lang('SQL command') . "</a>\n<a href='" . h(ME) . "import='" . bold(isset($_GET["import"])) . ">" . lang('Import') . "</a>\n" : "") . ""; if (support("sql")) {
if (support("dump")) { $actions[] = "<a href='" . h(ME) . "sql='" . bold(isset($_GET["sql"]) && !isset($_GET["import"])) . ">" . lang('SQL command') . "</a>";
echo "<a href='" . h(ME) . "dump=" . urlencode(isset($_GET["table"]) ? $_GET["table"] : $_GET["select"]) . "' id='dump'" . bold(isset($_GET["dump"])) . ">" . lang('Export') . "</a>\n"; $actions[] = "<a href='" . h(ME) . "import='" . bold(isset($_GET["import"])) . ">" . lang('Import') . "</a>";
} }
$actions[] = "<a href='" . h(ME) . "dump=" . urlencode(isset($_GET["table"]) ? $_GET["table"] : $_GET["select"]) . "' id='dump'" . bold(isset($_GET["dump"])) . ">" . lang('Export') . "</a>";
} }
if ($_GET["ns"] !== "" && !$missing && DB != "") { $in_db = $_GET["ns"] !== "" && !$missing && DB != "";
echo '<a href="' . h(ME) . 'create="' . bold($_GET["create"] === "") . ">" . lang('Create table') . "</a>\n"; if ($in_db) {
if (!$tables) { $actions[] = '<a href="' . h(ME) . 'create="' . bold($_GET["create"] === "") . ">" . lang('Create table') . "</a>";
echo "<p class='message'>" . lang('No tables.') . "\n"; }
} else { echo ($actions ? "<p class='links'>\n" . implode("\n", $actions) . "\n" : "");
if ($in_db) {
if ($tables) {
$this->tablesPrint($tables); $this->tablesPrint($tables);
} else {
echo "<p class='message'>" . lang('No tables.') . "</p>\n";
} }
} }
} }
@@ -998,7 +1055,7 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
function databasesPrint($missing) { function databasesPrint($missing) {
global $adminer, $connection; global $adminer, $connection;
$databases = $this->databases(); $databases = $this->databases();
if ($databases && !in_array(DB, $databases)) { if (DB && $databases && !in_array(DB, $databases)) {
array_unshift($databases, DB); array_unshift($databases, DB);
} }
?> ?>
@@ -1007,13 +1064,13 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
<?php <?php
hidden_fields_get(); hidden_fields_get();
$db_events = script("mixin(qsl('select'), {onmousedown: dbMouseDown, onchange: dbChange});"); $db_events = script("mixin(qsl('select'), {onmousedown: dbMouseDown, onchange: dbChange});");
echo "<span title='" . lang('database') . "'>" . lang('DB') . "</span>: " . ($databases echo "<span title='" . lang('Database') . "'>" . lang('DB') . "</span>: " . ($databases
? "<select name='db'>" . optionlist(array("" => "") + $databases, DB) . "</select>$db_events" ? "<select name='db'>" . optionlist(array("" => "") + $databases, DB) . "</select>$db_events"
: "<input name='db' value='" . h(DB) . "' autocapitalize='off'>\n" : "<input name='db' value='" . h(DB) . "' autocapitalize='off' size='19'>\n"
); );
echo "<input type='submit' value='" . lang('Use') . "'" . ($databases ? " class='hidden'" : "") . ">\n"; echo "<input type='submit' value='" . lang('Use') . "'" . ($databases ? " class='hidden'" : "") . ">\n";
if ($missing != "db" && DB != "" && $connection->select_db(DB)) {
if (support("scheme")) { if (support("scheme")) {
if ($missing != "db" && DB != "" && $connection->select_db(DB)) {
echo "<br>" . lang('Schema') . ": <select name='ns'>" . optionlist(array("" => "") + $adminer->schemas(), $_GET["ns"]) . "</select>$db_events"; echo "<br>" . lang('Schema') . ": <select name='ns'>" . optionlist(array("" => "") + $adminer->schemas(), $_GET["ns"]) . "</select>$db_events";
if ($_GET["ns"] != "") { if ($_GET["ns"] != "") {
set_schema($_GET["ns"]); set_schema($_GET["ns"]);
@@ -1038,7 +1095,10 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
foreach ($tables as $table => $status) { foreach ($tables as $table => $status) {
$name = $this->tableName($status); $name = $this->tableName($status);
if ($name != "") { if ($name != "") {
echo '<li><a href="' . h(ME) . 'select=' . urlencode($table) . '"' . bold($_GET["select"] == $table || $_GET["edit"] == $table, "select") . ">" . lang('select') . "</a> "; echo '<li><a href="' . h(ME) . 'select=' . urlencode($table) . '"'
. bold($_GET["select"] == $table || $_GET["edit"] == $table, "select")
. " title='" . lang('Select data') . "'>" . lang('select') . "</a> "
;
echo (support("table") || support("indexes") echo (support("table") || support("indexes")
? '<a href="' . h(ME) . 'table=' . urlencode($table) . '"' ? '<a href="' . h(ME) . 'table=' . urlencode($table) . '"'
. bold(in_array($table, array($_GET["table"], $_GET["create"], $_GET["indexes"], $_GET["foreign"], $_GET["trigger"])), (is_view($status) ? "view" : "structure")) . bold(in_array($table, array($_GET["table"], $_GET["create"], $_GET["indexes"], $_GET["foreign"], $_GET["trigger"])), (is_view($status) ? "view" : "structure"))
@@ -1049,10 +1109,4 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
} }
echo "</ul>\n"; echo "</ul>\n";
} }
}
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
if ($adminer->operators === null) {
$adminer->operators = $operators;
} }

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$connection = ''; $connection = '';
$has_token = $_SESSION["token"]; $has_token = $_SESSION["token"];
@@ -41,7 +43,7 @@ function add_invalid_login() {
function check_invalid_login() { function check_invalid_login() {
global $adminer; global $adminer;
$invalids = unserialize(@file_get_contents(get_temp_dir() . "/adminer.invalid")); // @ - may not exist $invalids = unserialize(@file_get_contents(get_temp_dir() . "/adminer.invalid")); // @ - may not exist
$invalid = $invalids[$adminer->bruteForceKey()]; $invalid = ($invalids ? $invalids[$adminer->bruteForceKey()] : array());
$next_attempt = ($invalid[1] > 29 ? $invalid[0] - time() : 0); // allow 30 invalid attempts $next_attempt = ($invalid[1] > 29 ? $invalid[0] - time() : 0); // allow 30 invalid attempts
if ($next_attempt > 0) { //! do the same with permanent login if ($next_attempt > 0) { //! do the same with permanent login
auth_error(lang('Too many unsuccessful logins, try again in %d minute(s).', ceil($next_attempt / 60))); auth_error(lang('Too many unsuccessful logins, try again in %d minute(s).', ceil($next_attempt / 60)));
@@ -64,7 +66,8 @@ if ($auth) {
$permanent[$key] = "$key:" . base64_encode($private ? encrypt_string($password, $private) : ""); $permanent[$key] = "$key:" . base64_encode($private ? encrypt_string($password, $private) : "");
cookie("adminer_permanent", implode(" ", $permanent)); cookie("adminer_permanent", implode(" ", $permanent));
} }
if (count($_POST) == 1 // 1 - auth if (
count($_POST) == 1 // 1 - auth
|| DRIVER != $vendor || DRIVER != $vendor
|| SERVER != $server || SERVER != $server
|| $_GET["username"] !== $username // "0" == "00" || $_GET["username"] !== $username // "0" == "00"
@@ -73,18 +76,12 @@ if ($auth) {
redirect(auth_url($vendor, $server, $username, $db)); redirect(auth_url($vendor, $server, $username, $db));
} }
} elseif ($_POST["logout"]) { } elseif ($_POST["logout"] && (!$has_token || verify_token())) {
if ($has_token && !verify_token()) {
page_header(lang('Logout'), lang('Invalid CSRF token. Send the form again.'));
page_footer("db");
exit;
} else {
foreach (array("pwds", "db", "dbs", "queries") as $key) { foreach (array("pwds", "db", "dbs", "queries") as $key) {
set_session($key, null); set_session($key, null);
} }
unset_permanent(); unset_permanent();
redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.') . ' ' . lang('Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.')); redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.') . ' ' . lang('Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.'));
}
} elseif ($permanent && !$_SESSION["pwds"]) { } elseif ($permanent && !$_SESSION["pwds"]) {
session_regenerate_id(); session_regenerate_id();
@@ -125,7 +122,7 @@ function auth_error($error) {
$password = get_password(); $password = get_password();
if ($password !== null) { if ($password !== null) {
if ($password === false) { if ($password === false) {
$error .= '<br>' . lang('Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.', target_blank(), '<code>permanentLogin()</code>'); $error .= ($error ? '<br>' : '') . lang('Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.', target_blank(), '<code>permanentLogin()</code>');
} }
set_password(DRIVER, SERVER, $_GET["username"], null); set_password(DRIVER, SERVER, $_GET["username"], null);
} }
@@ -136,7 +133,7 @@ function auth_error($error) {
$error = lang('Session support must be enabled.'); $error = lang('Session support must be enabled.');
} }
$params = session_get_cookie_params(); $params = session_get_cookie_params();
cookie("adminer_key", ($_COOKIE["adminer_key"] ? $_COOKIE["adminer_key"] : rand_string()), $params["lifetime"]); cookie("adminer_key", ($_COOKIE["adminer_key"] ?: rand_string()), $params["lifetime"]);
page_header(lang('Login'), $error, null); page_header(lang('Login'), $error, null);
echo "<form action='' method='post'>\n"; echo "<form action='' method='post'>\n";
echo "<div>"; echo "<div>";
@@ -150,10 +147,10 @@ function auth_error($error) {
exit; exit;
} }
if (isset($_GET["username"]) && !class_exists("Min_DB")) { if (isset($_GET["username"]) && !class_exists('Adminer\Db')) {
unset($_SESSION["pwds"][DRIVER]); unset($_SESSION["pwds"][DRIVER]);
unset_permanent(); unset_permanent();
page_header(lang('No extension'), lang('None of the supported PHP extensions (%s) are available.', implode(", ", $possible_drivers)), false); page_header(lang('No extension'), lang('None of the supported PHP extensions (%s) are available.', implode(", ", Driver::$possibleDrivers)), false);
page_footer("auth"); page_footer("auth");
exit; exit;
} }
@@ -162,20 +159,29 @@ stop_session(true);
if (isset($_GET["username"]) && is_string(get_password())) { if (isset($_GET["username"]) && is_string(get_password())) {
list($host, $port) = explode(":", SERVER, 2); list($host, $port) = explode(":", SERVER, 2);
if (is_numeric($port) && $port < 1024) { 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.')); auth_error(lang('Connecting to privileged ports is not allowed.'));
} }
check_invalid_login(); check_invalid_login();
$connection = connect(); $connection = connect($adminer->credentials());
$driver = new Min_Driver($connection); $driver = new Driver($connection);
if ($adminer->operators === null) {
$adminer->operators = $driver->operators;
}
} }
$login = null; $login = null;
if (!is_object($connection) || ($login = $adminer->login($_GET["username"], get_password())) !== true) { if (!is_object($connection) || ($login = $adminer->login($_GET["username"], get_password())) !== true) {
$error = (is_string($connection) ? h($connection) : (is_string($login) ? $login : lang('Invalid credentials.'))); $error = (is_string($connection) ? nl_br(h($connection)) : (is_string($login) ? $login : lang('Invalid credentials.')));
auth_error($error . (preg_match('~^ | $~', get_password()) ? '<br>' . lang('There is a space in the input password which might be the cause.') : '')); auth_error($error . (preg_match('~^ | $~', get_password()) ? '<br>' . lang('There is a space in the input password which might be the cause.') : ''));
} }
if ($_POST["logout"] && $has_token && !verify_token()) {
page_header(lang('Logout'), lang('Invalid CSRF token. Send the form again.'));
page_footer("db");
exit;
}
if ($auth && $_POST["token"]) { if ($auth && $_POST["token"]) {
$_POST["token"] = $token; // reset token after explicit login $_POST["token"] = $token; // reset token after explicit login
} }

View File

@@ -1,6 +1,8 @@
<?php <?php
error_reporting(6135); // errors and warnings namespace Adminer;
include "../adminer/include/version.inc.php";
include "../adminer/include/errors.inc.php";
include "../adminer/include/coverage.inc.php"; include "../adminer/include/coverage.inc.php";
// disable filter.default // disable filter.default
@@ -33,7 +35,7 @@ if ($_GET["script"] == "version") {
exit; exit;
} }
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 global $adminer, $connection, $driver, $drivers, $error, $HTTPS, $LANG, $langs, $permanent, $has_token, $token, $translations, $VERSION; // allows including Adminer inside a function
if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility
$_SERVER["REQUEST_URI"] = $_SERVER["ORIG_PATH_INFO"]; $_SERVER["REQUEST_URI"] = $_SERVER["ORIG_PATH_INFO"];
@@ -50,17 +52,13 @@ $HTTPS = ($_SERVER["HTTPS"] && strcasecmp($_SERVER["HTTPS"], "off")) || ini_bool
if (!defined("SID")) { if (!defined("SID")) {
session_cache_limiter(""); // to allow restarting session session_cache_limiter(""); // to allow restarting session
session_name("adminer_sid"); // use specific session name to get own namespace session_name("adminer_sid"); // use specific session name to get own namespace
$params = array(0, preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"]), "", $HTTPS); session_set_cookie_params(0, preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"]), "", $HTTPS, true); // ini_set() may be disabled
if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
$params[] = true; // HttpOnly
}
call_user_func_array('session_set_cookie_params', $params); // ini_set() may be disabled
session_start(); session_start();
} }
// disable magic quotes to be able to use database escaping function // disable magic quotes to be able to use database escaping function
remove_slashes(array(&$_GET, &$_POST, &$_COOKIE), $filter); remove_slashes(array(&$_GET, &$_POST, &$_COOKIE), $filter);
if (get_magic_quotes_runtime()) { if (function_exists("get_magic_quotes_runtime") && get_magic_quotes_runtime()) {
set_magic_quotes_runtime(false); set_magic_quotes_runtime(false);
} }
@set_time_limit(0); // @ - can be disabled @set_time_limit(0); // @ - can be disabled
@@ -75,28 +73,25 @@ include "../adminer/drivers/sqlite.inc.php";
include "../adminer/drivers/pgsql.inc.php"; include "../adminer/drivers/pgsql.inc.php";
include "../adminer/drivers/oracle.inc.php"; include "../adminer/drivers/oracle.inc.php";
include "../adminer/drivers/mssql.inc.php"; include "../adminer/drivers/mssql.inc.php";
include "../adminer/drivers/firebird.inc.php";
include "../adminer/drivers/simpledb.inc.php";
include "../adminer/drivers/mongo.inc.php"; include "../adminer/drivers/mongo.inc.php";
include "../adminer/drivers/elastic.inc.php"; include "./include/adminer.inc.php";
include "../adminer/drivers/clickhouse.inc.php"; $adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver include "../adminer/drivers/mysql.inc.php"; // must be included as last driver
define("SERVER", $_GET[DRIVER]); // read from pgsql=localhost define('Adminer\JUSH', Driver::$jush);
define("DB", $_GET["db"]); // for the sake of speed and size define('Adminer\SERVER', $_GET[DRIVER]); // read from pgsql=localhost
define("ME", str_replace(":", "%3a", preg_replace('~^[^?]*/([^?]*).*~', '\1', $_SERVER["REQUEST_URI"])) . '?' define('Adminer\DB', $_GET["db"]); // for the sake of speed and size
define(
'Adminer\ME',
preg_replace('~\?.*~', '', relative_uri()) . '?'
. (sid() ? SID . '&' : '') . (sid() ? SID . '&' : '')
. (SERVER !== null ? DRIVER . "=" . urlencode(SERVER) . '&' : '') . (SERVER !== null ? DRIVER . "=" . urlencode(SERVER) . '&' : '')
. (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '') . (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '')
. (DB != "" ? 'db=' . urlencode(DB) . '&' . (isset($_GET["ns"]) ? "ns=" . urlencode($_GET["ns"]) . "&" : "") : '') . (DB != "" ? 'db=' . urlencode(DB) . '&' . (isset($_GET["ns"]) ? "ns=" . urlencode($_GET["ns"]) . "&" : "") : '')
); );
include "../adminer/include/version.inc.php";
include "./include/adminer.inc.php";
include "../adminer/include/design.inc.php"; include "../adminer/include/design.inc.php";
include "../adminer/include/xxtea.inc.php"; include "../adminer/include/xxtea.inc.php";
include "../adminer/include/auth.inc.php"; include "../adminer/include/auth.inc.php";
include "./include/editing.inc.php"; include "./include/editing.inc.php";
include "./include/connect.inc.php"; include "./include/connect.inc.php";
$on_actions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; ///< @var string used in foreign_keys()

View File

@@ -1,6 +1,18 @@
<?php <?php
function connect_error() { namespace Adminer;
global $adminer, $connection, $token, $error, $drivers;
if (isset($_GET["status"])) {
$_GET["variables"] = $_GET["status"];
}
if (isset($_GET["import"])) {
$_GET["sql"] = $_GET["import"];
}
if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]) || isset($_GET["variables"]) || $_GET["script"] == "connect" || $_GET["script"] == "kill")) {
if (DB != "" || $_GET["refresh"]) {
restart_session();
set_session("dbs", null);
}
if (DB != "") { if (DB != "") {
header("HTTP/1.1 404 Not Found"); header("HTTP/1.1 404 Not Found");
page_header(lang('Database') . ": " . h(DB), lang('Invalid database.'), true); page_header(lang('Database') . ": " . h(DB), lang('Invalid database.'), true);
@@ -11,13 +23,15 @@ function connect_error() {
page_header(lang('Select database'), $error, false); page_header(lang('Select database'), $error, false);
echo "<p class='links'>\n"; echo "<p class='links'>\n";
foreach (array( foreach (
array(
'database' => lang('Create database'), 'database' => lang('Create database'),
'privileges' => lang('Privileges'), 'privileges' => lang('Privileges'),
'processlist' => lang('Process list'), 'processlist' => lang('Process list'),
'variables' => lang('Variables'), 'variables' => lang('Variables'),
'status' => lang('Status'), 'status' => lang('Status'),
) as $key => $val) { ) as $key => $val
) {
if (support($key)) { if (support($key)) {
echo "<a href='" . h(ME) . "$key='>$val</a>\n"; echo "<a href='" . h(ME) . "$key='>$val</a>\n";
} }
@@ -29,11 +43,11 @@ function connect_error() {
$scheme = support("scheme"); $scheme = support("scheme");
$collations = collations(); $collations = collations();
echo "<form action='' method='post'>\n"; echo "<form action='' method='post'>\n";
echo "<table cellspacing='0' class='checkable'>\n"; echo "<table class='checkable odds'>\n";
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});"); echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
echo "<thead><tr>" echo "<thead><tr>"
. (support("database") ? "<td>" : "") . (support("database") ? "<td>" : "")
. "<th>" . lang('Database') . " - <a href='" . h(ME) . "refresh=1'>" . lang('Refresh') . "</a>" . "<th>" . lang('Database') . (get_session("dbs") !== null ? " - <a href='" . h(ME) . "refresh=1'>" . lang('Refresh') . "</a>" : "")
. "<td>" . lang('Collation') . "<td>" . lang('Collation')
. "<td>" . lang('Tables') . "<td>" . lang('Tables')
. "<td>" . lang('Size') . " - <a href='" . h(ME) . "dbsize=1'>" . lang('Compute') . "</a>" . script("qsl('a').onclick = partial(ajaxSetHtml, '" . js_escape(ME) . "script=connect');", "") . "<td>" . lang('Size') . " - <a href='" . h(ME) . "dbsize=1'>" . lang('Compute') . "</a>" . script("qsl('a').onclick = partial(ajaxSetHtml, '" . js_escape(ME) . "script=connect');", "")
@@ -45,7 +59,7 @@ function connect_error() {
foreach ($databases as $db => $tables) { foreach ($databases as $db => $tables) {
$root = h(ME) . "db=" . urlencode($db); $root = h(ME) . "db=" . urlencode($db);
$id = h("Db-" . $db); $id = h("Db-" . $db);
echo "<tr" . odd() . ">" . (support("database") ? "<td>" . checkbox("db[]", $db, in_array($db, (array) $_POST["db"]), "", "", "", $id) : ""); 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>"; echo "<th><a href='$root' id='$id'>" . h($db) . "</a>";
$collation = h(db_collation($db, $collations)); $collation = h(db_collation($db, $collations));
echo "<td>" . (support("database") ? "<a href='$root" . ($scheme ? "&amp;ns=" : "") . "&amp;database=' title='" . lang('Alter database') . "'>$collation</a>" : $collation); echo "<td>" . (support("database") ? "<a href='$root" . ($scheme ? "&amp;ns=" : "") . "&amp;database=' title='" . lang('Alter database') . "'>$collation</a>" : $collation);
@@ -71,25 +85,11 @@ function connect_error() {
} }
page_footer("db"); page_footer("db");
}
if (isset($_GET["status"])) {
$_GET["variables"] = $_GET["status"];
}
if (isset($_GET["import"])) {
$_GET["sql"] = $_GET["import"];
}
if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]) || isset($_GET["variables"]) || $_GET["script"] == "connect" || $_GET["script"] == "kill")) {
if (DB != "" || $_GET["refresh"]) {
restart_session();
set_session("dbs", null);
}
connect_error(); // separate function to catch SQLite error
exit; exit;
} }
if (support("scheme") && DB != "" && $_GET["ns"] !== "") { if (support("scheme")) {
if (DB != "" && $_GET["ns"] !== "") {
if (!isset($_GET["ns"])) { if (!isset($_GET["ns"])) {
redirect(preg_replace('~ns=[^&]*&~', '', ME) . "ns=" . get_schema()); redirect(preg_replace('~ns=[^&]*&~', '', ME) . "ns=" . get_schema());
} }
@@ -100,3 +100,4 @@ if (support("scheme") && DB != "" && $_GET["ns"] !== "") {
exit; exit;
} }
} }
}

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
// coverage is used in tests and removed in compilation // coverage is used in tests and removed in compilation
if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer_coverage.ser")) { if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer_coverage.ser")) {
function save_coverage() { function save_coverage() {
@@ -14,5 +16,5 @@ if (extension_loaded("xdebug") && file_exists(sys_get_temp_dir() . "/adminer_cov
} }
} }
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
register_shutdown_function('save_coverage'); register_shutdown_function('Adminer\save_coverage');
} }

View File

@@ -1,13 +1,19 @@
<?php <?php
namespace Adminer;
if (!ob_get_level()) {
ob_start(null, 4096);
}
/** Print HTML header /** Print HTML header
* @param string used in title, breadcrumb and heading, should be HTML escaped * @param string used in title, breadcrumb and heading, should be HTML escaped
* @param string * @param string
* @param mixed array("key" => "link", "key2" => array("link", "desc")), null for nothing, false for driver only, true for driver and server * @param mixed ["key" => "link", "key2" => ["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 * @param string used after colon in title and heading, should be HTML escaped
* @return null * @return null
*/ */
function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") { function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
global $LANG, $VERSION, $adminer, $drivers, $jush; global $LANG, $VERSION, $adminer, $drivers;
page_headers(); page_headers();
if (is_ajax() && $error) { if (is_ajax() && $error) {
page_messages($error); page_messages($error);
@@ -20,6 +26,7 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
<html lang="<?php echo $LANG; ?>" dir="<?php echo lang('ltr'); ?>"> <html lang="<?php echo $LANG; ?>" dir="<?php echo lang('ltr'); ?>">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="robots" content="noindex"> <meta name="robots" content="noindex">
<meta name="viewport" content="width=device-width">
<title><?php echo $title_page; ?></title> <title><?php echo $title_page; ?></title>
<link rel="stylesheet" type="text/css" 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("../adminer/static/functions.js"); ?>
@@ -61,32 +68,32 @@ var offlineMessage = '<?php echo js_escape(lang('You are offline.')); ?>';
var thousandsSeparator = '<?php echo js_escape(lang(',')); ?>'; var thousandsSeparator = '<?php echo js_escape(lang(',')); ?>';
</script> </script>
<div id="help" class="jush-<?php echo $jush; ?> jsonly hidden"></div> <div id="help" class="jush-<?php echo JUSH; ?> jsonly hidden"></div>
<?php echo script("mixin(qs('#help'), {onmouseover: function () { helpOpen = 1; }, onmouseout: helpMouseout});"); ?> <?php echo script("mixin(qs('#help'), {onmouseover: function () { helpOpen = 1; }, onmouseout: helpMouseout});"); ?>
<div id="content"> <div id="content">
<?php <?php
if ($breadcrumb !== null) { if ($breadcrumb !== null) {
$link = substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1); $link = substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1);
echo '<p id="breadcrumb"><a href="' . h($link ? $link : ".") . '">' . $drivers[DRIVER] . '</a> &raquo; '; echo '<p id="breadcrumb"><a href="' . h($link ?: ".") . '">' . $drivers[DRIVER] . '</a> » ';
$link = substr(preg_replace('~\b(db|ns)=[^&]*&~', '', ME), 0, -1); $link = substr(preg_replace('~\b(db|ns)=[^&]*&~', '', ME), 0, -1);
$server = $adminer->serverName(SERVER); $server = $adminer->serverName(SERVER);
$server = ($server != "" ? $server : lang('Server')); $server = ($server != "" ? $server : lang('Server'));
if ($breadcrumb === false) { if ($breadcrumb === false) {
echo "$server\n"; echo "$server\n";
} else { } else {
echo "<a href='" . ($link ? h($link) : ".") . "' accesskey='1' title='Alt+Shift+1'>$server</a> &raquo; "; echo "<a href='" . h($link) . "' accesskey='1' title='Alt+Shift+1'>$server</a> » ";
if ($_GET["ns"] != "" || (DB != "" && is_array($breadcrumb))) { if ($_GET["ns"] != "" || (DB != "" && is_array($breadcrumb))) {
echo '<a href="' . h($link . "&db=" . urlencode(DB) . (support("scheme") ? "&ns=" : "")) . '">' . h(DB) . '</a> &raquo; '; echo '<a href="' . h($link . "&db=" . urlencode(DB) . (support("scheme") ? "&ns=" : "")) . '">' . h(DB) . '</a> » ';
} }
if (is_array($breadcrumb)) { if (is_array($breadcrumb)) {
if ($_GET["ns"] != "") { if ($_GET["ns"] != "") {
echo '<a href="' . h(substr(ME, 0, -1)) . '">' . h($_GET["ns"]) . '</a> &raquo; '; echo '<a href="' . h(substr(ME, 0, -1)) . '">' . h($_GET["ns"]) . '</a> » ';
} }
foreach ($breadcrumb as $key => $val) { foreach ($breadcrumb as $key => $val) {
$desc = (is_array($val) ? $val[1] : h($val)); $desc = (is_array($val) ? $val[1] : h($val));
if ($desc != "") { if ($desc != "") {
echo "<a href='" . h(ME . "$key=") . urlencode(is_array($val) ? $val[0] : $val) . "'>$desc</a> &raquo; "; echo "<a href='" . h(ME . "$key=") . urlencode(is_array($val) ? $val[0] : $val) . "'>$desc</a> » ";
} }
} }
} }
@@ -102,7 +109,7 @@ var thousandsSeparator = '<?php echo js_escape(lang(',')); ?>';
$databases = null; $databases = null;
} }
stop_session(); stop_session();
define("PAGE_HEADER", 1); define('Adminer\PAGE_HEADER', 1);
} }
/** Send HTTP headers /** Send HTTP headers
@@ -178,18 +185,19 @@ function page_footer($missing = "") {
?> ?>
</div> </div>
<?php switch_lang(); ?> <div id="menu">
<?php $adminer->navigation($missing); ?>
</div>
<?php if ($missing != "auth") { ?> <?php if ($missing != "auth") { ?>
<form action="" method="post"> <form action="" method="post">
<p class="logout"> <p class="logout">
<?php echo h($_GET["username"]) . "\n"; ?>
<input type="submit" name="logout" value="<?php echo lang('Logout'); ?>" id="logout"> <input type="submit" name="logout" value="<?php echo lang('Logout'); ?>" id="logout">
<input type="hidden" name="token" value="<?php echo $token; ?>"> <input type="hidden" name="token" value="<?php echo $token; ?>">
</p> </p>
</form> </form>
<?php } ?> <?php } ?>
<div id="menu">
<?php $adminer->navigation($missing); ?>
</div>
<?php <?php
echo script("setupSubmitHighlight(document);"); echo script("setupSubmitHighlight(document);");
} }

View File

@@ -1,15 +1,64 @@
<?php <?php
namespace Adminer;
$drivers = array();
/** Add a driver
* @param string
* @param string
* @return null
*/
function add_driver($id, $name) {
global $drivers;
$drivers[$id] = $name;
}
/** Get driver name
* @param string
* @return string
*/
function get_driver($id) {
global $drivers;
return $drivers[$id];
}
abstract class SqlDriver {
static $possibleDrivers = array();
static $jush; ///< @var string JUSH identifier
/*abstract*/ class Min_SQL {
var $_conn; var $_conn;
protected $types = array(); ///< @var array [$description => [$type => $maximum_unsigned_length, ...], ...]
var $editFunctions = array(); ///< @var array of ["$type|$type2" => "$function/$function2"] functions used in editing, [0] - edit and insert, [1] - edit only
var $unsigned = array(); ///< @var array number variants
var $operators = array(); ///< @var array operators used in select
var $functions = array(); ///< @var array functions used in select
var $grouping = array(); ///< @var array grouping functions used in select
var $onActions = "RESTRICT|NO ACTION|CASCADE|SET NULL|SET DEFAULT"; ///< @var string used in foreign_keys()
var $inout = "IN|OUT|INOUT";
var $enumLength = "'(?:''|[^'\\\\]|\\\\.)*'";
var $generated = array();
/** Create object for performing database operations /** Create object for performing database operations
* @param Min_DB * @param Db
*/ */
function __construct($connection) { function __construct($connection) {
$this->_conn = $connection; $this->_conn = $connection;
} }
/** Get all types
* @return array [$type => $maximum_unsigned_length, ...]
*/
function types() {
return call_user_func_array('array_merge', array_values($this->types));
}
/** Get structured types
* @return array [$description => [$type, ...], ...]
*/
function structuredTypes() {
return array_map('array_keys', $this->types);
}
/** Select data from table /** Select data from table
* @param string * @param string
* @param array result of $adminer->selectColumnsProcess()[0] * @param array result of $adminer->selectColumnsProcess()[0]
@@ -19,15 +68,15 @@
* @param int result of $adminer->selectLimitProcess() * @param int result of $adminer->selectLimitProcess()
* @param int index of page starting at zero * @param int index of page starting at zero
* @param bool whether to print the query * @param bool whether to print the query
* @return Min_Result * @return Result
*/ */
function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) { function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
global $adminer, $jush; global $adminer;
$is_group = (count($group) < count($select)); $is_group = (count($group) < count($select));
$query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page); $query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page);
if (!$query) { if (!$query) {
$query = "SELECT" . limit( $query = "SELECT" . limit(
($_GET["page"] != "last" && $limit != "" && $group && $is_group && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . implode(", ", $select) . "\nFROM " . table($table), ($_GET["page"] != "last" && $limit != "" && $group && $is_group && JUSH == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . implode(", ", $select) . "\nFROM " . table($table),
($where ? "\nWHERE " . implode(" AND ", $where) : "") . ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : ""), ($where ? "\nWHERE " . implode(" AND ", $where) : "") . ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : ""),
($limit != "" ? +$limit : null), ($limit != "" ? +$limit : null),
($page ? $limit * $page : 0), ($page ? $limit * $page : 0),
@@ -88,7 +137,7 @@
* @param array of arrays with escaped columns in keys and quoted data in values * @param array of arrays with escaped columns in keys and quoted data in values
* @return bool * @return bool
*/ */
/*abstract*/ function insertUpdate($table, $rows, $primary) { function insertUpdate($table, $rows, $primary) {
return false; return false;
} }
@@ -123,7 +172,7 @@
/** Convert column to be searchable /** Convert column to be searchable
* @param string escaped column name * @param string escaped column name
* @param array array("op" => , "val" => ) * @param array ["op" => , "val" => ]
* @param array * @param array
* @return string * @return string
*/ */
@@ -131,6 +180,14 @@
return $idf; return $idf;
} }
/** 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 /** Convert value returned by database to actual value
* @param string * @param string
* @param array * @param array
@@ -160,9 +217,38 @@
/** Get help link for table /** Get help link for table
* @param string * @param string
* @param bool
* @return string relative URL or null * @return string relative URL or null
*/ */
function tableHelp($name) { function tableHelp($name, $is_view = false) {
} }
/** Check if C-style escapes are supported
* @return bool
*/
function hasCStyleEscapes() {
return false;
}
/** Check whether table supports indexes
* @param array result of table_status()
* @return bool
*/
function supportsIndex($table_status) {
return !is_view($table_status);
}
/** Get defined check constraints
* @param string
* @return array [$name => $clause]
*/
function checkConstraints($table) {
// 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'"); // ignore default IS NOT NULL checks in PostrgreSQL
}
} }

View File

@@ -1,24 +1,26 @@
<?php <?php
namespace Adminer;
// This file is not used in Adminer Editor.
/** Print select result /** Print select result
* @param Min_Result * @param Result
* @param Min_DB connection to examine indexes * @param Db connection to examine indexes
* @param array * @param array
* @param int * @param int
* @return array $orgtables * @return array $orgtables
*/ */
function select($result, $connection2 = null, $orgtables = array(), $limit = 0) { function select($result, $connection2 = null, $orgtables = array(), $limit = 0) {
global $jush;
$links = array(); // colno => orgtable - create links from these columns $links = array(); // colno => orgtable - create links from these columns
$indexes = array(); // orgtable => array(column => colno) - primary keys $indexes = array(); // orgtable => array(column => colno) - primary keys
$columns = array(); // orgtable => array(column => ) - not selected columns in primary key $columns = array(); // orgtable => array(column => ) - not selected columns in primary key
$blobs = array(); // colno => bool - display bytes for blobs $blobs = array(); // colno => bool - display bytes for blobs
$types = array(); // colno => type - display char in <code> $types = array(); // colno => type - display char in <code>
$return = array(); // table => orgtable - mapping to use in EXPLAIN $return = array(); // table => orgtable - mapping to use in EXPLAIN
odd(''); // reset odd for each result
for ($i=0; (!$limit || $i < $limit) && ($row = $result->fetch_row()); $i++) { for ($i=0; (!$limit || $i < $limit) && ($row = $result->fetch_row()); $i++) {
if (!$i) { if (!$i) {
echo "<div class='scrollable'>\n"; echo "<div class='scrollable'>\n";
echo "<table cellspacing='0' class='nowrap'>\n"; echo "<table class='nowrap odds'>\n";
echo "<thead><tr>"; echo "<thead><tr>";
for ($j=0; $j < count($row); $j++) { for ($j=0; $j < count($row); $j++) {
$field = $result->fetch_field(); $field = $result->fetch_field();
@@ -26,7 +28,7 @@ function select($result, $connection2 = null, $orgtables = array(), $limit = 0)
$orgtable = $field->orgtable; $orgtable = $field->orgtable;
$orgname = $field->orgname; $orgname = $field->orgname;
$return[$field->table] = $orgtable; $return[$field->table] = $orgtable;
if ($orgtables && $jush == "sql") { // MySQL EXPLAIN if ($orgtables && JUSH == "sql") { // MySQL EXPLAIN
$links[$j] = ($name == "table" ? "table=" : ($name == "possible_keys" ? "indexes=" : null)); $links[$j] = ($name == "table" ? "table=" : ($name == "possible_keys" ? "indexes=" : null));
} elseif ($orgtable != "") { } elseif ($orgtable != "") {
if (!isset($indexes[$orgtable])) { if (!isset($indexes[$orgtable])) {
@@ -59,8 +61,22 @@ function select($result, $connection2 = null, $orgtables = array(), $limit = 0)
} }
echo "</thead>\n"; echo "</thead>\n";
} }
echo "<tr" . odd() . ">"; echo "<tr>";
foreach ($row as $key => $val) { foreach ($row as $key => $val) {
$link = "";
if (isset($links[$key]) && !$columns[$links[$key]]) {
if ($orgtables && JUSH == "sql") { // MySQL EXPLAIN
$table = $row[array_search("table=", $links)];
$link = ME . $links[$key] . urlencode($orgtables[$table] != "" ? $orgtables[$table] : $table);
} else {
$link = ME . "edit=" . urlencode($links[$key]);
foreach ($indexes[$links[$key]] as $col => $j) {
$link .= "&where" . urlencode("[" . bracket_escape($col) . "]") . "=" . urlencode($row[$j]);
}
}
} elseif (is_url($val)) {
$link = $val;
}
if ($val === null) { if ($val === null) {
$val = "<i>NULL</i>"; $val = "<i>NULL</i>";
} elseif ($blobs[$key] && !is_utf8($val)) { } elseif ($blobs[$key] && !is_utf8($val)) {
@@ -71,17 +87,8 @@ function select($result, $connection2 = null, $orgtables = array(), $limit = 0)
$val = "<code>$val</code>"; $val = "<code>$val</code>";
} }
} }
if (isset($links[$key]) && !$columns[$links[$key]]) { if ($link) {
if ($orgtables && $jush == "sql") { // MySQL EXPLAIN $val = "<a href='" . h($link) . "'" . (is_url($link) ? target_blank() : '') . ">$val</a>";
$table = $row[array_search("table=", $links)];
$link = $links[$key] . urlencode($orgtables[$table] != "" ? $orgtables[$table] : $table);
} else {
$link = "edit=" . urlencode($links[$key]);
foreach ($indexes[$links[$key]] as $col => $j) {
$link .= "&where" . urlencode("[" . bracket_escape($col) . "]") . "=" . urlencode($row[$j]);
}
}
$val = "<a href='" . h(ME . $link) . "'>$val</a>";
} }
echo "<td>$val"; echo "<td>$val";
} }
@@ -92,7 +99,7 @@ function select($result, $connection2 = null, $orgtables = array(), $limit = 0)
/** Get referencable tables with single column primary key except self /** Get referencable tables with single column primary key except self
* @param string * @param string
* @return array ($table_name => $field) * @return array [$table_name => $field]
*/ */
function referencable_primary($self) { function referencable_primary($self) {
$return = array(); // table_name => field $return = array(); // table_name => field
@@ -145,8 +152,7 @@ function set_adminer_settings($settings) {
* @return null * @return null
*/ */
function textarea($name, $value, $rows = 10, $cols = 80) { 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'>";
echo "<textarea name='$name' rows='$rows' cols='$cols' class='sqlarea jush-$jush' spellcheck='false' wrap='off'>";
if (is_array($value)) { if (is_array($value)) {
foreach ($value as $val) { // not implode() to save memory foreach ($value as $val) { // not implode() to save memory
echo h($val[0]) . "\n\n\n"; // $val == array($query, $time, $elapsed) echo h($val[0]) . "\n\n\n"; // $val == array($query, $time, $elapsed)
@@ -157,6 +163,41 @@ function textarea($name, $value, $rows = 10, $cols = 80) {
echo "</textarea>"; echo "</textarea>";
} }
/** Generate HTML <select> or <input> if $options are empty
* @param string
* @param array
* @param string
* @param string
* @param string
* @return string
*/
function select_input($attrs, $options, $value = "", $onchange = "", $placeholder = "") {
$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 or "" to close the object
* @param string
* @return null
*/
function json_row($key, $val = null) {
static $first = true;
if ($first) {
echo "{";
}
if ($key != "") {
echo ($first ? "" : ",") . "\n\t\"" . addcslashes($key, "\r\n\t\"\\/") . '": ' . ($val !== null ? '"' . addcslashes($val, "\r\n\"\\/") . '"' : 'null');
$first = false;
} else {
echo "\n}\n";
$first = true;
}
}
/** Print table columns for type edit /** Print table columns for type edit
* @param string * @param string
* @param array * @param array
@@ -166,25 +207,46 @@ function textarea($name, $value, $rows = 10, $cols = 80) {
* @return null * @return null
*/ */
function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_types = array()) { function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_types = array()) {
global $structured_types, $types, $unsigned, $on_actions; global $driver;
$type = $field["type"]; $type = $field["type"];
?> ?><td><select name="<?php echo h($key); ?>[type]" class="type" aria-labelledby="label-type"><?php
<td><select name="<?php echo h($key); ?>[type]" class="type" aria-labelledby="label-type"><?php if ($type && !array_key_exists($type, $driver->types()) && !isset($foreign_keys[$type]) && !in_array($type, $extra_types)) {
if ($type && !isset($types[$type]) && !isset($foreign_keys[$type]) && !in_array($type, $extra_types)) {
$extra_types[] = $type; $extra_types[] = $type;
} }
$structured_types = $driver->structuredTypes();
if ($foreign_keys) { if ($foreign_keys) {
$structured_types[lang('Foreign keys')] = $foreign_keys; $structured_types[lang('Foreign keys')] = $foreign_keys;
} }
echo optionlist(array_merge($extra_types, $structured_types), $type); echo optionlist(array_merge($extra_types, $structured_types), $type);
?></select> ?></select><td><input
<?php echo on_help("getTarget(event).value", 1); ?> name="<?php echo h($key); ?>[length]"
<?php echo script("mixin(qsl('select'), {onfocus: function () { lastType = selectValue(this); }, onchange: editingTypeChange});", ""); ?> value="<?php echo h($field["length"]); ?>"
<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"><?php echo script("mixin(qsl('input'), {onfocus: editingLengthFocus, oninput: editingLengthChange});", ""); ?><td class="options"><?php size="3"
echo "<select name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>'; <?php echo (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : ""); //! type="number" with enabled JavaScript ?>
echo ($unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : ''); aria-labelledby="label-length"><td class="options"><?php
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 ($collations ? "<select name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>' : '');
echo ($foreign_keys ? "<select name='" . h($key) . "[on_delete]'" . (preg_match("~`~", $type) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", $on_actions), $field["on_delete"]) . "</select> " : " "); // space for IE echo ($driver->unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match(number_type(), $type) ? "" : " class='hidden'") . '><option>' . optionlist($driver->unsigned, $field["unsigned"]) . '</select>' : '');
echo (isset($field['on_update']) ? "<select name='" . h($key) . "[on_update]'" . (preg_match('~timestamp|datetime~', $type) ? "" : " class='hidden'") . '>'
. optionlist(array("" => "(" . lang('ON UPDATE') . ")", "CURRENT_TIMESTAMP"), (preg_match('~^CURRENT_TIMESTAMP~i', $field["on_update"]) ? "CURRENT_TIMESTAMP" : $field["on_update"]))
. '</select>' : ''
);
echo ($foreign_keys ? "<select name='" . h($key) . "[on_delete]'" . (preg_match("~`~", $type) ? "" : " class='hidden'") . "><option value=''>(" . lang('ON DELETE') . ")" . optionlist(explode("|", $driver->onActions), $field["on_delete"]) . "</select> " : " "); // space for IE
}
/** Get partition info
* @param string
* @return array
*/
function get_partitions_info($table) {
global $connection;
$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 /** Filter length value including enums
@@ -192,7 +254,8 @@ echo optionlist(array_merge($extra_types, $structured_types), $type);
* @return string * @return string
*/ */
function process_length($length) { function process_length($length) {
global $enum_length; global $driver;
$enum_length = $driver->enumLength;
return (preg_match("~^\\s*\\(?\\s*$enum_length(?:\\s*,\\s*$enum_length)*+\\s*\\)?\\s*\$~", $length) && preg_match_all("~$enum_length~", $length, $matches) return (preg_match("~^\\s*\\(?\\s*$enum_length(?:\\s*,\\s*$enum_length)*+\\s*\\)?\\s*\$~", $length) && preg_match_all("~$enum_length~", $length, $matches)
? "(" . implode(",", $matches[0]) . ")" ? "(" . implode(",", $matches[0]) . ")"
: preg_replace('~^[0-9].*~', '(\0)', preg_replace('~[^-0-9,+()[\]]~', '', $length)) : preg_replace('~^[0-9].*~', '(\0)', preg_replace('~[^-0-9,+()[\]]~', '', $length))
@@ -205,20 +268,24 @@ function process_length($length) {
* @return string * @return string
*/ */
function process_type($field, $collate = "COLLATE") { function process_type($field, $collate = "COLLATE") {
global $unsigned; global $driver;
return " $field[type]" return " $field[type]"
. process_length($field["length"]) . process_length($field["length"])
. (preg_match(number_type(), $field["type"]) && in_array($field["unsigned"], $unsigned) ? " $field[unsigned]" : "") . (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 " . q($field["collation"]) : "") . (preg_match('~char|text|enum|set~', $field["type"]) && $field["collation"] ? " $collate " . (JUSH == "mssql" ? $field["collation"] : q($field["collation"])) : "")
; ;
} }
/** Create SQL string from field /** Create SQL string from field
* @param array basic field information * @param array basic field information
* @param array information about field type * @param array information about field type
* @return array array("field", "type", "NULL", "DEFAULT", "ON UPDATE", "COMMENT", "AUTO_INCREMENT") * @return array ["field", "type", "NULL", "DEFAULT", "ON UPDATE", "COMMENT", "AUTO_INCREMENT"]
*/ */
function process_field($field, $type_field) { function process_field($field, $type_field) {
// MariaDB exports CURRENT_TIMESTAMP as a function.
if ($field["on_update"]) {
$field["on_update"] = str_ireplace("current_timestamp()", "CURRENT_TIMESTAMP", $field["on_update"]);
}
return array( return array(
idf_escape(trim($field["field"])), idf_escape(trim($field["field"])),
process_type($type_field), process_type($type_field),
@@ -235,8 +302,16 @@ function process_field($field, $type_field) {
* @return string * @return string
*/ */
function default_value($field) { function default_value($field) {
global $driver;
$default = $field["default"]; $default = $field["default"];
return ($default === null ? "" : " DEFAULT " . (preg_match('~char|binary|text|enum|set~', $field["type"]) || preg_match('~^(?![a-z])~i', $default) ? q($default) : $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|enum|set~', $field["type"]) || preg_match('~^(?![a-z])~i', $default))
? q($default)
: str_ireplace("current_timestamp()", "CURRENT_TIMESTAMP", (JUSH == "sqlite" ? "($default)" : $default))
)
));
} }
/** Get type class to use in CSS /** Get type class to use in CSS
@@ -244,12 +319,14 @@ function default_value($field) {
* @return string class='' * @return string class=''
*/ */
function type_class($type) { function type_class($type) {
foreach (array( foreach (
array(
'char' => 'text', 'char' => 'text',
'date' => 'time|year', 'date' => 'time|year',
'binary' => 'blob', 'binary' => 'blob',
'enum' => 'set', 'enum' => 'set',
) as $key => $val) { ) as $key => $val
) {
if (preg_match("~$key|$val~", $type)) { if (preg_match("~$key|$val~", $type)) {
return " class='$key'"; return " class='$key'";
} }
@@ -264,26 +341,28 @@ function type_class($type) {
* @return null * @return null
*/ */
function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = array()) { function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = array()) {
global $inout; global $driver;
$fields = array_values($fields); $fields = array_values($fields);
$default_class = (($_POST ? $_POST["defaults"] : adminer_setting("defaults")) ? "" : " class='hidden'");
$comment_class = (($_POST ? $_POST["comments"] : adminer_setting("comments")) ? "" : " class='hidden'");
?> ?>
<thead><tr> <thead><tr>
<?php if ($type == "PROCEDURE") { ?><td><?php } ?> <?php echo ($type == "PROCEDURE" ? "<td>" : ""); ?>
<th id="label-name"><?php echo ($type == "TABLE" ? lang('Column name') : lang('Parameter name')); ?> <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-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 id="label-length"><?php echo lang('Length'); ?>
<td><?php echo lang('Options'); /* no label required, options have their own label */ ?> <td><?php echo lang('Options'); /* no label required, options have their own label */ ?>
<?php if ($type == "TABLE") { ?> <?php if ($type == "TABLE") { ?>
<td id="label-null">NULL <td id="label-null">NULL
<td><input type="radio" name="auto_increment_col" value=""><acronym id="label-ai" title="<?php echo lang('Auto Increment'); ?>">AI</acronym><?php echo doc_link(array( <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", 'sql' => "example-auto-increment.html",
'mariadb' => "auto_increment/", 'mariadb' => "auto_increment/",
'sqlite' => "autoinc.html", 'sqlite' => "autoinc.html",
'pgsql' => "datatype.html#DATATYPE-SERIAL", 'pgsql' => "datatype-numeric.html#DATATYPE-SERIAL",
'mssql' => "ms186775.aspx", 'mssql' => "t-sql/statements/create-table-transact-sql-identity-property",
)); ?> )); ?>
<td id="label-default"><?php echo lang('Default value'); ?> <td id="label-default"<?php echo $default_class; ?>><?php echo lang('Default value'); ?>
<?php echo (support("comment") ? "<td id='label-comment'>" . lang('Comment') : ""); ?> <?php echo (support("comment") ? "<td id='label-comment'$comment_class>" . lang('Comment') : ""); ?>
<?php } ?> <?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) . ";"); ?> <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> </thead>
@@ -296,15 +375,23 @@ function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = arra
$display = (isset($_POST["add"][$i-1]) || (isset($field["field"]) && !$_POST["drop_col"][$i])) && (support("drop_col") || $orig == ""); $display = (isset($_POST["add"][$i-1]) || (isset($field["field"]) && !$_POST["drop_col"][$i])) && (support("drop_col") || $orig == "");
?> ?>
<tr<?php echo ($display ? "" : " style='display: none;'"); ?>> <tr<?php echo ($display ? "" : " style='display: none;'"); ?>>
<?php echo ($type == "PROCEDURE" ? "<td>" . html_select("fields[$i][inout]", explode("|", $inout), $field["inout"]) : ""); ?> <?php echo ($type == "PROCEDURE" ? "<td>" . html_select("fields[$i][inout]", explode("|", $driver->inout), $field["inout"]) : "") . "<th>"; ?>
<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 echo script("qsl('input').oninput = function () { editingNameChange.call(this);" . ($field["field"] != "" || count($fields) > 1 ? "" : " editingAddRow.call(this);") . " };", ""); ?><?php } ?> <?php if ($display) { ?>
<input type="hidden" name="fields[<?php echo $i; ?>][orig]" value="<?php echo h($orig); ?>"> <input name="fields[<?php echo $i; ?>][field]" value="<?php echo h($field["field"]); ?>" data-maxlength="64" autocapitalize="off" aria-labelledby="label-name">
<?php edit_type("fields[$i]", $field, $collations, $foreign_keys); ?> <?php } ?>
<?php if ($type == "TABLE") { ?> <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><?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 <td><label class="block"><input type="radio" name="auto_increment_col" value="<?php echo $i; ?>"<?php echo ($field["auto_increment"] ? " checked" : ""); ?> aria-labelledby="label-ai"></label><td<?php echo $default_class; ?>><?php
echo 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 ($driver->generated
echo (support("comment") ? "<td><input name='fields[$i][comment]' value='" . h($field["comment"]) . "' data-maxlength='" . (min_version(5.5) ? 1024 : 255) . "' aria-labelledby='label-comment'>" : ""); ? "<select name='fields[$i][generated]'>" . optionlist(array_merge(array("", "DEFAULT"), $driver->generated), $field["generated"]) . "</select> "
: checkbox("fields[$i][generated]", 1, $field["generated"], "", "", "", "label-default")
);
?>
<input name="fields[<?php echo $i; ?>][default]" value="<?php echo h($field["default"]); ?>" aria-labelledby="label-default"><?php
echo (support("comment") ? "<td$comment_class><input name='fields[$i][comment]' value='" . h($field["comment"]) . "' data-maxlength='" . (min_version(5.5) ? 1024 : 255) . "' aria-labelledby='label-comment'>" : "");
} }
echo "<td>"; echo "<td>";
echo (support("move_col") ? echo (support("move_col") ?
@@ -426,11 +513,10 @@ function drop_create($drop, $create, $drop_created, $test, $drop_test, $location
* @return string * @return string
*/ */
function create_trigger($on, $row) { function create_trigger($on, $row) {
global $jush; $timing_event = " $row[Timing] $row[Event]" . (preg_match('~ OF~', $row["Event"]) ? " $row[Of]" : ""); // SQL injection
$timing_event = " $row[Timing] $row[Event]" . ($row["Event"] == "UPDATE OF" ? " " . idf_escape($row["Of"]) : "");
return "CREATE TRIGGER " return "CREATE TRIGGER "
. idf_escape($row["Trigger"]) . idf_escape($row["Trigger"])
. ($jush == "mssql" ? $on . $timing_event : $timing_event . $on) . (JUSH == "mssql" ? $on . $timing_event : $timing_event . $on)
. rtrim(" $row[Type]\n$row[Statement]", ";") . rtrim(" $row[Type]\n$row[Statement]", ";")
. ";" . ";"
; ;
@@ -442,22 +528,22 @@ function create_trigger($on, $row) {
* @return string * @return string
*/ */
function create_routine($routine, $row) { function create_routine($routine, $row) {
global $inout, $jush; global $driver;
$set = array(); $set = array();
$fields = (array) $row["fields"]; $fields = (array) $row["fields"];
ksort($fields); // enforce fields order ksort($fields); // enforce fields order
foreach ($fields as $field) { foreach ($fields as $field) {
if ($field["field"] != "") { if ($field["field"] != "") {
$set[] = (preg_match("~^($inout)\$~", $field["inout"]) ? "$field[inout] " : "") . idf_escape($field["field"]) . process_type($field, "CHARACTER SET"); $set[] = (preg_match("~^($driver->inout)\$~", $field["inout"]) ? "$field[inout] " : "") . idf_escape($field["field"]) . process_type($field, "CHARACTER SET");
} }
} }
$definition = rtrim("\n$row[definition]", ";"); $definition = rtrim($row["definition"], ";");
return "CREATE $routine " return "CREATE $routine "
. idf_escape(trim($row["name"])) . idf_escape(trim($row["name"]))
. " (" . implode(", ", $set) . ")" . " (" . implode(", ", $set) . ")"
. (isset($_GET["function"]) ? " RETURNS" . process_type($row["returns"], "CHARACTER SET") : "") . ($routine == "FUNCTION" ? " RETURNS" . process_type($row["returns"], "CHARACTER SET") : "")
. ($row["language"] ? " LANGUAGE $row[language]" : "") . ($row["language"] ? " LANGUAGE $row[language]" : "")
. ($jush == "pgsql" ? " AS " . q($definition) : "$definition;") . (JUSH == "pgsql" ? " AS " . q($definition) : "\n$definition;")
; ;
} }
@@ -470,20 +556,20 @@ function remove_definer($query) {
} }
/** Format foreign key to use in SQL query /** Format foreign key to use in SQL query
* @param array ("db" => string, "ns" => string, "table" => string, "source" => array, "target" => array, "on_delete" => one of $on_actions, "on_update" => one of $on_actions) * @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 * @return string
*/ */
function format_foreign_key($foreign_key) { function format_foreign_key($foreign_key) {
global $on_actions; global $driver;
$db = $foreign_key["db"]; $db = $foreign_key["db"];
$ns = $foreign_key["ns"]; $ns = $foreign_key["ns"];
return " FOREIGN KEY (" . implode(", ", array_map('idf_escape', $foreign_key["source"])) . ") REFERENCES " return " FOREIGN KEY (" . implode(", ", array_map('Adminer\idf_escape', $foreign_key["source"])) . ") REFERENCES "
. ($db != "" && $db != $_GET["db"] ? idf_escape($db) . "." : "") . ($db != "" && $db != $_GET["db"] ? idf_escape($db) . "." : "")
. ($ns != "" && $ns != $_GET["ns"] ? idf_escape($ns) . "." : "") . ($ns != "" && $ns != $_GET["ns"] ? idf_escape($ns) . "." : "")
. table($foreign_key["table"]) . idf_escape($foreign_key["table"])
. " (" . implode(", ", array_map('idf_escape', $foreign_key["target"])) . ")" //! reuse $name - check in older MySQL versions . " (" . implode(", ", array_map('Adminer\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("~^($driver->onActions)\$~", $foreign_key["on_delete"]) ? " ON DELETE $foreign_key[on_delete]" : "")
. (preg_match("~^($on_actions)\$~", $foreign_key["on_update"]) ? " ON UPDATE $foreign_key[on_update]" : "") . (preg_match("~^($driver->onActions)\$~", $foreign_key["on_update"]) ? " ON UPDATE $foreign_key[on_update]" : "")
; ;
} }
@@ -512,34 +598,37 @@ function tar_file($filename, $tmp_file) {
function ini_bytes($ini) { function ini_bytes($ini) {
$val = ini_get($ini); $val = ini_get($ini);
switch (strtolower(substr($val, -1))) { switch (strtolower(substr($val, -1))) {
case 'g': $val *= 1024; // no break case 'g':
case 'm': $val *= 1024; // no break $val = (int) $val * 1024; // no break
case 'k': $val *= 1024; case 'm':
$val = (int) $val * 1024; // no break
case 'k':
$val = (int) $val * 1024;
} }
return $val; return $val;
} }
/** Create link to database documentation /** Create link to database documentation
* @param array $jush => $path * @param array JUSH => $path
* @param string HTML code * @param string HTML code
* @return string HTML code * @return string HTML code
*/ */
function doc_link($paths, $text = "<sup>?</sup>") { function doc_link($paths, $text = "<sup>?</sup>") {
global $jush, $connection; global $connection;
$server_info = $connection->server_info; $server_info = $connection->server_info;
$version = preg_replace('~^(\d\.?\d).*~s', '\1', $server_info); // two most significant digits $version = preg_replace('~^(\d\.?\d).*~s', '\1', $server_info); // two most significant digits
$urls = array( $urls = array(
'sql' => "https://dev.mysql.com/doc/refman/$version/en/", 'sql' => "https://dev.mysql.com/doc/refman/$version/en/",
'sqlite' => "https://www.sqlite.org/", 'sqlite' => "https://www.sqlite.org/",
'pgsql' => "https://www.postgresql.org/docs/$version/", 'pgsql' => "https://www.postgresql.org/docs/$version/",
'mssql' => "https://msdn.microsoft.com/library/", 'mssql' => "https://learn.microsoft.com/en-us/sql/",
'oracle' => "https://www.oracle.com/pls/topic/lookup?ctx=db" . preg_replace('~^.* (\d+)\.(\d+)\.\d+\.\d+\.\d+.*~s', '\1\2', $server_info) . "&id=", 'oracle' => "https://www.oracle.com/pls/topic/lookup?ctx=db" . preg_replace('~^.* (\d+)\.(\d+)\.\d+\.\d+\.\d+.*~s', '\1\2', $server_info) . "&id=",
); );
if (preg_match('~MariaDB~', $server_info)) { if (preg_match('~MariaDB~', $server_info)) {
$urls['sql'] = "https://mariadb.com/kb/en/library/"; $urls['sql'] = "https://mariadb.com/kb/en/";
$paths['sql'] = (isset($paths['mariadb']) ? $paths['mariadb'] : str_replace(".html", "/", $paths['sql'])); $paths['sql'] = (isset($paths['mariadb']) ? $paths['mariadb'] : str_replace(".html", "/", $paths['sql']));
} }
return ($paths[$jush] ? "<a href='$urls[$jush]$paths[$jush]'" . target_blank() . ">$text</a>" : ""); return ($paths[JUSH] ? "<a href='" . h($urls[JUSH] . $paths[JUSH] . (JUSH == 'mssql' ? "?view=sql-server-ver$version" : "")) . "'" . target_blank() . ">$text</a>" : "");
} }
/** Wrap gzencode() for usage in ob_start() /** Wrap gzencode() for usage in ob_start()
@@ -547,7 +636,7 @@ function doc_link($paths, $text = "<sup>?</sup>") {
* @return string * @return string
*/ */
function ob_gzencode($string) { function ob_gzencode($string) {
// ob_start() callback recieves an optional parameter $phase but gzencode() accepts optional parameter $level // ob_start() callback receives an optional parameter $phase but gzencode() accepts optional parameter $level
return gzencode($string); return gzencode($string);
} }

View File

@@ -0,0 +1,7 @@
<?php
namespace Adminer;
error_reporting(6135); // errors and warnings
set_error_handler(function ($errno, $errstr) {
return !!preg_match('~^(Trying to access array offset on( value of type)? null|Undefined (array key|property))~', $errstr);
}, E_WARNING);

View File

@@ -1,6 +1,10 @@
<?php <?php
namespace Adminer;
// This file is used both in Adminer and Adminer Editor.
/** Get database connection /** Get database connection
* @return Min_DB * @return Db
*/ */
function connection() { function connection() {
// can be used in customization, $connection is minified // can be used in customization, $connection is minified
@@ -29,6 +33,9 @@ function version() {
* @return string * @return string
*/ */
function idf_unescape($idf) { function idf_unescape($idf) {
if (!preg_match('~^[`\'"[]~', $idf)) {
return $idf;
}
$last = substr($idf, -1); $last = substr($idf, -1);
return str_replace($last . $last, $last, substr($idf, 1, -1)); return str_replace($last . $last, $last, substr($idf, 1, -1));
} }
@@ -62,7 +69,7 @@ function number_type() {
* @return null modified in place * @return null modified in place
*/ */
function remove_slashes($process, $filter = false) { function remove_slashes($process, $filter = false) {
if (get_magic_quotes_gpc()) { if (function_exists("get_magic_quotes_gpc") && get_magic_quotes_gpc()) {
while (list($key, $val) = each($process)) { while (list($key, $val) = each($process)) {
foreach ($val as $k => $v) { foreach ($val as $k => $v) {
unset($process[$key][$k]); unset($process[$key][$k]);
@@ -91,7 +98,7 @@ function bracket_escape($idf, $back = false) {
/** Check if connection has at least the given version /** Check if connection has at least the given version
* @param string required version * @param string required version
* @param string required MariaDB version * @param string required MariaDB version
* @param Min_DB defaults to $connection * @param Db defaults to $connection
* @return bool * @return bool
*/ */
function min_version($version, $maria_db = "", $connection2 = null) { function min_version($version, $maria_db = "", $connection2 = null) {
@@ -104,11 +111,11 @@ function min_version($version, $maria_db = "", $connection2 = null) {
$server_info = $match[1]; $server_info = $match[1];
$version = $maria_db; $version = $maria_db;
} }
return (version_compare($server_info, $version) >= 0); return $version && version_compare($server_info, $version) >= 0;
} }
/** Get connection charset /** Get connection charset
* @param Min_DB * @param Db
* @return string * @return string
*/ */
function charset($connection) { function charset($connection) {
@@ -197,7 +204,11 @@ function optionlist($options, $selected = null, $use_keys = false) {
$opts = $v; $opts = $v;
} }
foreach ($opts as $key => $val) { foreach ($opts as $key => $val) {
$return .= '<option' . ($use_keys || is_string($key) ? ' value="' . h($key) . '"' : '') . (($use_keys || is_string($key) ? (string) $key : $val) === $selected ? ' selected' : '') . '>' . h($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)) { if (is_array($v)) {
$return .= '</optgroup>'; $return .= '</optgroup>';
@@ -229,22 +240,6 @@ function html_select($name, $options, $value = "", $onchange = true, $labelled_b
return $return; return $return;
} }
/** Generate HTML <select> or <input> if $options are empty
* @param string
* @param array
* @param string
* @param string
* @param string
* @return string
*/
function select_input($attrs, $options, $value = "", $onchange = "", $placeholder = "") {
$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
}
/** Get onclick confirmation /** Get onclick confirmation
* @param string * @param string
* @param string * @param string
@@ -277,18 +272,6 @@ function bold($bold, $class = "") {
return ($bold ? " class='active $class'" : ($class ? " class='$class'" : "")); return ($bold ? " class='active $class'" : ($class ? " class='$class'" : ""));
} }
/** Generate class for odd rows
* @param string return this for odd rows, empty to reset counter
* @return string
*/
function odd($return = ' class="odd"') {
static $i = 0;
if (!$return) { // reset counter
$i = -1;
}
return ($i++ % 2 ? $return : '');
}
/** Escape string for JavaScript apostrophes /** Escape string for JavaScript apostrophes
* @param string * @param string
* @return string * @return string
@@ -297,25 +280,6 @@ function js_escape($string) {
return addcslashes($string, "\r\n'\\/"); // slash for <script> return addcslashes($string, "\r\n'\\/"); // slash for <script>
} }
/** Print one row in JSON object
* @param string or "" to close the object
* @param string
* @return null
*/
function json_row($key, $val = null) {
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;
}
}
/** Get INI boolean value /** Get INI boolean value
* @param string * @param string
* @return bool * @return bool
@@ -325,7 +289,7 @@ function ini_bool($ini) {
return (preg_match('~^(on|true|yes)$~i', $val) || (int) $val); // boolean values set by php_value are strings return (preg_match('~^(on|true|yes)$~i', $val) || (int) $val); // boolean values set by php_value are strings
} }
/** Check if SID is neccessary /** Check if SID is necessary
* @return bool * @return bool
*/ */
function sid() { function sid() {
@@ -392,7 +356,7 @@ function get_vals($query, $column = 0) {
/** Get keys from first column and values from second /** Get keys from first column and values from second
* @param string * @param string
* @param Min_DB * @param Db
* @param bool * @param bool
* @return array * @return array
*/ */
@@ -417,7 +381,7 @@ function get_key_vals($query, $connection2 = null, $set_keys = true) {
/** Get all rows of result /** Get all rows of result
* @param string * @param string
* @param Min_DB * @param Db
* @param string * @param string
* @return array of associative arrays * @return array of associative arrays
*/ */
@@ -430,7 +394,7 @@ function get_rows($query, $connection2 = null, $error = "<p class='error'>") {
while ($row = $result->fetch_assoc()) { while ($row = $result->fetch_assoc()) {
$return[] = $row; $return[] = $row;
} }
} elseif (!$result && !is_object($connection2) && $error && defined("PAGE_HEADER")) { } elseif (!$result && !is_object($connection2) && $error && (defined('Adminer\PAGE_HEADER') || $error == "-- ")) {
echo $error . error() . "\n"; echo $error . error() . "\n";
} }
return $return; return $return;
@@ -473,18 +437,19 @@ function escape_key($key) {
* @return string * @return string
*/ */
function where($where, $fields = array()) { function where($where, $fields = array()) {
global $connection, $jush; global $connection;
$return = array(); $return = array();
foreach ((array) $where["where"] as $key => $val) { foreach ((array) $where["where"] as $key => $val) {
$key = bracket_escape($key, 1); // 1 - back $key = bracket_escape($key, 1); // 1 - back
$column = escape_key($key); $column = escape_key($key);
$return[] = $column $return[] = $column
. ($jush == "sql" && is_numeric($val) && preg_match('~\.~', $val) ? " LIKE " . q($val) // LIKE because of floats but slow with ints . (JUSH == "sql" && $fields[$key]["type"] == "json" ? " = CAST(" . q($val) . " AS JSON)"
: ($jush == "mssql" ? " LIKE " . q(preg_replace('~[_%[]~', '[\0]', $val)) // LIKE because of text : (JUSH == "sql" && is_numeric($val) && preg_match('~\.~', $val) ? " LIKE " . q($val) // LIKE because of floats but slow with ints
: (JUSH == "mssql" ? " LIKE " . q(preg_replace('~[_%[]~', '[\0]', $val)) // LIKE because of text
: " = " . unconvert_field($fields[$key], q($val)) : " = " . unconvert_field($fields[$key], q($val))
)) )))
; //! enum and set ; //! enum and set
if ($jush == "sql" && preg_match('~char|text~', $fields[$key]["type"]) && preg_match("~[^ -@]~", $val)) { // not just [a-z] to catch non-ASCII characters if (JUSH == "sql" && preg_match('~char|text~', $fields[$key]["type"]) && preg_match("~[^ -@]~", $val)) { // not just [a-z] to catch non-ASCII characters
$return[] = "$column = " . q($val) . " COLLATE " . charset($connection) . "_bin"; $return[] = "$column = " . q($val) . " COLLATE " . charset($connection) . "_bin";
} }
} }
@@ -539,17 +504,19 @@ function convert_fields($columns, $fields, $select = array()) {
/** Set cookie valid on current path /** Set cookie valid on current path
* @param string * @param string
* @param string * @param string
* @param int number of seconds, 0 for session cookie * @param int number of seconds, 0 for session cookie, 2592000 - 30 days
* @return bool * @return bool
*/ */
function cookie($name, $value, $lifetime = 2592000) { // 2592000 - 30 days function cookie($name, $value, $lifetime = 2592000) {
global $HTTPS; global $HTTPS;
return header("Set-Cookie: $name=" . urlencode($value) return header(
"Set-Cookie: $name=" . urlencode($value)
. ($lifetime ? "; expires=" . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT" : "") . ($lifetime ? "; expires=" . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT" : "")
. "; path=" . preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"]) . "; path=" . preg_replace('~\?.*~', '', $_SERVER["REQUEST_URI"])
. ($HTTPS ? "; secure" : "") . ($HTTPS ? "; secure" : "")
. "; HttpOnly; SameSite=lax", . "; HttpOnly; SameSite=lax",
false); false
);
} }
/** Restart stopped session /** Restart stopped session
@@ -670,7 +637,7 @@ function query_redirect($query, $location, $message, $redirect = true, $execute
/** Execute and remember query /** Execute and remember query
* @param string or null to return remembered queries, end with ';' to use DELIMITER * @param string or null to return remembered queries, end with ';' to use DELIMITER
* @return Min_Result or array($queries, $time) if $query = null * @return Result or [$queries, $time] if $query = null
*/ */
function queries($query) { function queries($query) {
global $connection; global $connection;
@@ -693,7 +660,7 @@ function queries($query) {
* @param callback * @param callback
* @return bool * @return bool
*/ */
function apply_queries($query, $tables, $escape = 'table') { function apply_queries($query, $tables, $escape = 'Adminer\table') {
foreach ($tables as $table) { foreach ($tables as $table) {
if (!queries("$query " . $escape($table))) { if (!queries("$query " . $escape($table))) {
return false; return false;
@@ -721,12 +688,19 @@ function format_time($start) {
return lang('%.3f s', max(0, microtime(true) - $start)); return lang('%.3f s', max(0, microtime(true) - $start));
} }
/** Get relative REQUEST_URI
* @return string
*/
function relative_uri() {
return str_replace(":", "%3a", preg_replace('~^[^?]*/([^?]*)~', '\1', $_SERVER["REQUEST_URI"]));
}
/** Remove parameter from query string /** Remove parameter from query string
* @param string * @param string
* @return string * @return string
*/ */
function remove_from_uri($param = "") { function remove_from_uri($param = "") {
return substr(preg_replace("~(?<=[?&])($param" . (SID ? "" : "|" . session_name()) . ")=[^&]*&~", '', "$_SERVER[REQUEST_URI]&"), 0, -1); return substr(preg_replace("~(?<=[?&])($param" . (SID ? "" : "|" . session_name()) . ")=[^&]*&~", '', relative_uri() . "&"), 0, -1);
} }
/** Generate page number for pagination /** Generate page number for pagination
@@ -761,7 +735,8 @@ function get_file($key, $decompress = false) {
} }
$name = $file["name"][$key]; $name = $file["name"][$key];
$tmp_name = $file["tmp_name"][$key]; $tmp_name = $file["tmp_name"][$key];
$content = file_get_contents($decompress && preg_match('~\.gz$~', $name) $content = file_get_contents(
$decompress && preg_match('~\.gz$~', $name)
? "compress.zlib://$tmp_name" ? "compress.zlib://$tmp_name"
: $tmp_name : $tmp_name
); //! may not be reachable because of open_basedir ); //! may not be reachable because of open_basedir
@@ -836,25 +811,24 @@ function format_number($val) {
*/ */
function friendly_url($val) { function friendly_url($val) {
// used for blobs and export // used for blobs and export
return preg_replace('~[^a-z0-9_]~i', '-', $val); return preg_replace('~\W~i', '-', $val);
} }
/** Print hidden fields /** Print hidden fields
* @param array * @param array
* @param array * @param array
* @param string
* @return bool * @return bool
*/ */
function hidden_fields($process, $ignore = array()) { function hidden_fields($process, $ignore = array(), $prefix = '') {
$return = false; $return = false;
while (list($key, $val) = each($process)) { foreach ($process as $key => $val) {
if (!in_array($key, $ignore)) { if (!in_array($key, $ignore)) {
if (is_array($val)) { if (is_array($val)) {
foreach ($val as $k => $v) { hidden_fields($val, array(), $key);
$process[$key . "[$k]"] = $v;
}
} else { } else {
$return = true; $return = true;
echo '<input type="hidden" name="' . h($key) . '" value="' . h($val) . '">'; echo '<input type="hidden" name="' . h($prefix ? $prefix . "[$key]" : $key) . '" value="' . h($val) . '">';
} }
} }
} }
@@ -877,12 +851,12 @@ function hidden_fields_get() {
*/ */
function table_status1($table, $fast = false) { function table_status1($table, $fast = false) {
$return = table_status($table, $fast); $return = table_status($table, $fast);
return ($return ? $return : array("Name" => $table)); return ($return ?: array("Name" => $table));
} }
/** Find out foreign keys for each column /** Find out foreign keys for each column
* @param string * @param string
* @return array array($col => array()) * @return array [$col => []]
*/ */
function column_foreign_keys($table) { function column_foreign_keys($table) {
global $adminer; global $adminer;
@@ -910,7 +884,7 @@ function enum_input($type, $attrs, $field, $value, $empty = null) {
foreach ($matches[1] as $i => $val) { foreach ($matches[1] as $i => $val) {
$val = stripcslashes(str_replace("''", "'", $val)); $val = stripcslashes(str_replace("''", "'", $val));
$checked = (is_int($value) ? $value == $i+1 : (is_array($value) ? in_array($i+1, $value) : $value === $val)); $checked = (is_int($value) ? $value == $i+1 : (is_array($value) ? in_array($i+1, $value) : $value === $val));
$return .= " <label><input type='$type'$attrs value='" . ($i+1) . "'" . ($checked ? ' checked' : '') . '>' . h($adminer->editVal($val, $field)) . '</label>'; $return .= " <label><input type='$type'$attrs value='" . (JUSH == "sql" ? $i+1 : h($val)) . "'" . ($checked ? ' checked' : '') . '>' . h($adminer->editVal($val, $field)) . '</label>';
} }
return $return; return $return;
} }
@@ -922,7 +896,7 @@ function enum_input($type, $attrs, $field, $value, $empty = null) {
* @return null * @return null
*/ */
function input($field, $value, $function) { function input($field, $value, $function) {
global $types, $adminer, $jush; global $driver, $adminer;
$name = h(bracket_escape($field["field"])); $name = h(bracket_escape($field["field"]));
echo "<td class='function'>"; echo "<td class='function'>";
if (is_array($value) && !$function) { if (is_array($value) && !$function) {
@@ -933,18 +907,28 @@ function input($field, $value, $function) {
$value = call_user_func_array('json_encode', $args); //! requires PHP 5.2 $value = call_user_func_array('json_encode', $args); //! requires PHP 5.2
$function = "json"; $function = "json";
} }
$reset = ($jush == "mssql" && $field["auto_increment"]); $reset = (JUSH == "mssql" && $field["auto_increment"]);
if ($reset && !$_POST["save"]) { if ($reset && !$_POST["save"]) {
$function = null; $function = null;
} }
$functions = (isset($_GET["select"]) || $reset ? array("orig" => lang('original')) : array()) + $adminer->editFunctions($field); $functions = (isset($_GET["select"]) || $reset ? array("orig" => lang('original')) : array()) + $adminer->editFunctions($field);
$attrs = " name='fields[$name]'"; $disabled = stripos($field["default"], "GENERATED ALWAYS AS ") === 0 ? " disabled=''" : "";
$attrs = " name='fields[$name]'$disabled";
$types = $driver->types();
$structured_types = $driver->structuredTypes();
if (in_array($field["type"], (array) $structured_types[lang('User types')])) {
$enums = type_values($types[$field["type"]]);
if ($enums) {
$field["type"] = "enum";
$field["length"] = $enums;
}
}
if ($field["type"] == "enum") { if ($field["type"] == "enum") {
echo h($functions[""]) . "<td>" . $adminer->editInput($_GET["edit"], $field, $attrs, $value); echo h($functions[""]) . "<td>" . $adminer->editInput($_GET["edit"], $field, $attrs, $value);
} else { } else {
$has_function = (in_array($function, $functions) || isset($functions[$function])); $has_function = (in_array($function, $functions) || isset($functions[$function]));
echo (count($functions) > 1 echo (count($functions) > 1
? "<select name='function[$name]'>" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>" ? "<select name='function[$name]'$disabled>" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>"
. on_help("getTarget(event).value.replace(/^SQL\$/, '')", 1) . on_help("getTarget(event).value.replace(/^SQL\$/, '')", 1)
. script("qsl('select').onchange = functionChange;", "") . script("qsl('select').onchange = functionChange;", "")
: h(reset($functions)) : h(reset($functions))
@@ -953,8 +937,8 @@ function input($field, $value, $function) {
if ($input != "") { if ($input != "") {
echo $input; echo $input;
} elseif (preg_match('~bool~', $field["type"])) { } elseif (preg_match('~bool~', $field["type"])) {
echo "<input type='hidden'$attrs value='0'>" . 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'>"; . "<input type='checkbox'" . (preg_match('~^(1|t|true|y|yes|on)$~i', $value) ? " checked='checked'" : "") . "$attrs value='1'>";
} elseif ($field["type"] == "set") { //! 64 bits } elseif ($field["type"] == "set") { //! 64 bits
preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches); preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
foreach ($matches[1] as $i => $val) { foreach ($matches[1] as $i => $val) {
@@ -965,7 +949,7 @@ function input($field, $value, $function) {
} elseif (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) { } elseif (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
echo "<input type='file' name='fields-$name'>"; echo "<input type='file' name='fields-$name'>";
} elseif (($text = preg_match('~text|lob|memo~i', $field["type"])) || preg_match("~\n~", $value)) { } elseif (($text = preg_match('~text|lob|memo~i', $field["type"])) || preg_match("~\n~", $value)) {
if ($text && $jush != "sqlite") { if ($text && JUSH != "sqlite") {
$attrs .= " cols='50' rows='12'"; $attrs .= " cols='50' rows='12'";
} else { } else {
$rows = min(12, substr_count($value, "\n") + 1); $rows = min(12, substr_count($value, "\n") + 1);
@@ -976,8 +960,11 @@ function input($field, $value, $function) {
echo "<textarea$attrs cols='50' rows='12' class='jush-js'>" . h($value) . '</textarea>'; echo "<textarea$attrs cols='50' rows='12' class='jush-js'>" . h($value) . '</textarea>';
} else { } else {
// int(3) is only a display hint // int(3) is only a display hint
$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)); $maxlength = (!preg_match('~int~', $field["type"]) && preg_match('~^(\d+)(,(\d+))?$~', $field["length"], $match)
if ($jush == 'sql' && min_version(5.6) && preg_match('~time~', $field["type"])) { ? ((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 $maxlength += 7; // microtime
} }
// type='date' and type='time' display localized value which may be confusing, type='datetime' uses 'T' as date and time separator // type='date' and type='time' display localized value which may be confusing, type='datetime' uses 'T' as date and time separator
@@ -1009,6 +996,11 @@ function input($field, $value, $function) {
*/ */
function process_input($field) { function process_input($field) {
global $adminer, $driver; global $adminer, $driver;
if (stripos($field["default"], "GENERATED ALWAYS AS ") === 0) {
return null;
}
$idf = bracket_escape($field["field"]); $idf = bracket_escape($field["field"]);
$function = $_POST["function"][$idf]; $function = $_POST["function"][$idf];
$value = $_POST["fields"][$idf]; $value = $_POST["fields"][$idf];
@@ -1109,7 +1101,7 @@ function dump_headers($identifier, $multi_table = false) {
$return = $adminer->dumpHeaders($identifier, $multi_table); $return = $adminer->dumpHeaders($identifier, $multi_table);
$output = $_POST["output"]; $output = $_POST["output"];
if ($output != "text") { if ($output != "text") {
header("Content-Disposition: attachment; filename=" . $adminer->dumpFilename($identifier) . ".$return" . ($output != "file" && !preg_match('~[^0-9a-z]~', $output) ? ".$output" : "")); header("Content-Disposition: attachment; filename=" . $adminer->dumpFilename($identifier) . ".$return" . ($output != "file" && preg_match('~^[0-9a-z]+$~', $output) ? ".$output" : ""));
} }
session_write_close(); session_write_close();
ob_flush(); ob_flush();
@@ -1123,7 +1115,7 @@ function dump_headers($identifier, $multi_table = false) {
*/ */
function dump_csv($row) { function dump_csv($row) {
foreach ($row as $key => $val) { foreach ($row as $key => $val) {
if (preg_match("~[\"\n,;\t]~", $val) || $val === "") { if (preg_match('~["\n,;\t]|^0|\.\d*0$~', $val) || $val === "") {
$row[$key] = '"' . str_replace('"', '""', $val) . '"'; $row[$key] = '"' . str_replace('"', '""', $val) . '"';
} }
} }
@@ -1232,7 +1224,7 @@ function select_value($val, $link, $field, $text_length) {
. "<td>" . select_value($v, $link, $field, $text_length) . "<td>" . select_value($v, $link, $field, $text_length)
; ;
} }
return "<table cellspacing='0'>$return</table>"; return "<table>$return</table>";
} }
if (!$link) { if (!$link) {
$link = $adminer->selectLink($val, $field); $link = $adminer->selectLink($val, $field);
@@ -1294,9 +1286,8 @@ function is_shortable($field) {
* @return string * @return string
*/ */
function count_rows($table, $where, $is_group, $group) { function count_rows($table, $where, $is_group, $group) {
global $jush;
$query = " FROM " . table($table) . ($where ? " WHERE " . implode(" AND ", $where) : ""); $query = " FROM " . table($table) . ($where ? " WHERE " . implode(" AND ", $where) : "");
return ($is_group && ($jush == "sql" || count($group) == 1) return ($is_group && (JUSH == "sql" || count($group) == 1)
? "SELECT COUNT(DISTINCT " . implode(", ", $group) . ")$query" ? "SELECT COUNT(DISTINCT " . implode(", ", $group) . ")$query"
: "SELECT COUNT(*)" . ($is_group ? " FROM (SELECT 1$query GROUP BY " . implode(", ", $group) . ") x" : $query) : "SELECT COUNT(*)" . ($is_group ? " FROM (SELECT 1$query GROUP BY " . implode(", ", $group) . ") x" : $query)
); );
@@ -1311,7 +1302,7 @@ function slow_query($query) {
$db = $adminer->database(); $db = $adminer->database();
$timeout = $adminer->queryTimeout(); $timeout = $adminer->queryTimeout();
$slow_query = $driver->slowQuery($query, $timeout); $slow_query = $driver->slowQuery($query, $timeout);
if (!$slow_query && support("kill") && is_object($connection2 = connect()) && ($db == "" || $connection2->select_db($db))) { if (!$slow_query && support("kill") && is_object($connection2 = connect($adminer->credentials())) && ($db == "" || $connection2->select_db($db))) {
$kill = $connection2->result(connection_id()); // MySQL and MySQLi can use thread_id but it's not in PDO_MySQL $kill = $connection2->result(connection_id()); // MySQL and MySQLi can use thread_id but it's not in PDO_MySQL
?> ?>
<script<?php echo nonce(); ?>> <script<?php echo nonce(); ?>>
@@ -1326,7 +1317,7 @@ var timeout = setTimeout(function () {
} }
ob_flush(); ob_flush();
flush(); flush();
$return = @get_key_vals(($slow_query ? $slow_query : $query), $connection2, false); // @ - may be killed $return = @get_key_vals(($slow_query ?: $query), $connection2, false); // @ - may be killed
if ($connection2) { if ($connection2) {
echo script("clearTimeout(timeout);"); echo script("clearTimeout(timeout);");
ob_flush(); ob_flush();
@@ -1405,17 +1396,19 @@ function on_help($command, $side = 0) {
* @param bool * @param bool
* @return null * @return null
*/ */
function edit_form($TABLE, $fields, $row, $update) { function edit_form($table, $fields, $row, $update) {
global $adminer, $jush, $token, $error; global $adminer, $token, $error;
$table_name = $adminer->tableName(table_status1($TABLE, true)); $table_name = $adminer->tableName(table_status1($table, true));
page_header( page_header(
($update ? lang('Edit') : lang('Insert')), ($update ? lang('Edit') : lang('Insert')),
$error, $error,
array("select" => array($TABLE, $table_name)), array("select" => array($table, $table_name)),
$table_name $table_name
); );
$adminer->editRowPrint($table, $fields, $row, $update);
if ($row === false) { if ($row === false) {
echo "<p class='error'>" . lang('No rows.') . "\n"; echo "<p class='error'>" . lang('No rows.') . "\n";
return;
} }
?> ?>
<form action="" method="post" enctype="multipart/form-data" id="form"> <form action="" method="post" enctype="multipart/form-data" id="form">
@@ -1423,8 +1416,8 @@ function edit_form($TABLE, $fields, $row, $update) {
if (!$fields) { if (!$fields) {
echo "<p class='error'>" . lang('You have no privileges to update this table.') . "\n"; echo "<p class='error'>" . lang('You have no privileges to update this table.') . "\n";
} else { } else {
echo "<table cellspacing='0' class='layout'>" . script("qsl('table').onkeydown = editingKeydown;"); echo "<table class='layout'>" . script("qsl('table').onkeydown = editingKeydown;");
$first = 0;
foreach ($fields as $name => $field) { foreach ($fields as $name => $field) {
echo "<tr><th>" . $adminer->fieldName($field); echo "<tr><th>" . $adminer->fieldName($field);
$default = $_GET["set"][bracket_escape($name)]; $default = $_GET["set"][bracket_escape($name)];
@@ -1435,9 +1428,9 @@ function edit_form($TABLE, $fields, $row, $update) {
} }
} }
$value = ($row !== null $value = ($row !== null
? ($row[$name] != "" && $jush == "sql" && preg_match("~enum|set~", $field["type"]) ? ($row[$name] != "" && JUSH == "sql" && preg_match("~enum|set~", $field["type"])
? (is_array($row[$name]) ? array_sum($row[$name]) : +$row[$name]) ? (is_array($row[$name]) ? array_sum($row[$name]) : +$row[$name])
: $row[$name] : (is_bool($row[$name]) ? +$row[$name] : $row[$name])
) )
: (!$update && $field["auto_increment"] : (!$update && $field["auto_increment"]
? "" ? ""
@@ -1454,10 +1447,20 @@ function edit_form($TABLE, $fields, $row, $update) {
: ($value === false ? null : ($value !== null ? '' : 'NULL')) : ($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)) { if (preg_match("~time~", $field["type"]) && preg_match('~^CURRENT_TIMESTAMP~i', $value)) {
$value = ""; $value = "";
$function = "now"; $function = "now";
} }
if ($field["type"] == "uuid" && $value == "uuid()") {
$value = "";
$function = "uuid";
}
if ($field["auto_increment"] || $function == "now" || $function == "uuid") {
$first++;
}
input($field, $value, $function); input($field, $value, $function);
echo "\n"; echo "\n";
} }
@@ -1484,7 +1487,7 @@ function edit_form($TABLE, $fields, $row, $update) {
} }
} }
echo ($update ? "<input type='submit' name='delete' value='" . lang('Delete') . "'>" . confirm() . "\n" echo ($update ? "<input type='submit' name='delete' value='" . lang('Delete') . "'>" . confirm() . "\n"
: ($_POST || !$fields ? "" : script("focus(qsa('td', qs('#form'))[1].firstChild);")) : ($_POST || !$fields ? "" : script("focus(qsa('td', qs('#form'))[2*$first+1].firstChild);"))
); );
if (isset($_GET["select"])) { if (isset($_GET["select"])) {
hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"])); hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"]));

View File

@@ -1,11 +1,13 @@
<?php <?php
namespace Adminer;
// not used in a single language version // not used in a single language version
$langs = array( $langs = array(
'en' => 'English', // Jakub Vrána - https://www.vrana.cz 'en' => 'English', // Jakub Vrána - https://www.vrana.cz
'ar' => 'العربية', // Y.M Amine - Algeria - nbr7@live.fr 'ar' => 'العربية', // Y.M Amine - Algeria - nbr7@live.fr
'bg' => 'Български', // Deyan Delchev 'bg' => 'Български', // Deyan Delchev
'bn' => 'বাংলা', // Dipak Kumar - dipak.ndc@gmail.com 'bn' => 'বাংলা', // Dipak Kumar - dipak.ndc@gmail.com, Hossain Ahmed Saiman - hossain.ahmed@altscope.com
'bs' => 'Bosanski', // Emir Kurtovic 'bs' => 'Bosanski', // Emir Kurtovic
'ca' => 'Català', // Joan Llosas 'ca' => 'Català', // Joan Llosas
'cs' => 'Čeština', // Jakub Vrána - https://www.vrana.cz 'cs' => 'Čeština', // Jakub Vrána - https://www.vrana.cz
@@ -26,6 +28,7 @@ $langs = array(
'ka' => 'ქართული', // Saba Khmaladze skhmaladze@uglt.org 'ka' => 'ქართული', // Saba Khmaladze skhmaladze@uglt.org
'ko' => '한국어', // dalli - skcha67@gmail.com 'ko' => '한국어', // dalli - skcha67@gmail.com
'lt' => 'Lietuvių', // Paulius Leščinskas - http://www.lescinskas.lt 'lt' => 'Lietuvių', // Paulius Leščinskas - http://www.lescinskas.lt
'lv' => 'Latviešu', // Kristaps Lediņš - https://krysits.com
'ms' => 'Bahasa Melayu', // Pisyek 'ms' => 'Bahasa Melayu', // Pisyek
'nl' => 'Nederlands', // Maarten Balliauw - http://blog.maartenballiauw.be 'nl' => 'Nederlands', // Maarten Balliauw - http://blog.maartenballiauw.be
'no' => 'Norsk', // Iver Odin Kvello, mupublishing.com 'no' => 'Norsk', // Iver Odin Kvello, mupublishing.com
@@ -37,6 +40,7 @@ $langs = array(
'sk' => 'Slovenčina', // Ivan Suchy - http://www.ivansuchy.com, Juraj Krivda - http://www.jstudio.cz '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 'sl' => 'Slovenski', // Matej Ferlan - www.itdinamik.com, matej.ferlan@itdinamik.com
'sr' => 'Српски', // Nikola Radovanović - cobisimo@gmail.com 'sr' => 'Српски', // Nikola Radovanović - cobisimo@gmail.com
'sv' => 'Svenska', // rasmusolle - https://github.com/rasmusolle
'ta' => 'த‌மிழ்', // G. Sampath Kumar, Chennai, India, sampathkumar11@gmail.com 'ta' => 'த‌மிழ்', // G. Sampath Kumar, Chennai, India, sampathkumar11@gmail.com
'th' => 'ภาษาไทย', // Panya Saraphi, elect.tu@gmail.com - http://www.opencart2u.com/ 'th' => 'ภาษาไทย', // Panya Saraphi, elect.tu@gmail.com - http://www.opencart2u.com/
'tr' => 'Türkçe', // Bilgehan Korkmaz - turktron.com 'tr' => 'Türkçe', // Bilgehan Korkmaz - turktron.com
@@ -61,7 +65,7 @@ function get_lang() {
*/ */
function lang($idf, $number = null) { function lang($idf, $number = null) {
global $LANG, $translations; global $LANG, $translations;
$translation = ($translations[$idf] ? $translations[$idf] : $idf); $translation = ($translations[$idf] ?: $idf);
if (is_array($translation)) { if (is_array($translation)) {
$pos = ($number == 1 ? 0 $pos = ($number == 1 ? 0
: ($LANG == 'cs' || $LANG == 'sk' ? ($number && $number < 5 ? 1 : 2) // different forms for 1, 2-4, other : ($LANG == 'cs' || $LANG == 'sk' ? ($number && $number < 5 ? 1 : 2) // different forms for 1, 2-4, other
@@ -69,9 +73,10 @@ function lang($idf, $number = null) {
: ($LANG == 'pl' ? ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2) // different forms for 1, 2-4 except 12-14, other : ($LANG == 'pl' ? ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2) // different forms for 1, 2-4 except 12-14, other
: ($LANG == 'sl' ? ($number % 100 == 1 ? 0 : ($number % 100 == 2 ? 1 : ($number % 100 == 3 || $number % 100 == 4 ? 2 : 3))) // different forms for 1, 2, 3-4, other : ($LANG == 'sl' ? ($number % 100 == 1 ? 0 : ($number % 100 == 2 ? 1 : ($number % 100 == 3 || $number % 100 == 4 ? 2 : 3))) // different forms for 1, 2, 3-4, other
: ($LANG == 'lt' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1, 12-19, other : ($LANG == 'lt' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1, 12-19, other
: ($LANG == 'lv' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number ? 1 : 2)) // different forms for 1 except 11, other, 0
: ($LANG == 'bs' || $LANG == 'ru' || $LANG == 'sr' || $LANG == 'uk' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1 except 11, 2-4 except 12-14, other : ($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 : 1 // different forms for 1, other
))))))); // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html )))))))); // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
$translation = $translation[$pos]; $translation = $translation[$pos];
} }
$args = func_get_args(); $args = func_get_args();

View File

@@ -1,34 +1,33 @@
<?php <?php
namespace Adminer;
// PDO can be used in several database drivers // PDO can be used in several database drivers
if (extension_loaded('pdo')) { if (extension_loaded('pdo')) {
/*abstract*/ class Min_PDO extends PDO { abstract class PdoDb {
var $_result, $server_info, $affected_rows, $errno, $error; 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]);
}
}
function dsn($dsn, $username, $password, $options = array()) { function dsn($dsn, $username, $password, $options = array()) {
$options[\PDO::ATTR_ERRMODE] = \PDO::ERRMODE_SILENT;
$options[\PDO::ATTR_STATEMENT_CLASS] = array('Adminer\PdoDbStatement');
try { try {
parent::__construct($dsn, $username, $password, $options); $this->pdo = new \PDO($dsn, $username, $password, $options);
} catch (Exception $ex) { } catch (Exception $ex) {
auth_error(h($ex->getMessage())); auth_error(h($ex->getMessage()));
} }
$this->setAttribute(13, array('Min_PDOStatement')); // 13 - PDO::ATTR_STATEMENT_CLASS $this->server_info = @$this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION);
$this->server_info = @$this->getAttribute(4); // 4 - PDO::ATTR_SERVER_VERSION
} }
/*abstract function select_db($database);*/ abstract function select_db($database);
function quote($string) {
return $this->pdo->quote($string);
}
function query($query, $unbuffered = false) { function query($query, $unbuffered = false) {
$result = parent::query($query); $result = $this->pdo->query($query);
$this->error = ""; $this->error = "";
if (!$result) { if (!$result) {
list(, $this->errno, $this->error) = $this->errorInfo(); list(, $this->errno, $this->error) = $this->pdo->errorInfo();
if (!$this->error) { if (!$this->error) {
$this->error = lang('Unknown error.'); $this->error = lang('Unknown error.');
} }
@@ -75,15 +74,15 @@ if (extension_loaded('pdo')) {
} }
} }
class Min_PDOStatement extends PDOStatement { class PdoDbStatement extends \PDOStatement {
var $_offset = 0, $num_rows; var $_offset = 0, $num_rows;
function fetch_assoc() { function fetch_assoc() {
return $this->fetch(2); // PDO::FETCH_ASSOC return $this->fetch(\PDO::FETCH_ASSOC);
} }
function fetch_row() { function fetch_row() {
return $this->fetch(3); // PDO::FETCH_NUM return $this->fetch(\PDO::FETCH_NUM);
} }
function fetch_field() { function fetch_field() {
@@ -93,7 +92,11 @@ if (extension_loaded('pdo')) {
$row->charsetnr = (in_array("blob", (array) $row->flags) ? 63 : 0); $row->charsetnr = (in_array("blob", (array) $row->flags) ? 63 : 0);
return $row; return $row;
} }
}
}
$drivers = array(); function seek($offset) {
for ($i=0; $i < $offset; $i++) {
$this->fetch();
}
}
}
}

View File

@@ -1,4 +1,5 @@
<?php <?php
namespace Adminer;
class TmpFile { class TmpFile {
var $handler; var $handler;
@@ -18,5 +19,4 @@ class TmpFile {
fpassthru($this->handler); fpassthru($this->handler);
fclose($this->handler); fclose($this->handler);
} }
} }

View File

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

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
/** PHP implementation of XXTEA encryption algorithm /** PHP implementation of XXTEA encryption algorithm
* @author Ma Bingyao <andot@ujn.edu.cn> * @author Ma Bingyao <andot@ujn.edu.cn>
* @link http://www.coolcode.cn/?action=show&id=128 * @link http://www.coolcode.cn/?action=show&id=128

View File

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

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$TABLE = $_GET["indexes"]; $TABLE = $_GET["indexes"];
$index_types = array("PRIMARY", "UNIQUE", "INDEX"); $index_types = array("PRIMARY", "UNIQUE", "INDEX");
$table_status = table_status($TABLE, true); $table_status = table_status($TABLE, true);
@@ -10,13 +12,15 @@ if (preg_match('~MyISAM|M?aria' . (min_version(5.7, '10.2.2') ? '|InnoDB' : '')
} }
$indexes = indexes($TABLE); $indexes = indexes($TABLE);
$primary = array(); $primary = array();
if ($jush == "mongo") { // doesn't support primary key if (JUSH == "mongo") { // doesn't support primary key
$primary = $indexes["_id_"]; $primary = $indexes["_id_"];
unset($index_types[0]); unset($index_types[0]);
unset($indexes["_id_"]); unset($indexes["_id_"]);
} }
$row = $_POST; $row = $_POST;
if ($row) {
set_adminer_settings(array("index_options" => $row["options"]));
}
if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) { if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) {
$alter = array(); $alter = array();
foreach ($row["indexes"] as $index) { foreach ($row["indexes"] as $index) {
@@ -33,18 +37,18 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) {
$desc = $index["descs"][$key]; $desc = $index["descs"][$key];
$set[] = idf_escape($column) . ($length ? "(" . (+$length) . ")" : "") . ($desc ? " DESC" : ""); $set[] = idf_escape($column) . ($length ? "(" . (+$length) . ")" : "") . ($desc ? " DESC" : "");
$columns[] = $column; $columns[] = $column;
$lengths[] = ($length ? $length : null); $lengths[] = ($length ?: null);
$descs[] = $desc; $descs[] = $desc;
} }
} }
if ($columns) {
$existing = $indexes[$name]; $existing = $indexes[$name];
if ($existing) { if ($existing) {
ksort($existing["columns"]); ksort($existing["columns"]);
ksort($existing["lengths"]); ksort($existing["lengths"]);
ksort($existing["descs"]); ksort($existing["descs"]);
if ($index["type"] == $existing["type"] if (
$index["type"] == $existing["type"]
&& array_values($existing["columns"]) === $columns && array_values($existing["columns"]) === $columns
&& (!$existing["lengths"] || array_values($existing["lengths"]) === $lengths) && (!$existing["lengths"] || array_values($existing["lengths"]) === $lengths)
&& array_values($existing["descs"]) === $descs && array_values($existing["descs"]) === $descs
@@ -54,6 +58,7 @@ if ($_POST && !$error && !$_POST["add"] && !$_POST["drop_col"]) {
continue; continue;
} }
} }
if ($columns) {
$alter[] = array($index["type"], $name, $set); $alter[] = array($index["type"], $name, $set);
} }
} }
@@ -91,14 +96,21 @@ if (!$row) {
$indexes[] = array("columns" => array(1 => "")); $indexes[] = array("columns" => array(1 => ""));
$row["indexes"] = $indexes; $row["indexes"] = $indexes;
} }
$lengths = (JUSH == "sql" || JUSH == "mssql");
$show_options = ($_POST ? $_POST["options"] : adminer_setting("index_options"));
?> ?>
<form action="" method="post"> <form action="" method="post">
<div class="scrollable"> <div class="scrollable">
<table cellspacing="0" class="nowrap"> <table class="nowrap">
<thead><tr> <thead><tr>
<th id="label-type"><?php echo lang('Index Type'); ?> <th id="label-type"><?php echo lang('Index Type'); ?>
<th><input type="submit" class="wayoff"><?php echo lang('Column (length)'); ?> <th><input type="submit" class="wayoff"><?php
echo lang('Column') . ($lengths ? "<span class='idxopts" . ($show_options ? "" : " hidden") . "'> (" . lang('length') . ")</span>" : "");
if ($lengths || support("descidx")) {
echo checkbox("options", 1, $show_options, lang('Options'), "indexOptionsShow(this.checked)", "jsonly") . "\n";
}
?>
<th id="label-name"><?php echo lang('Name'); ?> <th id="label-name"><?php echo lang('Name'); ?>
<th><noscript><?php echo "<input type='image' class='icon' name='add[0]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>"; ?></noscript> <th><noscript><?php echo "<input type='image' class='icon' name='add[0]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>"; ?></noscript>
</thead> </thead>
@@ -124,11 +136,12 @@ foreach ($row["indexes"] as $index) {
" name='indexes[$j][columns][$i]' title='" . lang('Column') . "'", " name='indexes[$j][columns][$i]' title='" . lang('Column') . "'",
($fields ? array_combine($fields, $fields) : $fields), ($fields ? array_combine($fields, $fields) : $fields),
$column, $column,
"partial(" . ($i == count($index["columns"]) ? "indexesAddColumn" : "indexesChangeColumn") . ", '" . js_escape($jush == "sql" ? "" : $_GET["indexes"] . "_") . "')" "partial(" . ($i == count($index["columns"]) ? "indexesAddColumn" : "indexesChangeColumn") . ", '" . js_escape(JUSH == "sql" ? "" : $_GET["indexes"] . "_") . "')"
); );
echo ($jush == "sql" || $jush == "mssql" ? "<input type='number' name='indexes[$j][lengths][$i]' class='size' value='" . h($index["lengths"][$key]) . "' title='" . lang('Length') . "'>" : ""); echo "<span class='idxopts" . ($show_options ? "" : " hidden") . "'>";
echo ($lengths ? "<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 (support("descidx") ? checkbox("indexes[$j][descs][$i]", 1, $index["descs"][$key], lang('descending')) : "");
echo " </span>"; echo "</span> </span>";
$i++; $i++;
} }

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'تسجيل الدخول', 'Login' => 'تسجيل الدخول',
'Logout successful.' => 'تم تسجيل الخروج بنجاح.', 'Logout successful.' => 'تم تسجيل الخروج بنجاح.',
@@ -30,7 +32,6 @@ $translations = array(
'Create database' => 'إنشاء قاعدة بيانات', 'Create database' => 'إنشاء قاعدة بيانات',
'SQL command' => 'استعلام SQL', 'SQL command' => 'استعلام SQL',
'Logout' => 'تسجيل الخروج', 'Logout' => 'تسجيل الخروج',
'database' => 'قاعدة بيانات',
'Use' => 'استعمال', 'Use' => 'استعمال',
'No tables.' => 'لا توجد جداول.', 'No tables.' => 'لا توجد جداول.',
'select' => 'تحديد', 'select' => 'تحديد',
@@ -94,7 +95,7 @@ $translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'نوع المؤشر', 'Index Type' => 'نوع المؤشر',
'Column (length)' => 'العمود (الطول)', 'length' => 'الطول',
'View has been dropped.' => 'تم مسح العرض.', 'View has been dropped.' => 'تم مسح العرض.',
'View has been altered.' => 'تم تعديل العرض.', 'View has been altered.' => 'تم تعديل العرض.',
'View has been created.' => 'تم إنشاء العرض.', 'View has been created.' => 'تم إنشاء العرض.',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Система', 'System' => 'Система',
@@ -78,7 +80,6 @@ $translations = array(
'Data' => 'Данни', 'Data' => 'Данни',
'Database' => 'База данни', 'Database' => 'База данни',
'database' => 'база данни',
'Use' => 'Избор', 'Use' => 'Избор',
'Select database' => 'Избор на база данни', 'Select database' => 'Избор на база данни',
'Invalid database.' => 'Невалидна база данни.', 'Invalid database.' => 'Невалидна база данни.',
@@ -193,7 +194,7 @@ $translations = array(
'Alter indexes' => 'Промяна на индекси', 'Alter indexes' => 'Промяна на индекси',
'Add next' => 'Добавяне на следващ', 'Add next' => 'Добавяне на следващ',
'Index Type' => 'Вид на индекса', 'Index Type' => 'Вид на индекса',
'Column (length)' => 'Колона (дължина)', 'length' => 'дължина',
'Foreign keys' => 'Препратки', 'Foreign keys' => 'Препратки',
'Foreign key' => 'Препратка', 'Foreign key' => 'Препратка',

View File

@@ -1,53 +1,54 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'লগইন', 'Login' => 'লগইন',
'Logout successful.' => 'লগআউট সম্পন্ন হয়েছে।', 'Logout successful.' => 'সফলভাবে লগআউট হয়েছে।',
'Invalid credentials.' => 'ভুল পাসওয়ার্ড।', 'Invalid credentials.' => 'ভুল পাসওয়ার্ড।',
'Server' => 'সার্ভার', 'Server' => 'সার্ভার',
'Username' => 'ইউজারের নাম', 'Username' => 'ইউজারের নাম',
'Password' => 'পাসওয়ার্ড', 'Password' => 'পাসওয়ার্ড',
'Select database' => 'ডাটাবেজ নির্বাচন কর', 'Select database' => 'ডাটাবেজ নির্বাচন করুন',
'Invalid database.' => 'ভুল ডাটাবেজ।', 'Invalid database.' => 'অকার্যকর ডাটাবেজ।',
'Table has been dropped.' => 'টেবিল মুছে ফেলা হয়েছে।', 'Table has been dropped.' => 'টেবিল মুছে ফেলা হয়েছে।',
'Table has been altered.' => 'টেবিল সম্পাদনা করা হয়েছে।', 'Table has been altered.' => 'টেবিল পরিবর্তন করা হয়েছে।',
'Table has been created.' => 'টেবিল তৈরী করা হয়েছে।', 'Table has been created.' => 'টেবিল তৈরী করা হয়েছে।',
'Alter table' => 'টেবিল সম্পাদনা', 'Alter table' => 'টেবিল পরিবর্তন করুন',
'Create table' => 'টেবিল তৈরী কর', 'Create table' => 'টেবিল তৈরী করুন',
'Table name' => 'টেবিলের নাম', 'Table name' => 'টেবিলের নাম',
'engine' => 'ইন্জিন', 'engine' => 'ইন্জিন',
'collation' => 'কলোকেশন', 'collation' => 'সমষ্টি',
'Column name' => 'কলামের নাম', 'Column name' => 'কলামের নাম',
'Type' => 'টাইপ', 'Type' => 'ধরণ',
'Length' => 'দৈর্ঘ্য', 'Length' => 'দৈর্ঘ্য',
'Auto Increment' => 'স্বয়ংক্রিয় বৃদ্ধি', 'Auto Increment' => 'স্বয়ংক্রিয় বৃদ্ধি',
'Options' => 'অপশন', 'Options' => 'বিকল্পসমূহ',
'Save' => 'সংরক্ষণ', 'Save' => 'সংরক্ষণ করুন',
'Drop' => 'মুছে ফেলো', 'Drop' => 'মুছে ফেলো',
'Database has been dropped.' => 'ডাটাবেজ মুছে ফেলা হয়েছে।', 'Database has been dropped.' => 'ডাটাবেজ মুছে ফেলা হয়েছে।',
'Database has been created.' => 'ডাটাবেজ তৈরী করা হয়েছে।', 'Database has been created.' => 'ডাটাবেজ তৈরী করা হয়েছে।',
'Database has been renamed.' => 'ডাটাবেজের নতুন নামকরণ করা হয়েছে।', 'Database has been renamed.' => 'ডাটাবেজের নতুন নামকরণ করা হয়েছে।',
'Database has been altered.' => 'ডাটাবেজ সম্পাদনা করা হয়েছে।', 'Database has been altered.' => 'ডাটাবেজ পরিবর্তন করা হয়েছে।',
'Alter database' => 'ডাটাবেজ সম্পাদনা', 'Alter database' => 'ডাটাবেজ পরিবর্তন করুন',
'Create database' => 'ডাটাবেজ তৈরী', 'Create database' => 'ডাটাবেজ তৈরী করুন',
'SQL command' => 'SQL-কোয়্যারী', 'SQL command' => 'SQL-কমান্ড',
'Logout' => 'লগআউট', 'Logout' => 'লগআউট',
'database' => 'ডাটাবেজ',
'Use' => 'ব্যবহার', 'Use' => 'ব্যবহার',
'No tables.' => 'কোন টেবিল নাই।', 'No tables.' => 'কোন টেবিল নাই।',
'select' => 'নির্বাচন', 'select' => 'নির্বাচন',
'Item has been deleted.' => 'বিষয়বস্তু মুছে ফেলা হয়েছে।', 'Item has been deleted.' => 'বিষয়বস্তু মুছে ফেলা হয়েছে।',
'Item has been updated.' => 'বিষয়বস্তু আপডেট করা হয়েছে।', 'Item has been updated.' => 'বিষয়বস্তু হালনাগাদ করা হয়েছে।',
'Item%s has been inserted.' => 'বিষয়বস্তুসমূহ সংযোজন করা হয়েছে।', 'Item%s has been inserted.' => 'বিষয়বস্তুসমূহ সংযোজন করা হয়েছে।',
'Edit' => 'সম্পাদনা', 'Edit' => 'সম্পাদনা',
'Insert' => 'সংযোজন', 'Insert' => 'সংযোজন',
'Save and insert next' => 'সংরক্ষন ও পরবর্তী সংযোজন', 'Save and insert next' => 'সংরক্ষন ও পরবর্তী সংযোজন করুন',
'Delete' => 'মুছে ফেল', 'Delete' => 'মুছে ফেলুন',
'Database' => 'ডাটাবেজ', 'Database' => 'ডাটাবেজ',
'Routines' => 'রুটিনসমূহ', 'Routines' => 'রুটিনসমূহ',
'Indexes have been altered.' => 'সূচীসমূহ সম্পাদনা করা হয়েছে।', 'Indexes have been altered.' => 'সূচীসমূহ সম্পাদনা করা হয়েছে।',
'Indexes' => 'সূচীসমূহ', 'Indexes' => 'সূচীসমূহ',
'Alter indexes' => 'সূচীসমূহ সম্পাদনা', 'Alter indexes' => 'সূচীসমূহ পরিবর্তন করুন',
'Add next' => 'সংযোজন', 'Add next' => 'পরবর্তী সংযোজন করুন',
'Language' => 'ভাষা', 'Language' => 'ভাষা',
'Select' => 'নির্বাচন', 'Select' => 'নির্বাচন',
'New item' => 'নতুন বিষয়বস্তু', 'New item' => 'নতুন বিষয়বস্তু',
@@ -60,18 +61,18 @@ $translations = array(
'edit' => 'সম্পাদনা', 'edit' => 'সম্পাদনা',
'Page' => 'পৃষ্ঠা', 'Page' => 'পৃষ্ঠা',
'Query executed OK, %d row(s) affected.' => array('কোয়্যারী সম্পাদন হয়েছে, %d সারি প্রভাবিত হয়েছে।', 'কোয়্যারী সম্পাদন হয়েছে, %d সারি প্রভাবিত হয়েছে।'), 'Query executed OK, %d row(s) affected.' => array('কোয়্যারী সম্পাদন হয়েছে, %d সারি প্রভাবিত হয়েছে।', 'কোয়্যারী সম্পাদন হয়েছে, %d সারি প্রভাবিত হয়েছে।'),
'Error in query' => 'কোয়্যারীতে ভুল আছে।', 'Error in query' => 'অনুসন্ধানে ভুল আছে।',
'Execute' => 'সম্পাদন করো', 'Execute' => 'সম্পাদন করো',
'Table' => 'টেবিল', 'Table' => 'টেবিল',
'Foreign keys' => 'ফরেন কী', 'Foreign keys' => 'ফরেন কী',
'Triggers' => 'ট্রিগার', 'Triggers' => 'ট্রিগার',
'View' => 'ভিউ', 'View' => 'ভিউ',
'Unable to select the table' => 'টেবিল নির্বাচন করতে অক্ষম', 'Unable to select the table' => 'টেবিল নির্বাচন করতে অক্ষম',
'Invalid CSRF token. Send the form again.' => 'অবৈধ CSRF টোকেন। ফর্ম আবার পাঠা।', 'Invalid CSRF token. Send the form again.' => 'অবৈধ CSRF টোকেন। ফর্মটি আবার পাঠা।',
'Comment' => 'মন্তব্য', 'Comment' => 'মন্তব্য',
'Default values' => 'ডিফল্ট মান', 'Default values' => 'ডিফল্ট মান',
'%d byte(s)' => array('%d বাইট', '%d বাইটসমূহ'), '%d byte(s)' => array('%d বাইট', '%d বাইটসমূহ'),
'No commands to execute.' => 'সম্পাদন করার মত কোন নির্দেশ নই।', 'No commands to execute.' => 'সম্পাদন করার মত কোন নির্দেশ নই।',
'Unable to upload a file.' => 'ফাইল আপলোড করা সম্ভব হচ্ছে না।', 'Unable to upload a file.' => 'ফাইল আপলোড করা সম্ভব হচ্ছে না।',
'File upload' => 'ফাইল আপলোড', 'File upload' => 'ফাইল আপলোড',
'File uploads are disabled.' => 'ফাইল আপলোড নিষ্ক্রিয় করা আছে।', 'File uploads are disabled.' => 'ফাইল আপলোড নিষ্ক্রিয় করা আছে।',
@@ -80,70 +81,70 @@ $translations = array(
'No extension' => 'কোন এক্সটেনশান নাই', 'No extension' => 'কোন এক্সটেনশান নাই',
'None of the supported PHP extensions (%s) are available.' => 'কোন PHP সমর্থিত এক্সটেনশন (%s) পাওয়া যায় নাই।', 'None of the supported PHP extensions (%s) are available.' => 'কোন PHP সমর্থিত এক্সটেনশন (%s) পাওয়া যায় নাই।',
'Session support must be enabled.' => 'সেশন সমর্থন সক্রিয় করা আবশ্যক।', 'Session support must be enabled.' => 'সেশন সমর্থন সক্রিয় করা আবশ্যক।',
'Session expired, please login again.' => 'সেশনের মেয়াদ শেষ হয়েছে, আবার লগইন করুন।', 'Session expired, please login again.' => 'সেশনের মেয়াদ শেষ হয়েছে, আবার লগইন করুন।',
'Text length' => 'টেক্সট দৈর্ঘ্য', 'Text length' => 'টেক্সট দৈর্ঘ্য',
'Foreign key has been dropped.' => 'ফরেন কী মুছে ফেলা হয়েছে।', 'Foreign key has been dropped.' => 'ফরেন কী মুছে ফেলা হয়েছে।',
'Foreign key has been altered.' => 'ফরেন কী সম্পাদনা করা হয়েছে।', 'Foreign key has been altered.' => 'ফরেন কী পরিবর্তন করা হয়েছে।',
'Foreign key has been created.' => 'ফরেন কী তৈরী করা হয়েছে।', 'Foreign key has been created.' => 'ফরেন কী তৈরী করা হয়েছে।',
'Foreign key' => 'ফরেন কী ', 'Foreign key' => 'ফরেন কী ',
'Target table' => 'টার্গেট টেবিল', 'Target table' => 'টার্গেট টেবিল',
'Change' => 'পরিবর্তন', 'Change' => 'পরিবর্তন',
'Source' => 'উৎস', 'Source' => 'উৎস',
'Target' => 'লক্ষ্য', 'Target' => 'লক্ষ্য',
'Add column' => 'কলাম সংযোজন', 'Add column' => 'কলাম সংযোজন করুন',
'Alter' => 'সম্পাদনা', 'Alter' => 'পরিবর্তন',
'Add foreign key' => 'ফরেন কী সংযোজন কর', 'Add foreign key' => 'ফরেন কী সংযোজন করুন',
'ON DELETE' => 'অন ডিলিট', 'ON DELETE' => 'অন ডিলিট',
'ON UPDATE' => 'অন আপডেট', 'ON UPDATE' => 'অন আপডেট',
'Index Type' => 'সূচী-ধরণ', 'Index Type' => 'সূচী-ধরণ',
'Column (length)' => 'কলাম (দৈর্ঘ্য)', 'length' => 'দৈর্ঘ্য',
'View has been dropped.' => 'ভিউ মুছে ফেলা হয়েছে।', 'View has been dropped.' => 'ভিউ মুছে ফেলা হয়েছে।',
'View has been altered.' => 'ভিউ সম্পাদনা করা হয়েছে।', 'View has been altered.' => 'ভিউ পরিবর্তন করা হয়েছে।',
'View has been created.' => 'ভিউ তৈরী করা হয়েছে।', 'View has been created.' => 'ভিউ তৈরী করা হয়েছে।',
'Alter view' => 'ভিউ সম্পাদনা কর', 'Alter view' => 'ভিউ পরিবর্তন করুন',
'Create view' => 'ভিউ তৈরী কর', 'Create view' => 'ভিউ তৈরী করুন',
'Name' => 'নাম', 'Name' => 'নাম',
'Process list' => 'প্রসেস তালিকা', 'Process list' => 'প্রসেস তালিকা',
'%d process(es) have been killed.' => array('%d টি প্রসেস(সমূহ) বিনষ্ট করা হয়েছে।', '%d টি প্রসেস(সমূহ) বিনষ্ট করা হয়েছে।'), '%d process(es) have been killed.' => array('%d টি প্রসেস(সমূহ) বিনষ্ট করা হয়েছে।', '%d টি প্রসেস(সমূহ) বিনষ্ট করা হয়েছে।'),
'Kill' => 'বিনষ্ট করো', 'Kill' => 'বিনষ্ট করো',
'Parameter name' => 'প্যারামিটারের নাম', 'Parameter name' => 'প্যারামিটারের নাম',
'Database schema' => 'ডাটাবেজ স্কিমা', 'Database schema' => 'ডাটাবেজ স্কিমা',
'Create procedure' => 'প্রসিডিওর তৈরী কর', 'Create procedure' => 'কার্যপ্রণালী তৈরী করুন',
'Create function' => 'ফাংশন তৈরী কর', 'Create function' => 'ফাংশন তৈরী করুন',
'Routine has been dropped.' => 'রুটিন মুছে ফেলা হয়েছে।', 'Routine has been dropped.' => 'রুটিন মুছে ফেলা হয়েছে।',
'Routine has been altered.' => 'রুটিন সম্পাদনা করা হয়েছে।', 'Routine has been altered.' => 'রুটিন পরিবর্তন করা হয়েছে।',
'Routine has been created.' => 'রুটিন তৈরী করা হয়েছে।', 'Routine has been created.' => 'রুটিন তৈরী করা হয়েছে।',
'Alter function' => 'ফাংশন সম্পাদনা কর', 'Alter function' => 'ফাংশন পরিবর্তন করুন',
'Alter procedure' => 'প্রসিডিওর সম্পাদনা কর', 'Alter procedure' => 'কার্যপ্রণালী পরিবর্তন করুন',
'Return type' => 'রিটার্ন টাইপ', 'Return type' => 'রিটার্ন টাইপ',
'Add trigger' => 'ট্রিগার সংযোজন কর', 'Add trigger' => 'ট্রিগার সংযোজন করুন',
'Trigger has been dropped.' => 'ট্রিগার মুছে ফেলা হয়েছে।', 'Trigger has been dropped.' => 'ট্রিগার মুছে ফেলা হয়েছে।',
'Trigger has been altered.' => 'ট্রিগার সম্পাদনা করা হয়েছে।', 'Trigger has been altered.' => 'ট্রিগার পরিবর্তন করা হয়েছে।',
'Trigger has been created.' => 'ট্রিগার তৈরী করা হয়েছে।', 'Trigger has been created.' => 'ট্রিগার তৈরী করা হয়েছে।',
'Alter trigger' => 'ট্রিগার সম্পাদনা কর', 'Alter trigger' => 'ট্রিগার পরিবর্তন করুন',
'Create trigger' => 'ট্রিগার তৈরী কর', 'Create trigger' => 'ট্রিগার তৈরী করুন',
'Time' => 'সময়', 'Time' => 'সময়',
'Event' => 'ইভেন্ট', 'Event' => 'ইভেন্ট',
'%s version: %s through PHP extension %s' => 'ভার্সন %s: %s, %s PHP এক্সটেনশনের মধ্য দিয়ে', '%s version: %s through PHP extension %s' => 'ভার্সন %s: %s, %s PHP এক্সটেনশনের মধ্য দিয়ে',
'%d row(s)' => array('%d সারি', '%d সারি সমূহ'), '%d row(s)' => array('%d সারি', '%d সারি সমূহ'),
'Remove' => 'অপসারণ', 'Remove' => 'মুছে ফেলুন',
'Are you sure?' => 'তুমি কি নিশ্চিত?', 'Are you sure?' => 'আপনি কি নিশ্চিত?',
'Privileges' => 'প্রিভিলেজেস', 'Privileges' => 'প্রিভিলেজেস',
'Create user' => 'ইউজার তৈরী কর', 'Create user' => 'ব্যবহারকারি তৈরী করুন',
'User has been dropped.' => 'ইউজার মুছে ফেলা হয়েছে।', 'User has been dropped.' => 'ব্যবহারকারি মুছে ফেলা হয়েছে।',
'User has been altered.' => 'ইউজার সম্পাদনা করা হয়েছে।', 'User has been altered.' => 'ব্যবহারকারি সম্পাদনা করা হয়েছে।',
'User has been created.' => 'ইউজার তৈরী করা হয়েছে।', 'User has been created.' => 'ব্যবহারকারি তৈরী করা হয়েছে।',
'Hashed' => 'হ্যাড', 'Hashed' => 'হ্যাড',
'Column' => 'কলাম', 'Column' => 'কলাম',
'Routine' => 'রুটিন', 'Routine' => 'রুটিন',
'Grant' => 'গ্র্যান্ট', 'Grant' => 'অনুমতি',
'Revoke' => 'রিভোক', 'Revoke' => 'প্রত্যাহার',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'খুব বড় POST ডাটা। ডাটা সংক্ষিপ্ত করো অথবা %s কনফিগারেশন নির্দেশ বৃদ্ধি করো', 'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'খুব বড় POST ডাটা। ডাটা সংক্ষিপ্ত করো অথবা %s কনফিগারেশন নির্দেশ বৃদ্ধি করো',
'Logged as: %s' => '%s হিসাবে লগড', 'Logged as: %s' => '%s হিসাবে লগড',
'Move up' => 'উপরে স্থানান্তর', 'Move up' => 'উপরে স্থানান্তর',
'Move down' => 'নীচে স্থানান্তর', 'Move down' => 'নীচে স্থানান্তর',
'Functions' => 'ফাংশন সমূহ', 'Functions' => 'ফাংশন সমূহ',
'Aggregation' => 'মোট পরিমাণ', 'Aggregation' => 'সমষ্টি',
'Export' => 'এক্সপোর্ট', 'Export' => 'এক্সপোর্ট',
'Output' => 'আউটপুট', 'Output' => 'আউটপুট',
'open' => 'খোলা', 'open' => 'খোলা',
@@ -162,8 +163,8 @@ $translations = array(
'Schedule' => 'সময়সূচি', 'Schedule' => 'সময়সূচি',
'Start' => 'শুরু', 'Start' => 'শুরু',
'End' => 'সমাপ্তি', 'End' => 'সমাপ্তি',
'Status' => 'স্ট্যাটাস', 'Status' => 'অবস্থা',
'On completion preserve' => 'সমাপ্ত হওয়ার পর সংরক্ষন কর', 'On completion preserve' => 'সমাপ্ত হওয়ার পর সংরক্ষন করুন',
'Tables and views' => 'টেবিল এবং ভিউ সমূহ', 'Tables and views' => 'টেবিল এবং ভিউ সমূহ',
'Data Length' => 'ডাটার দৈর্ঘ্য', 'Data Length' => 'ডাটার দৈর্ঘ্য',
'Index Length' => 'ইনডেক্স এর দৈর্ঘ্য', 'Index Length' => 'ইনডেক্স এর দৈর্ঘ্য',
@@ -175,14 +176,14 @@ $translations = array(
'Repair' => 'মেরামত', 'Repair' => 'মেরামত',
'Truncate' => 'ছাঁটাই', 'Truncate' => 'ছাঁটাই',
'Tables have been truncated.' => 'টেবিল ছাঁটাই করা হয়েছে', 'Tables have been truncated.' => 'টেবিল ছাঁটাই করা হয়েছে',
'Rows' => 'সারি', 'Rows' => 'সারিসমূহ',
',' => ',', ',' => ',',
'0123456789' => '০১২৩৪৫৬৭৮৯', '0123456789' => '০১২৩৪৫৬৭৮৯',
'Tables have been moved.' => 'টেবিল স্থানান্তর করা হয়েছে।', 'Tables have been moved.' => 'টেবিল স্থানান্তর করা হয়েছে।',
'Move to other database' => 'অন্য ডাটাবেজে স্থানান্তর কর', 'Move to other database' => 'অন্য ডাটাবেজে স্থানান্তর করুন',
'Move' => 'স্থানান্তর কর', 'Move' => 'স্থানান্তর করুন',
'Engine' => 'ইঞ্জিন', 'Engine' => 'ইঞ্জিন',
'Save and continue edit' => 'সংরক্ষণ কর এবং সম্পাদনা চালিয়ে যা', 'Save and continue edit' => 'সংরক্ষণ করুন এবং সম্পাদনা চালিয়ে যা',
'original' => 'প্রকৃত', 'original' => 'প্রকৃত',
'Tables have been dropped.' => 'টেবিলসমূহ মুছে ফেলা হয়েছে।', 'Tables have been dropped.' => 'টেবিলসমূহ মুছে ফেলা হয়েছে।',
'%d item(s) have been affected.' => '%d টি বিষয়বস্তু প্রভাবিত হয়েছে', '%d item(s) have been affected.' => '%d টি বিষয়বস্তু প্রভাবিত হয়েছে',
@@ -196,7 +197,7 @@ $translations = array(
'%d row(s) have been imported.' => array('%d টি সারি(সমূহ) ইমপোর্ট করা হয়েছে।', '%d টি সারি(সমূহ) ইমপোর্ট করা হয়েছে।'), '%d row(s) have been imported.' => array('%d টি সারি(সমূহ) ইমপোর্ট করা হয়েছে।', '%d টি সারি(সমূহ) ইমপোর্ট করা হয়েছে।'),
'anywhere' => 'যে কোন স্থানে', 'anywhere' => 'যে কোন স্থানে',
'Import' => 'ইমপোর্ট', 'Import' => 'ইমপোর্ট',
'Stop on error' => 'ত্রুটি পেলে থেমে যা', 'Stop on error' => 'ত্রুটি পেলে থেমে যা',
'%.3f s' => '%.3f s', '%.3f s' => '%.3f s',
'$1-$3-$5' => '$6.$4.$1', '$1-$3-$5' => '$6.$4.$1',
'[yyyy]-mm-dd' => 't.m.[jjjj]', '[yyyy]-mm-dd' => 't.m.[jjjj]',
@@ -216,14 +217,14 @@ $translations = array(
'E-mail' => '​​ই-মেইল', 'E-mail' => '​​ই-মেইল',
'From' => 'থেকে', 'From' => 'থেকে',
'Subject' => 'বিষয়', 'Subject' => 'বিষয়',
'Send' => 'পাঠা', 'Send' => 'পাঠা',
'%d e-mail(s) have been sent.' => array('%d ইমেইল(গুলি) পাঠানো হয়েছে।', '%d ইমেইল(গুলি) পাঠানো হয়েছে।'), '%d e-mail(s) have been sent.' => array('%d ইমেইল(গুলি) পাঠানো হয়েছে।', '%d ইমেইল(গুলি) পাঠানো হয়েছে।'),
'Webserver file %s' => 'ওয়েবসার্ভার ফাইল %s', 'Webserver file %s' => 'ওয়েবসার্ভার ফাইল %s',
'File does not exist.' => 'ফাইলর কোন অস্তিত্ব নেই।', 'File does not exist.' => 'ফাইলটির কোন অস্তিত্ব নেই।',
'%d in total' => 'সর্বমোটঃ %d টি', '%d in total' => 'সর্বমোটঃ %d টি',
'Permanent login' => 'স্থায়ী লগইন', 'Permanent login' => 'স্থায়ী লগইন',
'Databases have been dropped.' => 'ডাটাবেজসমূহ মুছে ফেলা হয়েছে।', 'Databases have been dropped.' => 'ডাটাবেজসমূহ মুছে ফেলা হয়েছে।',
'Search data in tables' => 'টেবিলে খোঁজ করো', 'Search data in tables' => 'টেবিলে তথ্য খুঁজুন',
'Schema' => 'স্কিমা', 'Schema' => 'স্কিমা',
'Alter schema' => 'স্কিমা পরিবর্তন করো', 'Alter schema' => 'স্কিমা পরিবর্তন করো',
'Create schema' => 'স্কিমা তৈরী করো', 'Create schema' => 'স্কিমা তৈরী করো',
@@ -236,32 +237,32 @@ $translations = array(
'Sequence has been dropped.' => 'অনুক্রম মুছে ফেলা হয়েছে।', 'Sequence has been dropped.' => 'অনুক্রম মুছে ফেলা হয়েছে।',
'Sequence has been created.' => 'অনুক্রম তৈরি করা হয়েছে।', 'Sequence has been created.' => 'অনুক্রম তৈরি করা হয়েছে।',
'Sequence has been altered.' => 'অনুক্রম সম্পাদনা করা হয়েছে।', 'Sequence has been altered.' => 'অনুক্রম সম্পাদনা করা হয়েছে।',
'User types' => 'ইউজারের টাইপ', 'User types' => 'ব্যবহারকারির ধরণ',
'Create type' => 'টাইপ তৈরী কর', 'Create type' => 'ধরণ তৈরী করুন',
'Alter type' => 'টাইপ পরিবর্তন কর', 'Alter type' => 'ধরণ পরিবর্তন করুন',
'Type has been dropped.' => 'টাইপ মুছে ফেলা হয়েছে।', 'Type has been dropped.' => 'ধরণ মুছে ফেলা হয়েছে।',
'Type has been created.' => 'টাইপ তৈরি করা হয়েছে।', 'Type has been created.' => 'ধরণ তৈরি করা হয়েছে।',
'Use edit link to modify this value.' => 'এই মান পরিবর্তনের জন্য সম্পাদনা লিঙ্ক ব্যবহার কর।', 'Use edit link to modify this value.' => 'এই মানটি পরিবর্তনের জন্য সম্পাদনা লিঙ্ক ব্যবহার করুন।',
'last' => 'সর্বশেষ', 'last' => 'সর্বশেষ',
'From server' => 'সার্ভার থেকে', 'From server' => 'সার্ভার থেকে',
'System' => 'সিস্টেম', 'System' => 'সিস্টেম',
'Select data' => 'তথ্য নির্বাচন করো', 'Select data' => 'তথ্য নির্বাচন করো',
'Show structure' => 'গঠন দেখা', 'Show structure' => 'গঠন দেখা',
'empty' => 'খালি', 'empty' => 'খালি',
'Network' => 'নেটওয়ার্ক', 'Network' => 'নেটওয়ার্ক',
'Geometry' => 'জ্যামিতি', 'Geometry' => 'জ্যামিতি',
'File exists.' => 'ফাইল রয়েছে।', 'File exists.' => 'ফাইল রয়েছে।',
'Attachments' => 'সংযুক্তি', 'Attachments' => 'সংযুক্তিগুলো',
'%d query(s) executed OK.' => array('SQL-কোয়্যারী সফলভাবে সম্পন্ন হয়েছে', '%d SQL-কোয়্যারীসমূহ সফলভাবে সম্পন্ন হয়েছে'), '%d query(s) executed OK.' => array('SQL-অনুসন্ধান সফলভাবে সম্পন্ন হয়েছে', '%d SQL-অনুসন্ধানসমূহ সফলভাবে সম্পন্ন হয়েছে'),
'Show only errors' => 'শুধুমাত্র ত্রুটি দেখা', 'Show only errors' => 'শুধুমাত্র ত্রুটিগুলো দেখা',
'Refresh' => 'রিফ্রেশ', 'Refresh' => 'রিফ্রেশ',
'Invalid schema.' => 'অবৈধ স্কিমা।', 'Invalid schema.' => 'অবৈধ স্কিমা।',
'Please use one of the extensions %s.' => 'কোন একটা এক্সটেনশন %s ব্যবহার কর।', 'Please use one of the extensions %s.' => 'কোন একটা এক্সটেনশন %s ব্যবহার করুন।',
'now' => 'এখন', 'now' => 'এখন',
'ltr' => 'ltr', 'ltr' => 'ltr',
'Tables have been copied.' => 'টেবিল কপি করা হয়েছে।', 'Tables have been copied.' => 'টেবিলগুলো কপি করা হয়েছে।',
'Copy' => 'কপি', 'Copy' => 'কপি',
'Permanent link' => 'স্থায়ী লিংক', 'Permanent link' => 'স্থায়ী লিংক',
'Edit all' => 'সকল সম্পাদনা কর', 'Edit all' => 'সবগুলো সম্পাদনা করুন',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
); );

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem', 'System' => 'Sistem',
@@ -73,7 +75,6 @@ $translations = array(
'Data' => 'Podaci', 'Data' => 'Podaci',
'Database' => 'Baza podataka', 'Database' => 'Baza podataka',
'database' => 'baza podataka',
'Use' => 'Koristi', 'Use' => 'Koristi',
'Select database' => 'Izaberite bazu', 'Select database' => 'Izaberite bazu',
'Invalid database.' => 'Neispravna baza podataka.', 'Invalid database.' => 'Neispravna baza podataka.',
@@ -183,7 +184,7 @@ $translations = array(
'Alter indexes' => 'Ažuriraj indekse', 'Alter indexes' => 'Ažuriraj indekse',
'Add next' => 'Dodaj slijedeći', 'Add next' => 'Dodaj slijedeći',
'Index Type' => 'Tip indeksa', 'Index Type' => 'Tip indeksa',
'Column (length)' => 'kolumna (dužina)', 'length' => 'dužina',
'Foreign keys' => 'Strani ključevi', 'Foreign keys' => 'Strani ključevi',
'Foreign key' => 'Strani ključ', 'Foreign key' => 'Strani ključ',

View File

@@ -1,8 +1,10 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Inicia la sessió', 'Login' => 'Inicia la sessió',
'Logout successful.' => 'Desconnexió correcta.', 'Logout successful.' => 'Desconnexió correcta.',
'Invalid credentials.' => 'Credencials invàlids.', 'Invalid credentials.' => 'Credencials invàlides.',
'Server' => 'Servidor', 'Server' => 'Servidor',
'Username' => 'Nom d\'usuari', 'Username' => 'Nom d\'usuari',
'Password' => 'Contrasenya', 'Password' => 'Contrasenya',
@@ -31,11 +33,10 @@ $translations = array(
'Create database' => 'Crea una base de dades', 'Create database' => 'Crea una base de dades',
'SQL command' => 'Ordre SQL', 'SQL command' => 'Ordre SQL',
'Logout' => 'Desconnecta', 'Logout' => 'Desconnecta',
'database' => 'base de dades',
'Use' => 'Utilitza', 'Use' => 'Utilitza',
'No tables.' => 'No hi ha cap taula.', 'No tables.' => 'No hi ha cap taula.',
'select' => 'registres', 'select' => 'registres',
'Item has been deleted.' => 'S\'ha suprmit l\'element.', 'Item has been deleted.' => 'S\'ha suprimit l\'element.',
'Item has been updated.' => 'S\'ha actualitzat l\'element.', 'Item has been updated.' => 'S\'ha actualitzat l\'element.',
'Item%s has been inserted.' => 'S\'ha insertat l\'element%s.', 'Item%s has been inserted.' => 'S\'ha insertat l\'element%s.',
'Edit' => 'Edita', 'Edit' => 'Edita',
@@ -44,9 +45,9 @@ $translations = array(
'Delete' => 'Suprimeix', 'Delete' => 'Suprimeix',
'Database' => 'Base de dades', 'Database' => 'Base de dades',
'Routines' => 'Rutines', 'Routines' => 'Rutines',
'Indexes have been altered.' => 'S\'han modificat els índexs.', 'Indexes have been altered.' => 'S\'han modificat els índex.',
'Indexes' => 'Índexs', 'Indexes' => 'Índexs',
'Alter indexes' => 'Modifica els índexs', 'Alter indexes' => 'Modifica els índex',
'Add next' => 'Afegeix el següent', 'Add next' => 'Afegeix el següent',
'Language' => 'Idioma', 'Language' => 'Idioma',
'Select' => 'Selecciona', 'Select' => 'Selecciona',
@@ -74,11 +75,11 @@ $translations = array(
'No commands to execute.' => 'Cap comanda per executar.', 'No commands to execute.' => 'Cap comanda per executar.',
'Unable to upload a file.' => 'Impossible adjuntar el fitxer.', 'Unable to upload a file.' => 'Impossible adjuntar el fitxer.',
'File upload' => 'Adjunta un fitxer', 'File upload' => 'Adjunta un fitxer',
'File uploads are disabled.' => 'L\'ddjunció de fitxers està desactivada.', 'File uploads are disabled.' => 'La pujada de fitxers està desactivada.',
'Routine has been called, %d row(s) affected.' => array('S\'ha cridat la rutina, %d registre modificat.', 'S\'ha cridat la rutina, %d registres modificats.'), 'Routine has been called, %d row(s) affected.' => array('S\'ha cridat la rutina, %d registre modificat.', 'S\'ha cridat la rutina, %d registres modificats.'),
'Call' => 'Crida', 'Call' => 'Crida',
'No extension' => 'Cap extensió', 'No extension' => 'Cap extensió',
'None of the supported PHP extensions (%s) are available.' => 'No hi ha cap de les extensions PHP soporatades (%s) disponible.', 'None of the supported PHP extensions (%s) are available.' => 'No hi ha cap de les extensions PHP suportades (%s) disponible.',
'Session support must be enabled.' => 'Cal que estigui permès l\'us de sessions.', 'Session support must be enabled.' => 'Cal que estigui permès l\'us de sessions.',
'Session expired, please login again.' => 'La sessió ha expirat, torna a iniciar-ne una.', 'Session expired, please login again.' => 'La sessió ha expirat, torna a iniciar-ne una.',
'Text length' => 'Longitud del text', 'Text length' => 'Longitud del text',
@@ -86,7 +87,7 @@ $translations = array(
'Foreign key has been altered.' => 'S\'ha modificat la clau forana.', 'Foreign key has been altered.' => 'S\'ha modificat la clau forana.',
'Foreign key has been created.' => 'S\'ha creat la clau forana.', 'Foreign key has been created.' => 'S\'ha creat la clau forana.',
'Foreign key' => 'Clau forana', 'Foreign key' => 'Clau forana',
'Target table' => 'Taula de destí', 'Target table' => 'Taula de destinació',
'Change' => 'Canvi', 'Change' => 'Canvi',
'Source' => 'Font', 'Source' => 'Font',
'Target' => 'Destí', 'Target' => 'Destí',
@@ -96,7 +97,7 @@ $translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Tipus d\'índex', 'Index Type' => 'Tipus d\'índex',
'Column (length)' => 'Columna (longitud)', 'length' => 'longitud',
'View has been dropped.' => 'S\'ha suprimit la vista.', 'View has been dropped.' => 'S\'ha suprimit la vista.',
'View has been altered.' => 'S\'ha modificat la vista.', 'View has been altered.' => 'S\'ha modificat la vista.',
'View has been created.' => 'S\'ha creat la vista.', 'View has been created.' => 'S\'ha creat la vista.',
@@ -139,7 +140,7 @@ $translations = array(
'Grant' => 'Grant', 'Grant' => 'Grant',
'Revoke' => 'Revoke', 'Revoke' => 'Revoke',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Les dades POST són massa grans. Redueix les dades o incrementa la directiva de configuració %s.', 'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Les dades POST són massa grans. Redueix les dades o incrementa la directiva de configuració %s.',
'Logged as: %s' => 'Connectat com: %s', 'Logged as: %s' => 'Connectat com a: %s',
'Move up' => 'Mou a dalt', 'Move up' => 'Mou a dalt',
'Move down' => 'Mou a baix', 'Move down' => 'Mou a baix',
'Functions' => 'Funcions', 'Functions' => 'Funcions',
@@ -204,7 +205,7 @@ $translations = array(
'[yyyy]-mm-dd' => 'dd/mm/[aaaa]', '[yyyy]-mm-dd' => 'dd/mm/[aaaa]',
'History' => 'Història', 'History' => 'Història',
'Variables' => 'Variables', '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 origen i destí han de ser del mateix tipus, la columna destí ha d\'estar indexada i les dades referenciades han d\'existir.', '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', 'E-mail' => 'Correu electrònic',
'From' => 'De', 'From' => 'De',
'Subject' => 'Assumpte', 'Subject' => 'Assumpte',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Systém', 'System' => 'Systém',
@@ -23,7 +25,7 @@ $translations = array(
'No extension' => 'Žádné rozšíření', 'No extension' => 'Žádné rozšíření',
'None of the supported PHP extensions (%s) are available.' => 'Není dostupné žádné z podporovaných PHP rozšíření (%s).', 'None of the supported PHP extensions (%s) are available.' => 'Není dostupné žádné z podporovaných PHP rozšíření (%s).',
'Connecting to privileged ports is not allowed.' => 'Připojování k privilegovaným portům není povoleno.', 'Connecting to privileged ports is not allowed.' => 'Připojování k privilegovaným portům není povoleno.',
'Disable %s or enable %s or %s extensions.' => 'Zakažte %s nebo povolte extenze %s nebo %s.', 'Disable %s or enable %s or %s extensions.' => 'Zakažte %s nebo povolte rozšíření %s nebo %s.',
'Session support must be enabled.' => 'Session proměnné musí být povolené.', 'Session support must be enabled.' => 'Session proměnné musí být povolené.',
'Session expired, please login again.' => 'Session vypršela, přihlašte se prosím znovu.', 'Session expired, please login again.' => 'Session vypršela, přihlašte se prosím znovu.',
'The action will be performed after successful login with the same credentials.' => 'Akce bude provedena po úspěšném přihlášení se stejnými přihlašovacími údaji.', 'The action will be performed after successful login with the same credentials.' => 'Akce bude provedena po úspěšném přihlášení se stejnými přihlašovacími údaji.',
@@ -88,7 +90,6 @@ $translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Databáze', 'Database' => 'Databáze',
'database' => 'databáze',
'DB' => 'DB', 'DB' => 'DB',
'Use' => 'Vybrat', 'Use' => 'Vybrat',
'Select database' => 'Vybrat databázi', 'Select database' => 'Vybrat databázi',
@@ -206,7 +207,7 @@ $translations = array(
'Alter indexes' => 'Pozměnit indexy', 'Alter indexes' => 'Pozměnit indexy',
'Add next' => 'Přidat další', 'Add next' => 'Přidat další',
'Index Type' => 'Typ indexu', 'Index Type' => 'Typ indexu',
'Column (length)' => 'Sloupec (délka)', 'length' => 'délka',
'Foreign keys' => 'Cizí klíče', 'Foreign keys' => 'Cizí klíče',
'Foreign key' => 'Cizí klíč', 'Foreign key' => 'Cizí klíč',
@@ -256,8 +257,8 @@ $translations = array(
'%d row(s)' => array('%d řádek', '%d řádky', '%d řádků'), '%d row(s)' => array('%d řádek', '%d řádky', '%d řádků'),
'Page' => 'Stránka', 'Page' => 'Stránka',
'last' => 'poslední', 'last' => 'poslední',
'Load more data' => 'Nahrát další data', 'Load more data' => 'Načíst další data',
'Loading' => 'Nahrává se', 'Loading' => 'Načítá se',
'Whole result' => 'Celý výsledek', 'Whole result' => 'Celý výsledek',
'%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtů'), '%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtů'),
@@ -346,4 +347,12 @@ $translations = array(
'Type has been dropped.' => 'Typ byl odstraněn.', 'Type has been dropped.' => 'Typ byl odstraněn.',
'Type has been created.' => 'Typ byl vytvořen.', 'Type has been created.' => 'Typ byl vytvořen.',
'Alter type' => 'Pozměnit typ', 'Alter type' => 'Pozměnit typ',
// Table check constraints
'Checks' => 'Kontroly',
'Create check' => 'Vytvořit kontrolu',
'Alter check' => 'Změnit kontrolu',
'Check has been created.' => 'Kontrola byla vytvořena.',
'Check has been altered.' => 'Kontrola byla změněna.',
'Check has been dropped.' => 'Kontrola byla odstraněna.',
); );

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'System' => 'System', 'System' => 'System',
'Server' => 'Server', 'Server' => 'Server',
@@ -64,7 +66,6 @@ $translations = array(
'Format' => 'Format', 'Format' => 'Format',
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Database', 'Database' => 'Database',
'database' => 'database',
'Use' => 'Brug', 'Use' => 'Brug',
'Select database' => 'Vælg database', 'Select database' => 'Vælg database',
'Invalid database.' => 'Ugyldig database.', 'Invalid database.' => 'Ugyldig database.',
@@ -165,7 +166,7 @@ $translations = array(
'Alter indexes' => 'Ændre indekser', 'Alter indexes' => 'Ændre indekser',
'Add next' => 'Læg til næste', 'Add next' => 'Læg til næste',
'Index Type' => 'Indekstype', 'Index Type' => 'Indekstype',
'Column (length)' => 'Kolonne (længde)', 'length' => 'længde',
'Foreign keys' => 'Fremmednøgler', 'Foreign keys' => 'Fremmednøgler',
'Foreign key' => 'Fremmednøgle', 'Foreign key' => 'Fremmednøgle',
'Foreign key has been dropped.' => 'Fremmednøglen er slettet.', 'Foreign key has been dropped.' => 'Fremmednøglen er slettet.',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Login', 'Login' => 'Login',
'Logout successful.' => 'Abmeldung erfolgreich.', 'Logout successful.' => 'Abmeldung erfolgreich.',
@@ -32,8 +34,7 @@ $translations = array(
'Create database' => 'Datenbank erstellen', 'Create database' => 'Datenbank erstellen',
'SQL command' => 'SQL-Kommando', 'SQL command' => 'SQL-Kommando',
'Logout' => 'Abmelden', 'Logout' => 'Abmelden',
'database' => 'Datenbank', 'Use' => 'Auswählen',
'Use' => 'Benutzung',
'No tables.' => 'Keine Tabellen.', 'No tables.' => 'Keine Tabellen.',
'select' => 'zeigen', 'select' => 'zeigen',
'Item has been deleted.' => 'Datensatz wurde gelöscht.', 'Item has been deleted.' => 'Datensatz wurde gelöscht.',
@@ -97,7 +98,7 @@ $translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Index-Typ', 'Index Type' => 'Index-Typ',
'Column (length)' => 'Spalte (Länge)', 'length' => 'Länge',
'View has been dropped.' => 'View wurde entfernt.', 'View has been dropped.' => 'View wurde entfernt.',
'View has been altered.' => 'View wurde geändert.', 'View has been altered.' => 'View wurde geändert.',
'View has been created.' => 'View wurde erstellt.', 'View has been created.' => 'View wurde erstellt.',
@@ -280,10 +281,25 @@ $translations = array(
'If you did not send this request from Adminer then close this page.' => 'Wenn Sie diese Anfrage nicht von Adminer gesendet haben, schließen Sie diese Seite.', 'If you did not send this request from Adminer then close this page.' => 'Wenn Sie diese Anfrage nicht von Adminer gesendet haben, schließen Sie diese Seite.',
'You can upload a big SQL file via FTP and import it from server.' => 'Sie können eine große SQL-Datei per FTP hochladen und dann vom Server importieren.', 'You can upload a big SQL file via FTP and import it from server.' => 'Sie können eine große SQL-Datei per FTP hochladen und dann vom Server importieren.',
'You are offline.' => 'Sie sind offline.', 'You are offline.' => 'Sie sind offline.',
'You have no privileges to update this table.' => 'Sie haben keine Rechte, um diese Tabelle zu aktualisieren.' , 'You have no privileges to update this table.' => 'Sie haben keine Rechte, diese Tabelle zu aktualisieren.',
'Saving' => 'Speichere', 'Saving' => 'Speichere',
'yes' => 'ja', 'yes' => 'ja',
'no' => 'nein', 'no' => 'nein',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Das Master-Passwort ist abgelaufen. <a href="https://www.adminer.org/de/extension/"%s>Implementieren</a> Sie die %s Methode, um es permanent zu machen.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Das Master-Passwort ist abgelaufen. <a href="https://www.adminer.org/de/extension/"%s>Implementieren</a> Sie die %s Methode, um es permanent zu machen.',
'%d / ' => '%d / ', '%d / ' => '%d / ',
'Drop %s?' => '%s entfernen?',
'Materialized view' => 'Strukturierte Ansicht',
'Vacuum' => 'Vacuum',
'overwrite' => 'überschreiben',
'DB' => 'DB',
'ATTACH queries are not supported.' => 'ATTACH Abfragen werden nicht unterstützt.',
'Warnings' => 'Warnungen',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer unterstützt den Zugriff auf eine Datenbank ohne Passwort nicht, <a href="https://www.adminer.org/en/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.',
); );

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Σύστημα', 'System' => 'Σύστημα',
@@ -11,12 +13,12 @@ $translations = array(
'Logged as: %s' => 'Συνδεθήκατε ως %s', 'Logged as: %s' => 'Συνδεθήκατε ως %s',
'Logout successful.' => 'Αποσυνδεθήκατε με επιτυχία.', 'Logout successful.' => 'Αποσυνδεθήκατε με επιτυχία.',
'Invalid credentials.' => 'Εσφαλμένα Διαπιστευτήρια.', 'Invalid credentials.' => 'Εσφαλμένα Διαπιστευτήρια.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Επανηλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτό.', 'Επανηλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτά.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτό.', 'Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτά.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Έλειξε ο Κύριος Κωδικός. <a href="https://www.adminer.org/en/extension/"%s>Ενεργοποιήστε</a> τη μέθοδο %s για να τον κάνετε μόνιμο.', 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Έληξε ο Κύριος Κωδικός. <a href="https://www.adminer.org/en/extension/"%s>Ενεργοποιήστε</a> τη μέθοδο %s για να τον κάνετε μόνιμο.',
'Language' => 'Γλώσσα', 'Language' => 'Γλώσσα',
'Invalid CSRF token. Send the form again.' => 'Άκυρο κουπόνι CSRF. Στείλτε τη φόρμα ξανά.', 'Invalid CSRF token. Send the form again.' => 'Άκυρο κουπόνι CSRF. Στείλτε τη φόρμα ξανά.',
'If you did not send this request from Adminer then close this page.' => 'Αν δε στείλατε αυτό το αίτημα από το Adminer, τότε κλείστε αυτή τη σελίδα.', 'If you did not send this request from Adminer then close this page.' => 'Αν δε στείλατε αυτό το αίτημα από το Adminer, τότε κλείστε αυτή τη σελίδα.',
'No extension' => 'Χωρίς Επεκτάσεις', 'No extension' => 'Καμία Επέκταση',
'None of the supported PHP extensions (%s) are available.' => 'Καμία από τις υποστηριζόμενες επεκτάσεις PHP (%s) δεν είναι διαθέσιμη.', 'None of the supported PHP extensions (%s) are available.' => 'Καμία από τις υποστηριζόμενες επεκτάσεις PHP (%s) δεν είναι διαθέσιμη.',
'Session support must be enabled.' => 'Πρέπει να είναι ενεργοποιημένη η υποστήριξη συνεδριών.', 'Session support must be enabled.' => 'Πρέπει να είναι ενεργοποιημένη η υποστήριξη συνεδριών.',
'Session expired, please login again.' => 'Η συνεδρία έληξε, παρακαλώ συνδεθείτε ξανά.', 'Session expired, please login again.' => 'Η συνεδρία έληξε, παρακαλώ συνδεθείτε ξανά.',
@@ -26,7 +28,7 @@ $translations = array(
// text direction - 'ltr' or 'rtl' // text direction - 'ltr' or 'rtl'
'ltr' => 'ltr', 'ltr' => 'ltr',
'Privileges' => 'Προνόμια', 'Privileges' => 'Δικαιώματα',
'Create user' => 'Δημιουργία Χρήστη', 'Create user' => 'Δημιουργία Χρήστη',
'User has been dropped.' => 'Ο Χρήστης διαγράφηκε.', 'User has been dropped.' => 'Ο Χρήστης διαγράφηκε.',
'User has been altered.' => 'Ο Χρήστης τροποποιήθηκε.', 'User has been altered.' => 'Ο Χρήστης τροποποιήθηκε.',
@@ -38,7 +40,7 @@ $translations = array(
'Revoke' => 'Ανάκληση', 'Revoke' => 'Ανάκληση',
'Process list' => 'Λίστα διεργασιών', 'Process list' => 'Λίστα διεργασιών',
'%d process(es) have been killed.' => array('Τερματίστηκαν %d διεργασία.', 'Τερματίστηκαν %d διεργασίες.'), '%d process(es) have been killed.' => array('Τερματίστηκε %d διεργασία.', 'Τερματίστηκαν %d διεργασίες.'),
'Kill' => 'Τερματισμός', 'Kill' => 'Τερματισμός',
'Variables' => 'Μεταβλητές', 'Variables' => 'Μεταβλητές',
@@ -46,8 +48,8 @@ $translations = array(
'SQL command' => 'Εντολή SQL', 'SQL command' => 'Εντολή SQL',
'%d query(s) executed OK.' => array('Το ερώτημα %d εκτελέστηκε ΟΚ.', 'Τα ερώτηματα %d εκτελέστηκαν ΟΚ.'), '%d query(s) executed OK.' => array('Το ερώτημα %d εκτελέστηκε ΟΚ.', 'Τα ερώτηματα %d εκτελέστηκαν ΟΚ.'),
'Query executed OK, %d row(s) affected.' => array('Το ερώτημα εκτελέστηκε ΟΚ, επιρρεάστηκε %d σειρά.', 'Το ερώτημα εκτελέστηκε ΟΚ, επιρρεάστηκαν %d σειρές.'), 'Query executed OK, %d row(s) affected.' => array('Το ερώτημα εκτελέστηκε ΟΚ, επηρεάστηκε %d σειρά.', 'Το ερώτημα εκτελέστηκε ΟΚ, επηρεάστηκαν %d σειρές.'),
'No commands to execute.' => 'Δεν υπάρχει εντολή να εκτελεστεί.', 'No commands to execute.' => 'Δεν υπάρχουν εντολές να εκτελεστούν.',
'Error in query' => 'Σφάλμα στο ερώτημα', 'Error in query' => 'Σφάλμα στο ερώτημα',
'Execute' => 'Εκτέλεση', 'Execute' => 'Εκτέλεση',
'Stop on error' => 'Διακοπή όταν υπάρχει σφάλμα', 'Stop on error' => 'Διακοπή όταν υπάρχει σφάλμα',
@@ -58,16 +60,16 @@ $translations = array(
'Clear' => 'Καθαρισμός', 'Clear' => 'Καθαρισμός',
'Edit all' => 'Επεξεργασία όλων', 'Edit all' => 'Επεξεργασία όλων',
'File upload' => 'Ανέβασμα αρχείου', 'File upload' => 'Μεταφόρτωση αρχείου',
'From server' => 'Από διακομιστή', 'From server' => 'Από διακομιστή',
'Webserver file %s' => 'Αρχείο %s από διακομιστή web', 'Webserver file %s' => 'Αρχείο %s από διακομιστή web',
'Run file' => 'Εκτέλεση αρχείου', 'Run file' => 'Εκτέλεση αρχείου',
'File does not exist.' => 'Το αρχείο δεν υπάρχει.', 'File does not exist.' => 'Το αρχείο δεν υπάρχει.',
'File uploads are disabled.' => 'Έχει απενεργοποιηθεί το ανέβασμα αρχείων.', 'File uploads are disabled.' => 'Έχει απενεργοποιηθεί η μεταφόρτωση αρχείων.',
'Unable to upload a file.' => 'Δεν είναι δυνατόν να ανεβεί το αρχείο.', 'Unable to upload a file.' => 'Αδυναμία μεταφόρτωσης αρχείου.',
'Maximum allowed file size is %sB.' => 'Το μέγιστο επιτρεπόμενο μέγεθος αρχείο για ανέβασμα είναι %sB.', 'Maximum allowed file size is %sB.' => 'Το μέγιστο επιτρεπόμενο μέγεθος αρχείου είναι %sB.',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Πολλά δεδομένα POST. Μείωστε τα περιεχόμενα ή αυξήστε την σχετική ρύθμιση %s.', 'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Πολλά δεδομένα POST. Μείωστε τα περιεχόμενα ή αυξήστε την σχετική ρύθμιση %s.',
'You can upload a big SQL file via FTP and import it from server.' => 'Μπορείτε να ανεβάσετε ένα μεγάλο αρχείο SQL μέσω FTP και να το εισάγετε από το διακομιστή.', 'You can upload a big SQL file via FTP and import it from server.' => 'Μπορείτε να μεταφορτώσετε ένα μεγάλο αρχείο SQL μέσω FTP και να το εισάγετε από το διακομιστή.',
'You are offline.' => 'Βρίσκεστε εκτός σύνδεσης.', 'You are offline.' => 'Βρίσκεστε εκτός σύνδεσης.',
'Export' => 'Εξαγωγή', 'Export' => 'Εξαγωγή',
@@ -79,10 +81,9 @@ $translations = array(
'Data' => 'Δεδομένα', 'Data' => 'Δεδομένα',
'Database' => 'Β. Δεδομένων', 'Database' => 'Β. Δεδομένων',
'database' => 'β. δεδομένων',
'Use' => 'χρήση', 'Use' => 'χρήση',
'Select database' => 'Επιλέξτε Β.Δ.', 'Select database' => 'Επιλέξτε Β.Δ.',
'Invalid database.' => 'Άκυρη Β.Δ.', 'Invalid database.' => 'Λανθασμένη Β.Δ.',
'Database has been dropped.' => 'Η Β.Δ. διαγράφηκε.', 'Database has been dropped.' => 'Η Β.Δ. διαγράφηκε.',
'Databases have been dropped.' => 'Οι Β.Δ. διαγράφηκαν.', 'Databases have been dropped.' => 'Οι Β.Δ. διαγράφηκαν.',
'Database has been created.' => 'Η Β.Δ. δημιουργήθηκε.', 'Database has been created.' => 'Η Β.Δ. δημιουργήθηκε.',
@@ -111,7 +112,7 @@ $translations = array(
'Check' => 'Έλεγχος', 'Check' => 'Έλεγχος',
'Repair' => 'Επιδιόρθωση', 'Repair' => 'Επιδιόρθωση',
'Truncate' => 'Περικοπή', 'Truncate' => 'Περικοπή',
'Tables have been truncated.' => 'Οι πίνακες περικόπτηκαν.', 'Tables have been truncated.' => 'Οι πίνακες περικόπηκαν.',
'Move to other database' => 'Μεταφορά σε άλλη Β.Δ.', 'Move to other database' => 'Μεταφορά σε άλλη Β.Δ.',
'Move' => 'Μεταφορά', 'Move' => 'Μεταφορά',
'Tables have been moved.' => 'Οι πίνακες μεταφέρθηκαν.', 'Tables have been moved.' => 'Οι πίνακες μεταφέρθηκαν.',
@@ -119,11 +120,11 @@ $translations = array(
'Tables have been copied.' => 'Οι πίνακες αντιγράφηκαν.', 'Tables have been copied.' => 'Οι πίνακες αντιγράφηκαν.',
'Routines' => 'Ρουτίνες', 'Routines' => 'Ρουτίνες',
'Routine has been called, %d row(s) affected.' => array('Η ρουτίνα εκτελέστηκε, επιρρεάστηκε %d σειρά.', 'Η ρουτίνα εκτελέστηκε, επιρρεάστηκαν %d σειρές.'), 'Routine has been called, %d row(s) affected.' => array('Η ρουτίνα εκτελέστηκε, επηρεάστηκε %d σειρά.', 'Η ρουτίνα εκτελέστηκε, επηρεάστηκαν %d σειρές.'),
'Call' => 'Εκτέλεση', 'Call' => 'Εκτέλεση',
'Parameter name' => 'Όνομα παραμέτρου', 'Parameter name' => 'Όνομα παραμέτρου',
'Create procedure' => 'Δημιουργία διαδικασίας', 'Create procedure' => 'Δημιουργία διαδικασίας',
'Create function' => 'Δημιουργία Λειτουργίας', 'Create function' => 'Δημιουργία Συνάρτησης',
'Routine has been dropped.' => 'Η ρουτίνα διαγράφηκε.', 'Routine has been dropped.' => 'Η ρουτίνα διαγράφηκε.',
'Routine has been altered.' => 'Η ρουτίνα τροποποιήθηκε.', 'Routine has been altered.' => 'Η ρουτίνα τροποποιήθηκε.',
'Routine has been created.' => 'Η ρουτίνα δημιουργήθηκε.', 'Routine has been created.' => 'Η ρουτίνα δημιουργήθηκε.',
@@ -151,7 +152,7 @@ $translations = array(
'Alter table' => 'Τροποποίηση πίνακα', 'Alter table' => 'Τροποποίηση πίνακα',
'Create table' => 'Δημιουργία πίνακα', 'Create table' => 'Δημιουργία πίνακα',
'Table has been dropped.' => 'Ο πίνακας διαγράφηκε.', 'Table has been dropped.' => 'Ο πίνακας διαγράφηκε.',
'Tables have been dropped.' => 'Οι πινακες διαγράφηκαν.', 'Tables have been dropped.' => 'Οι πίνακες διαγράφηκαν.',
'Tables have been optimized.' => 'Οι πίνακες βελτιστοποιήθηκαν.', 'Tables have been optimized.' => 'Οι πίνακες βελτιστοποιήθηκαν.',
'Table has been altered.' => 'Ο πίνακας τροποποιήθηκε.', 'Table has been altered.' => 'Ο πίνακας τροποποιήθηκε.',
'Table has been created.' => 'Ο πίνακας δημιουργήθηκε.', 'Table has been created.' => 'Ο πίνακας δημιουργήθηκε.',
@@ -194,7 +195,7 @@ $translations = array(
'Alter indexes' => 'Τροποποίηση δεικτών', 'Alter indexes' => 'Τροποποίηση δεικτών',
'Add next' => 'Προσθήκη επόμενου', 'Add next' => 'Προσθήκη επόμενου',
'Index Type' => 'Τύπος δείκτη', 'Index Type' => 'Τύπος δείκτη',
'Column (length)' => 'Στήλη (μήκος)', 'length' => 'μήκος',
'Foreign keys' => 'Εξαρτημένα κλειδιά', 'Foreign keys' => 'Εξαρτημένα κλειδιά',
'Foreign key' => 'Εξαρτημένο κλειδί', 'Foreign key' => 'Εξαρτημένο κλειδί',
@@ -210,7 +211,7 @@ $translations = array(
'Add foreign key' => 'Προσθήκη εξαρτημένου κλειδιού', 'Add foreign key' => 'Προσθήκη εξαρτημένου κλειδιού',
'ON DELETE' => 'ΚΑΤΑ ΤΗ ΔΙΑΓΡΑΦΗ', 'ON DELETE' => 'ΚΑΤΑ ΤΗ ΔΙΑΓΡΑΦΗ',
'ON UPDATE' => 'ΚΑΤΑ ΤΗΝ ΑΛΛΑΓΗ', 'ON UPDATE' => 'ΚΑΤΑ ΤΗΝ ΑΛΛΑΓΗ',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'Οι στήλες στη πηγή και το στόχο πρέπει να έχουν τον ίδιο τύπο, πρέπει να υπάρχει δείκτης στη στήλη στόχο και να υπάρχουν εξαρτημένα δεδομένα.', 'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'Οι στήλες στην πηγή και το στόχο πρέπει να έχουν τον ίδιο τύπο, πρέπει να υπάρχει δείκτης στη στήλη στόχο και να υπάρχουν εξαρτημένα δεδομένα.',
'Triggers' => 'Εναύσματα', 'Triggers' => 'Εναύσματα',
'Add trigger' => 'Προσθήκη εναύσματος', 'Add trigger' => 'Προσθήκη εναύσματος',
@@ -234,7 +235,7 @@ $translations = array(
'Sort' => 'Ταξινόμηση', 'Sort' => 'Ταξινόμηση',
'descending' => 'Φθίνουσα', 'descending' => 'Φθίνουσα',
'Limit' => 'Όριο', 'Limit' => 'Όριο',
'Limit rows' => 'Περιοριμός σειρών', 'Limit rows' => 'Περιορισμός σειρών',
'Text length' => 'Μήκος κειμένου', 'Text length' => 'Μήκος κειμένου',
'Action' => 'Ενέργεια', 'Action' => 'Ενέργεια',
'Full table scan' => 'Πλήρης σάρωση πινάκων', 'Full table scan' => 'Πλήρης σάρωση πινάκων',
@@ -262,7 +263,7 @@ $translations = array(
'Item%s has been inserted.' => 'Η εγγραφή%s εισήχθη.', 'Item%s has been inserted.' => 'Η εγγραφή%s εισήχθη.',
'Item has been deleted.' => 'Η εγγραφή διαγράφηκε.', 'Item has been deleted.' => 'Η εγγραφή διαγράφηκε.',
'Item has been updated.' => 'Η εγγραφή ενημερώθηκε.', 'Item has been updated.' => 'Η εγγραφή ενημερώθηκε.',
'%d item(s) have been affected.' => array('Επιρρεάστηκε %d εγγραφή.', 'Επιρρεάστηκαν %d εγγραφές.'), '%d item(s) have been affected.' => array('Επηρεάστηκε %d εγγραφή.', 'Επηρεάστηκαν %d εγγραφές.'),
'New item' => 'Νέα εγγραφή', 'New item' => 'Νέα εγγραφή',
'original' => 'πρωτότυπο', 'original' => 'πρωτότυπο',
// label for value '' in enum data type // label for value '' in enum data type
@@ -274,7 +275,7 @@ $translations = array(
'Save and continue edit' => 'Αποθήκευση και συνέχεια επεξεργασίας', 'Save and continue edit' => 'Αποθήκευση και συνέχεια επεξεργασίας',
'Save and insert next' => 'Αποθήκευση και εισαγωγή επόμενου', 'Save and insert next' => 'Αποθήκευση και εισαγωγή επόμενου',
'Selected' => 'Επιλεγμένα', 'Selected' => 'Επιλεγμένα',
'Clone' => 'Κλονοποίηση', 'Clone' => 'Κλωνοποίηση',
'Delete' => 'Διαγραφή', 'Delete' => 'Διαγραφή',
'You have no privileges to update this table.' => 'Δεν έχετε δικαίωμα να τροποποιήσετε αυτό τον πίνακα.', 'You have no privileges to update this table.' => 'Δεν έχετε δικαίωμα να τροποποιήσετε αυτό τον πίνακα.',
@@ -283,7 +284,7 @@ $translations = array(
'Subject' => 'Θέμα', 'Subject' => 'Θέμα',
'Attachments' => 'Συνημμένα', 'Attachments' => 'Συνημμένα',
'Send' => 'Αποστολή', 'Send' => 'Αποστολή',
'%d e-mail(s) have been sent.' => array('%d e-mail απεστάλλει.', '%d e-mail απεστάλλησαν.'), '%d e-mail(s) have been sent.' => array('%d e-mail απεστάλη.', '%d e-mail απεστάλησαν.'),
// data type descriptions // data type descriptions
'Numbers' => 'Αριθμοί', 'Numbers' => 'Αριθμοί',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$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.'), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Too many unsuccessful logins, try again in %d minute.', 'Too many unsuccessful logins, try again in %d minutes.'),
'Query executed OK, %d row(s) affected.' => array('Query executed OK, %d row affected.', 'Query executed OK, %d rows affected.'), 'Query executed OK, %d row(s) affected.' => array('Query executed OK, %d row affected.', 'Query executed OK, %d rows affected.'),

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Login', 'Login' => 'Login',
'Logout successful.' => 'Sesión finalizada con éxito.', 'Logout successful.' => 'Sesión finalizada con éxito.',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'Crear Base de datos', 'Create database' => 'Crear Base de datos',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Cerrar sesión', 'Logout' => 'Cerrar sesión',
'database' => 'base de datos',
'Use' => 'Usar', 'Use' => 'Usar',
'No tables.' => 'No existen tablas.', 'No tables.' => 'No existen tablas.',
'select' => 'registros', 'select' => 'registros',
@@ -96,7 +97,7 @@ $translations = array(
'ON DELETE' => 'AL BORRAR', 'ON DELETE' => 'AL BORRAR',
'ON UPDATE' => 'AL ACTUALIZAR', 'ON UPDATE' => 'AL ACTUALIZAR',
'Index Type' => 'Tipo de índice', 'Index Type' => 'Tipo de índice',
'Column (length)' => 'Columna (longitud)', 'length' => 'longitud',
'View has been dropped.' => 'Vista eliminada.', 'View has been dropped.' => 'Vista eliminada.',
'View has been altered.' => 'Vista modificada.', 'View has been altered.' => 'Vista modificada.',
'View has been created.' => 'Vista creada.', 'View has been created.' => 'Vista creada.',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Logi sisse', 'Login' => 'Logi sisse',
'Logout successful.' => 'Väljalogimine õnnestus.', 'Logout successful.' => 'Väljalogimine õnnestus.',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'Loo uus andmebaas', 'Create database' => 'Loo uus andmebaas',
'SQL command' => 'SQL-Päring', 'SQL command' => 'SQL-Päring',
'Logout' => 'Logi välja', 'Logout' => 'Logi välja',
'database' => 'andmebaas',
'Use' => 'Kasuta', 'Use' => 'Kasuta',
'No tables.' => 'Tabeleid ei leitud.', 'No tables.' => 'Tabeleid ei leitud.',
'select' => 'kuva', 'select' => 'kuva',
@@ -96,7 +97,7 @@ $translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Indeksi tüüp', 'Index Type' => 'Indeksi tüüp',
'Column (length)' => 'Veerg (pikkus)', 'length' => 'pikkus',
'View has been dropped.' => 'Vaade (VIEW) on edukalt kustutatud.', 'View has been dropped.' => 'Vaade (VIEW) on edukalt kustutatud.',
'View has been altered.' => 'Vaade (VIEW) on edukalt muudetud.', 'View has been altered.' => 'Vaade (VIEW) on edukalt muudetud.',
'View has been created.' => 'Vaade (VIEW) on edukalt loodud.', 'View has been created.' => 'Vaade (VIEW) on edukalt loodud.',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'سیستم', 'System' => 'سیستم',
@@ -77,7 +79,6 @@ $translations = array(
'Data' => 'داده', 'Data' => 'داده',
'Database' => 'پایگاه داده', 'Database' => 'پایگاه داده',
'database' => 'پایگاه داده',
'Use' => 'استفاده', 'Use' => 'استفاده',
'Select database' => 'انتخاب پایگاه داده', 'Select database' => 'انتخاب پایگاه داده',
'Invalid database.' => 'پایگاه داده نامعتبر.', 'Invalid database.' => 'پایگاه داده نامعتبر.',
@@ -192,7 +193,7 @@ $translations = array(
'Alter indexes' => 'ویرایش ایندکسها', 'Alter indexes' => 'ویرایش ایندکسها',
'Add next' => 'افرودن بعدی', 'Add next' => 'افرودن بعدی',
'Index Type' => 'نوع ایندکس', 'Index Type' => 'نوع ایندکس',
'Column (length)' => 'ستون (طول)', 'length' => 'طول',
'Foreign keys' => 'کلیدهای خارجی', 'Foreign keys' => 'کلیدهای خارجی',
'Foreign key' => 'کلید خارجی', 'Foreign key' => 'کلید خارجی',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Järjestelmä', 'System' => 'Järjestelmä',
@@ -79,7 +81,6 @@ $translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Tietokanta', 'Database' => 'Tietokanta',
'database' => 'tietokanta',
'Use' => 'Käytä', 'Use' => 'Käytä',
'Select database' => 'Valitse tietokanta', 'Select database' => 'Valitse tietokanta',
'Invalid database.' => 'Tietokanta ei kelpaa.', 'Invalid database.' => 'Tietokanta ei kelpaa.',
@@ -194,7 +195,7 @@ $translations = array(
'Alter indexes' => 'Muuta indeksejä', 'Alter indexes' => 'Muuta indeksejä',
'Add next' => 'Lisää seuraava', 'Add next' => 'Lisää seuraava',
'Index Type' => 'Indeksityyppi', 'Index Type' => 'Indeksityyppi',
'Column (length)' => 'Sarake (pituus)', 'length' => 'pituus',
'Foreign keys' => 'Vieraat avaimet', 'Foreign keys' => 'Vieraat avaimet',
'Foreign key' => 'Vieras avain', 'Foreign key' => 'Vieras avain',
@@ -333,4 +334,18 @@ $translations = array(
'Type has been dropped.' => 'Tyyppi poistettiin.', 'Type has been dropped.' => 'Tyyppi poistettiin.',
'Type has been created.' => 'Tyyppi luotiin.', 'Type has been created.' => 'Tyyppi luotiin.',
'Alter type' => 'Muuta tyyppiä', 'Alter type' => 'Muuta tyyppiä',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Kiitos, kun käytät Admineriä, voit <a href="https://www.adminer.org/en/donation/">tehdä lahjoituksen tästä</a>.',
'Drop %s?' => 'Poistetaanko %s?',
'overwrite' => 'kirjoittaen päälle',
'DB' => 'TK',
'ATTACH queries are not supported.' => 'ATTACH-komennolla tehtyjä kyselyjä ei tueta.',
'Warnings' => 'Varoitukset',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer ei tue pääsyä tietokantaan ilman salasanaa, katso tarkemmin <a href="https://www.adminer.org/en/password/"%s>täältä</a>.',
'The action will be performed after successful login with the same credentials.' => 'Toiminto suoritetaan sen jälkeen, kun on onnistuttu kirjautumaan samoilla käyttäjätunnuksilla uudestaan.',
'Connecting to privileged ports is not allowed.' => 'Yhteydet etuoikeutettuihin portteihin eivät ole sallittuja.',
'There is a space in the input password which might be the cause.' => 'Syynä voi olla syötetyssä salasanassa oleva välilyönti.',
'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.',
); );

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Authentification', 'Login' => 'Authentification',
'Logout successful.' => 'Au revoir !', 'Logout successful.' => 'Au revoir !',
@@ -30,7 +32,6 @@ $translations = array(
'Create database' => 'Créer une base de données', 'Create database' => 'Créer une base de données',
'SQL command' => 'Requête SQL', 'SQL command' => 'Requête SQL',
'Logout' => 'Déconnexion', 'Logout' => 'Déconnexion',
'database' => 'base de données',
'Use' => 'Utiliser', 'Use' => 'Utiliser',
'No tables.' => 'Aucune table.', 'No tables.' => 'Aucune table.',
'select' => 'select', 'select' => 'select',
@@ -94,7 +95,7 @@ $translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Type d\'index', 'Index Type' => 'Type d\'index',
'Column (length)' => 'Colonne (longueur)', 'length' => 'longueur',
'View has been dropped.' => 'La vue a été effacée.', 'View has been dropped.' => 'La vue a été effacée.',
'View has been altered.' => 'La vue a été modifiée.', 'View has been altered.' => 'La vue a été modifiée.',
'View has been created.' => 'La vue a été créée.', 'View has been created.' => 'La vue a été créée.',
@@ -288,4 +289,16 @@ $translations = array(
'Default value' => 'Valeur par défaut', 'Default value' => 'Valeur par défaut',
'If you did not send this request from Adminer then close this page.' => 'Si vous n\'avez pas envoyé cette requête depuis Adminer, alors fermez cette page.', 'If you did not send this request from Adminer then close this page.' => 'Si vous n\'avez pas envoyé cette requête depuis Adminer, alors fermez cette page.',
'You are offline.' => 'Vous êtes hors ligne.', 'You are offline.' => 'Vous êtes hors ligne.',
'Drop %s?' => 'Supprimer %s?',
'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>.',
'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',
'Disable %s or enable %s or %s extensions.' => 'Désactiver %s ou activer %s or %s extensions.',
); );

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Conectar', 'Login' => 'Conectar',
'Logout successful.' => 'Pechouse a sesión con éxito.', 'Logout successful.' => 'Pechouse a sesión con éxito.',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'Crear Base de datos', 'Create database' => 'Crear Base de datos',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Pechar sesión', 'Logout' => 'Pechar sesión',
'database' => 'base de datos',
'Use' => 'Usar', 'Use' => 'Usar',
'No tables.' => 'Nengunha táboa.', 'No tables.' => 'Nengunha táboa.',
'select' => 'selecciona', 'select' => 'selecciona',
@@ -96,7 +97,7 @@ $translations = array(
'ON DELETE' => 'AO BORRAR (ON DELETE)', 'ON DELETE' => 'AO BORRAR (ON DELETE)',
'ON UPDATE' => 'AO ACTUALIZAR (ON UPDATE)', 'ON UPDATE' => 'AO ACTUALIZAR (ON UPDATE)',
'Index Type' => 'Tipo de índice', 'Index Type' => 'Tipo de índice',
'Column (length)' => 'Columna (lonxitude)', 'length' => 'lonxitude',
'View has been dropped.' => 'Eliminouse a vista.', 'View has been dropped.' => 'Eliminouse a vista.',
'View has been altered.' => 'Modificouse a vista.', 'View has been altered.' => 'Modificouse a vista.',
'View has been created.' => 'Creouse a vista.', 'View has been created.' => 'Creouse a vista.',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'התחברות', 'Login' => 'התחברות',
'Logout successful.' => 'ההתחברות הצליחה', 'Logout successful.' => 'ההתחברות הצליחה',
@@ -30,7 +32,6 @@ $translations = array(
'Create database' => 'צור מסד נתונים', 'Create database' => 'צור מסד נתונים',
'SQL command' => 'שאילתת SQL', 'SQL command' => 'שאילתת SQL',
'Logout' => 'התנתק', 'Logout' => 'התנתק',
'database' => 'מסד נתונים',
'Use' => 'השתמש', 'Use' => 'השתמש',
'No tables.' => 'אין טבלאות', 'No tables.' => 'אין טבלאות',
'select' => 'בחר', 'select' => 'בחר',
@@ -94,7 +95,7 @@ $translations = array(
'ON DELETE' => 'בעת מחיקה', 'ON DELETE' => 'בעת מחיקה',
'ON UPDATE' => 'בעת עידכון', 'ON UPDATE' => 'בעת עידכון',
'Index Type' => 'סוג אינדקס', 'Index Type' => 'סוג אינדקס',
'Column (length)' => 'עמודה (אורך)', 'length' => 'אורך',
'View has been dropped.' => 'התצוגה הושלכה', 'View has been dropped.' => 'התצוגה הושלכה',
'View has been altered.' => 'התצוגה שונתה', 'View has been altered.' => 'התצוגה שונתה',
'View has been created.' => 'התצוגה נוצרה', 'View has been created.' => 'התצוגה נוצרה',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Belépés', 'Login' => 'Belépés',
'Logout successful.' => 'Sikeres kilépés.', 'Logout successful.' => 'Sikeres kilépés.',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'Adatbázis létrehozása', 'Create database' => 'Adatbázis létrehozása',
'SQL command' => 'SQL parancs', 'SQL command' => 'SQL parancs',
'Logout' => 'Kilépés', 'Logout' => 'Kilépés',
'database' => 'adatbázis',
'Use' => 'Használ', 'Use' => 'Használ',
'No tables.' => 'Nincs tábla.', 'No tables.' => 'Nincs tábla.',
'select' => 'kiválasztás', 'select' => 'kiválasztás',
@@ -96,7 +97,7 @@ $translations = array(
'ON DELETE' => 'törléskor', 'ON DELETE' => 'törléskor',
'ON UPDATE' => 'frissítéskor', 'ON UPDATE' => 'frissítéskor',
'Index Type' => 'Index típusa', 'Index Type' => 'Index típusa',
'Column (length)' => 'Oszop (méret)', 'length' => 'méret',
'View has been dropped.' => 'A nézet eldobva.', 'View has been dropped.' => 'A nézet eldobva.',
'View has been altered.' => 'A nézet módosult.', 'View has been altered.' => 'A nézet módosult.',
'View has been created.' => 'A nézet létrejött.', 'View has been created.' => 'A nézet létrejött.',
@@ -175,7 +176,7 @@ $translations = array(
'Repair' => 'Javít', 'Repair' => 'Javít',
'Truncate' => 'Felszabadít', 'Truncate' => 'Felszabadít',
'Tables have been truncated.' => 'A tábla felszabadítva.', 'Tables have been truncated.' => 'A tábla felszabadítva.',
'Rows' => 'Oszlop', 'Rows' => 'Sorok',
',' => ' ', ',' => ' ',
'0123456789' => '0123456789', '0123456789' => '0123456789',
'Tables have been moved.' => 'Táblák áthelyezve.', 'Tables have been moved.' => 'Táblák áthelyezve.',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem', 'System' => 'Sistem',
@@ -73,7 +75,6 @@ $translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Basis data', 'Database' => 'Basis data',
'database' => 'basis data',
'Use' => 'Gunakan', 'Use' => 'Gunakan',
'Select database' => 'Pilih basis data', 'Select database' => 'Pilih basis data',
'Invalid database.' => 'Basis data tidak sah.', 'Invalid database.' => 'Basis data tidak sah.',
@@ -183,7 +184,7 @@ $translations = array(
'Alter indexes' => 'Ubah indeks', 'Alter indexes' => 'Ubah indeks',
'Add next' => 'Tambah setelahnya', 'Add next' => 'Tambah setelahnya',
'Index Type' => 'Jenis Indeks', 'Index Type' => 'Jenis Indeks',
'Column (length)' => 'Kolom (panjang)', 'length' => 'panjang',
'Foreign keys' => 'Kunci asing', 'Foreign keys' => 'Kunci asing',
'Foreign key' => 'Kunci asing', 'Foreign key' => 'Kunci asing',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Autenticazione', 'Login' => 'Autenticazione',
'Logout successful.' => 'Uscita effettuata con successo.', 'Logout successful.' => 'Uscita effettuata con successo.',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'Crea database', 'Create database' => 'Crea database',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Esci', 'Logout' => 'Esci',
'database' => 'database',
'Use' => 'Usa', 'Use' => 'Usa',
'No tables.' => 'No tabelle.', 'No tables.' => 'No tabelle.',
'select' => 'seleziona', 'select' => 'seleziona',
@@ -96,7 +97,7 @@ $translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Tipo indice', 'Index Type' => 'Tipo indice',
'Column (length)' => 'Colonna (lunghezza)', 'length' => 'lunghezza',
'View has been dropped.' => 'Vista eliminata.', 'View has been dropped.' => 'Vista eliminata.',
'View has been altered.' => 'Vista modificata.', 'View has been altered.' => 'Vista modificata.',
'View has been created.' => 'Vista creata.', 'View has been created.' => 'Vista creata.',
@@ -265,4 +266,39 @@ $translations = array(
'Permanent link' => 'Link permanente', 'Permanent link' => 'Link permanente',
'Edit all' => 'Modifica tutto', 'Edit all' => 'Modifica tutto',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
'Drop %s?' => 'Scartare %s?',
'Tables have been optimized.' => 'Le tabelle sono state ottimizzate',
'Materialized view' => 'Vista materializzata',
'Vacuum' => 'Aspira',
'Selected' => 'Selezionato',
'overwrite' => 'sovrascrivi',
'DB' => 'DB',
'File must be in UTF-8 encoding.' => 'Il file deve avere codifica UTF-8.',
'Modify' => 'Modifica',
'Load more data' => 'Carica piú dati',
'Loading' => 'Caricamento',
'ATTACH queries are not supported.' => 'ATTACH queries non sono supportate.',
'Warnings' => 'Attenzione',
'%d / ' => '%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.'),
'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.',
'There is a space in the input password which might be the cause.' => 'Esiste uno spazio nella passoword inserita che potrebbe essere la causa.',
'If you did not send this request from Adminer then close this page.' => 'Se non hai inviato tu la richiesta tramite Adminer puoi chiudere la pagina.',
'You can upload a big SQL file via FTP and import it from server.' => 'Puoi caricare un grande file SQL tramite FTP ed impirtarlo dal server.',
'Size' => 'Taglia',
'Compute' => 'Elabora',
'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',
'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',
); );

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'ログイン', 'Login' => 'ログイン',
'Logout successful.' => 'ログアウト', 'Logout successful.' => 'ログアウト',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'データベースを作成', 'Create database' => 'データベースを作成',
'SQL command' => 'SQLコマンド', 'SQL command' => 'SQLコマンド',
'Logout' => 'ログアウト', 'Logout' => 'ログアウト',
'database' => 'データベース',
'Use' => '使用', 'Use' => '使用',
'No tables.' => 'テーブルがありません。', 'No tables.' => 'テーブルがありません。',
'select' => '選択', 'select' => '選択',
@@ -95,7 +96,7 @@ $translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => '索引の型', 'Index Type' => '索引の型',
'Column (length)' => '列(長さ', 'length' => '長さ',
'View has been dropped.' => 'ビューを削除しました', 'View has been dropped.' => 'ビューを削除しました',
'View has been altered.' => 'ビューを変更しました', 'View has been altered.' => 'ビューを変更しました',
'View has been created.' => 'ビューを作成しました', 'View has been created.' => 'ビューを作成しました',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'შესვლა', 'Login' => 'შესვლა',
'Logout successful.' => 'გამოხვედით სისტემიდან.', 'Logout successful.' => 'გამოხვედით სისტემიდან.',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'ბაზის შექმნა', 'Create database' => 'ბაზის შექმნა',
'SQL command' => 'SQL-ბრძანება', 'SQL command' => 'SQL-ბრძანება',
'Logout' => 'გასვლა', 'Logout' => 'გასვლა',
'database' => 'ბაზა',
'Use' => 'არჩევა', 'Use' => 'არჩევა',
'No tables.' => 'ბაზაში ცხრილი არაა.', 'No tables.' => 'ბაზაში ცხრილი არაა.',
'select' => 'არჩევა', 'select' => 'არჩევა',
@@ -94,7 +95,7 @@ $translations = array(
'ON DELETE' => 'წაშლისას', 'ON DELETE' => 'წაშლისას',
'ON UPDATE' => 'განახლებისას', 'ON UPDATE' => 'განახლებისას',
'Index Type' => 'ინდექსის სახეობა', 'Index Type' => 'ინდექსის სახეობა',
'Column (length)' => 'ველი (სიგრძე)', 'length' => 'სიგრძე',
'View has been dropped.' => 'წარმოდგენა წაიშალა.', 'View has been dropped.' => 'წარმოდგენა წაიშალა.',
'View has been altered.' => 'წარმოდგენა შეიცვალა.', 'View has been altered.' => 'წარმოდგენა შეიცვალა.',
'View has been created.' => 'წარმოდგენა შეიქმნა.', 'View has been created.' => 'წარმოდგენა შეიქმნა.',

View File

@@ -1,267 +1,281 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => '로그인', '$1-$3-$5' => '$1-$3-$5',
'Logout successful.' => '로그아웃', '%.3f s' => '%.3f 초',
'Invalid credentials.' => '잘못된 로그인',
'Server' => '서버',
'Username' => '사용자이름',
'Password' => '비밀번호',
'Select database' => '데이터베이스를 선택하십시오.',
'Invalid database.' => '잘못된 데이터베이스입니다.',
'Table has been dropped.' => '테이블을 삭제했습니다.',
'Table has been altered.' => '테이블을 변경했습니다.',
'Table has been created.' => '테이블을 만들었습니다.',
'Alter table' => '테이블 변경',
'Create table' => '테이블 만들기',
'Table name' => '테이블 이름',
'engine' => '엔진',
'collation' => '정렬',
'Column name' => '열 이름',
'Type' => '형',
'Length' => '길이',
'Auto Increment' => '자동증가',
'Options' => '설정',
'Save' => '저장',
'Drop' => '삭제',
'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.' => '항목을 갱신했습니다.',
'Edit' => '편집',
'Insert' => '삽입',
'Save and insert next' => '저장하고 다음에 추가',
'Delete' => '삭제',
'Database' => '데이터베이스',
'Routines' => '루틴',
'Indexes have been altered.' => '인덱스를 변경했습니다.',
'Indexes' => '색인',
'Alter indexes' => '인덱스 변경',
'Add next' => '추가',
'Language' => '언어',
'Select' => '선택',
'New item' => '항목 만들기',
'Search' => '검색',
'Sort' => '정렬',
'descending' => '역순',
'Limit' => '제약',
'No rows.' => '행이 없습니다.',
'Action' => '실행',
'edit' => '편집',
'Page' => '페이지',
'Query executed OK, %d row(s) affected.' => '쿼리를 실행했습니다. %d 행을 변경했습니다.',
'Error in query' => '쿼리의 오류',
'Execute' => '실행',
'Table' => '테이블',
'Foreign keys' => '외부 키',
'Triggers' => '트리거',
'View' => '보기',
'Unable to select the table' => '테이블을 선택할 수 없습니다.',
'Invalid CSRF token. Send the form again.' => '잘못된 CSRF 토큰. 다시 보내주십시오.',
'Comment' => '코멘트',
'Default values' => '기본값',
'%d byte(s)' => '%d 바이트', '%d byte(s)' => '%d 바이트',
'No commands to execute.' => '실행할 수 있는 명령이 없습니다.', '%d e-mail(s) have been sent.' => '%d개 메일을 보냈습니다.',
'Unable to upload a file.' => '파일을 업로드 할 수 없습니다.', '%d in total' => '총 %d개',
'File upload' => '파일 올리기', '%d item(s) have been affected.' => '%d개 항목을 갱신했습니다.',
'File uploads are disabled.' => '파일 업로드가 잘못되었습니다.', '%d process(es) have been killed.' => '%d개 프로세스를 강제 종료하였습니다.',
'Routine has been called, %d row(s) affected.' => '루틴을 호출했습니다. %d 행을 변경했습니다.', '%d query(s) executed OK.' => '%d개 쿼리를 잘 실행했습니다.',
'Call' => '외침', '%d row(s) have been imported.' => '%d개 행을 가져 왔습니다.',
'No extension' => '확장 기능이 없습니다.', '%d row(s)' => '%d개 행',
'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' => '외부 키',
'Target table' => '테이블',
'Change' => '변경',
'Source' => '소스',
'Target' => '타겟',
'Add column' => '열 추가',
'Alter' => '변경',
'Add foreign key' => '외부 키를 추가',
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Index Type' => '인덱스 형',
'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 프로세스를 강제 종료되었습니다.',
'Kill' => '강제 종료',
'Parameter name' => '참조 여명',
'Database schema' => '구조',
'Create procedure' => '시저 만들기',
'Create function' => '함수 만들기',
'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.' => '트리거를 추가했습니다.',
'Alter trigger' => '트리거 변경',
'Create trigger' => '트리거 만들기',
'Time' => '시간',
'Event' => '이벤트',
'%s version: %s through PHP extension %s' => '%s 버전 %s, PHP 확장 %s', '%s version: %s through PHP extension %s' => '%s 버전 %s, PHP 확장 %s',
'%d row(s)' => '%d 행',
'Remove' => '제외',
'Are you sure?' => '실행 하시겠습니까?',
'Privileges' => '권한',
'Create user' => '사용자 만들기',
'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 설정을 늘리십시오.',
'Move up' => '상',
'Move down' => '아래',
'Export' => '내보내기',
'Tables' => '테이블',
'Data' => '데이터',
'Output' => '출력',
'open' => '열',
'save' => '저장',
'Format' => '형식',
'Functions' => '함수',
'Aggregation' => '집합',
'Event has been dropped.' => '삭제했습니다.',
'Event has been altered.' => '변경했습니다.',
'Event has been created.' => '만들었습니다.',
'Alter event' => '변경',
'Create event' => '만들기',
'Start' => '시작',
'End' => '종료',
'Every' => '매번',
'Status' => '상태',
'On completion preserve' => '완성 후 저장',
'Events' => '이벤트',
'Schedule' => '일정',
'At given time' => '지정 시간',
'Tables have been truncated.' => '테이블을 truncate했습니다.',
'Tables have been moved.' => '테이블을 옮겼습니다.',
'Tables and views' => '테이블과 뷰',
'Engine' => '엔진',
'Collation' => '정렬',
'Data Length' => '데이터 길이',
'Index Length' => '인덱스 길이',
'Data Free' => '여유',
'Rows' => '행',
',' => ',', ',' => ',',
'0123456789' => '0123456789', '0123456789' => '0123456789',
'Analyze' => '분석',
'Optimize' => '최적화',
'Check' => '확인',
'Repair' => '복구',
'Truncate' => 'Truncate',
'Move to other database' => '다른 데이터베이스로 이동',
'Move' => '이동',
'Save and continue edit' => '저장하고 계속',
'original' => '원래',
'%d item(s) have been affected.' => '%d를 갱신했습니다.',
'Whole result' => '모든 결과',
'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 행을 가져 왔습니다.',
'Show structure' => '구조',
'anywhere' => '모든',
'Import' => '가져 오기',
'Stop on error' => '오류의 경우 중지',
'Select data' => '데이터',
'%.3f s' => '%.3f 초',
'$1-$3-$5' => '$1-$3-$5',
'[yyyy]-mm-dd' => '[yyyy]-mm-dd', '[yyyy]-mm-dd' => '[yyyy]-mm-dd',
'History' => '역사', 'Action' => '실행',
'Variables' => '변수', 'Add column' => '열 추가',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => '원본 및 대상 열은 동일한 데이터 형식이어야합니다. 목표 컬럼에 인덱스와 데이터가 존재해야합니다.', 'Add foreign key' => '외부 키를 추가',
'Relations' => '관계', 'Add next' => '다음 추가',
'Run file' => '파일을 실행', 'Add trigger' => '트리거 추가',
'Clear' => '삭제', 'Aggregation' => '집합',
'Maximum allowed file size is %sB.' => '파일의 최대 크기 %sB', 'Alter database' => '데이터베이스 변경',
'Numbers' => '숫자', 'Alter event' => '이벤트 변경',
'Date and time' => '시간', 'Alter function' => '함수 변경',
'Strings' => '문자열', 'Alter indexes' => '색인 변경',
'Binary' => '이진', 'Alter procedure' => '시저 변경',
'Lists' => '목록',
'Editor' => '에디터',
'E-mail' => '메일',
'From' => '보낸 사람',
'Subject' => '제목',
'Send' => '보내기',
'%d e-mail(s) have been sent.' => '%d 메일을 보냈습니다.',
'Webserver file %s' => 'Web 서버 파일 %s',
'File does not exist.' => '파일이 존재하지 않습니다.',
'%d in total' => '총 %d',
'Permanent login' => '영구적으로 로그인',
'Databases have been dropped.' => '데이터베이스를 삭제했습니다.',
'Search data in tables' => '데이터 검색',
'Schema' => '스키마',
'Alter schema' => '스키마 변경', 'Alter schema' => '스키마 변경',
'Create schema' => '스키마 추가',
'Schema has been dropped.' => '스키마를 삭제했습니다.',
'Schema has been created.' => '스키마를 추가했습니다.',
'Schema has been altered.' => '스키마를 변경했습니다.',
'Sequences' => '시퀀스',
'Create sequence' => '시퀀스 만들기',
'Alter sequence' => '순서 변경', 'Alter sequence' => '순서 변경',
'Sequence has been dropped.' => '시퀀스를 제거했습니다.', 'Alter table' => '테이블 변경',
'Sequence has been created.' => '시퀀스를 추가했습니다.', 'Alter trigger' => '트리거 변경',
'Sequence has been altered.' => '순서를 변경했습니다.', 'Alter type' => '형 변경',
'User types' => '사용자 정의 형', 'Alter view' => '보기 변경',
'Create type' => '사용자 정의 형식 만들기', 'Alter' => '변경',
'Alter type' => '사용자 정의 형식 변경', 'Analyze' => '분석',
'Type has been dropped.' => '사용자 정의 형식을 삭제했습니다.', 'anywhere' => '모든',
'Type has been created.' => '사용자 정의 형식을 추가했습니다.', 'Are you sure?' => '실행 하시겠습니까?',
'Use edit link to modify this value.' => '링크 편집', 'At given time' => '지정 시간',
'last' => '마지막',
'From server' => '서버에서 실행',
'System' => '데이터베이스 형식',
'empty' => '하늘',
'Network' => '네트워크 형',
'Geometry' => '기하 형',
'File exists.' => '파일이 이미 있습니다.',
'Attachments' => '첨부 파일', 'Attachments' => '첨부 파일',
'Item%s has been inserted.' => '%s 항목을 삽입했습니다.', 'Auto Increment' => '자동 증가',
'now' => '현재 시간', 'Binary' => '이진',
'%d query(s) executed OK.' => '%d 쿼리를 실행했습니다.', 'Call' => '호출',
'Show only errors' => '오류 만 표시', 'Change' => '변경',
'Refresh' => '새로 고침', 'Check' => '확인',
'Invalid schema.' => '잘못된 스키마', 'Clear' => '삭제',
'Please use one of the extensions %s.' => '하나의 확장 기능을 사용하십시오 %s', 'Clone' => '복제',
'ltr' => 'ltr', 'collation' => '정렬',
'Tables have been copied.' => '테이블을 복사했습니다', 'Collation' => '정렬',
'length' => '길이',
'Column name' => '열 이름',
'Column' => '열',
'Comment' => '주석',
'Compute' => '계산하기',
'Copy' => '복사', 'Copy' => '복사',
'Permanent link' => '영구 링크', 'Create database' => '데이터베이스 만들기',
'Edit all' => '모든 편집', 'Create event' => '만들기',
'Create function' => '함수 만들기',
'Create procedure' => '시저 만들기',
'Create schema' => '스키마 추가',
'Create sequence' => '시퀀스 만들기',
'Create table' => '테이블 만들기',
'Create trigger' => '트리거 만들기',
'Create type' => '사용자 정의 형식 만들기',
'Create user' => '사용자 만들기',
'Create view' => '뷰 만들기',
'Data Free' => '데이터 여유',
'Data Length' => '데이터 길이',
'Data' => '데이터',
'Database has been altered.' => '데이터베이스를 변경했습니다.',
'Database has been created.' => '데이터베이스를 만들었습니다.',
'Database has been dropped.' => '데이터베이스를 삭제했습니다.',
'Database has been renamed.' => '데이터베이스의 이름을 바꾸었습니다.',
'Database schema' => '데이터베이스 구조',
'Database' => '데이터베이스',
'Databases have been dropped.' => '데이터베이스를 삭제했습니다.',
'Date and time' => '시간',
'Default values' => '기본값',
'Delete' => '삭제',
'descending' => '역순',
'Drop' => '삭제',
'E-mail' => '메일',
'Edit all' => '모두 편집',
'Edit' => '편집',
'edit' => '편집',
'Editor' => '에디터',
'empty' => '비어있음',
'End' => '종료',
'engine' => '엔진',
'Engine' => '엔진',
'Error in query' => '쿼리의 오류',
'Event has been altered.' => '변경했습니다.',
'Event has been created.' => '만들었습니다.',
'Event has been dropped.' => '삭제했습니다.',
'Event' => '이벤트',
'Events' => '이벤트',
'Every' => '매 번',
'Execute' => '실행',
'Export' => '내보내기',
'File does not exist.' => '파일이 존재하지 않습니다.',
'File exists.' => '파일이 이미 있습니다.',
'File upload' => '파일 올리기',
'File uploads are disabled.' => '파일 업로드가 잘못되었습니다.',
'Foreign key has been altered.' => '외부 키를 변경했습니다.',
'Foreign key has been created.' => '외부 키를 만들었습니다.',
'Foreign key has been dropped.' => '외부 키를 제거했습니다.',
'Foreign key' => '외부 키',
'Foreign keys' => '외부 키',
'Format' => '형식',
'From server' => '서버에서 실행',
'From' => '보낸 사람',
'Functions' => '함수',
'Geometry' => '기하 형',
'Grant' => '권한 부여',
'Hashed' => 'Hashed',
'HH:MM:SS' => '시:분:초', 'HH:MM:SS' => '시:분:초',
'History' => '이력',
'Import' => '가져 오기',
'Index Length' => '색인 길이',
'Index Type' => '색인 형',
'Indexes have been altered.' => '색인을 변경했습니다.',
'Indexes' => '색인',
'Insert' => '삽입',
'Invalid credentials.' => '잘못된 로그인',
'Invalid CSRF token. Send the form again.' => '잘못된 CSRF 토큰입니다. 다시 보내주십시오.',
'Invalid database.' => '잘못된 데이터베이스입니다.',
'Invalid schema.' => '잘못된 스키마입니다.',
'Item has been deleted.' => '항목을 삭제했습니다.',
'Item has been updated.' => '항목을 갱신했습니다.',
'Item%s has been inserted.' => '%s 항목을 삽입했습니다.',
'Kill' => '강제 종료',
'Language' => '언어',
'last' => '마지막',
'Length' => '길이',
'Limit rows' => '행 제약',
'Limit' => '제약',
'Lists' => '목록',
'Load more data' => '더 많은 데이터 부르기',
'Loading' => '부르는 중',
'Logged as: %s' => '다음으로 로그인했습니다: %s',
'Login' => '로그인',
'Logout successful.' => '로그아웃을 성공했습니다.',
'Logout' => '로그아웃',
'ltr' => 'ltr',
'Maximum allowed file size is %sB.' => '파일의 최대 크기 %sB',
'Maximum number of allowed fields exceeded. Please increase %s.' => '정의 가능한 최대 필드 수를 초과했습니다. %s(을)를 늘리십시오.',
'Modify' => '수정',
'Move down' => '아래로',
'Move to other database' => '다른 데이터베이스로 이동',
'Move up' => '위로',
'Move' => '이동',
'Name' => '이름',
'Network' => '네트워크 형',
'New item' => '항목 만들기',
'No commands to execute.' => '실행할 수 있는 명령이 없습니다.',
'No extension' => '확장이 없습니다.',
'No rows.' => '행이 없습니다.',
'No tables.' => '테이블이 없습니다.',
'None of the supported PHP extensions (%s) are available.' => 'PHP 확장(%s)이 설치되어 있지 않습니다.',
'now' => '현재 시간',
'Numbers' => '숫자',
'On completion preserve' => '완성 후 저장',
'ON DELETE' => '지울 때',
'ON UPDATE' => '업데이트할 때',
'open' => '열',
'Optimize' => '최적화',
'Options' => '설정',
'original' => '원본',
'Output' => '출력',
'overwrite' => '덮어쓰기',
'Page' => '페이지',
'Parameter name' => '매개변수 이름',
'Partition by' => '파티션',
'Partition name' => '파티션 이름',
'Partitions' => '파티션',
'Password' => '비밀번호',
'Permanent link' => '영구적으로 링크',
'Permanent login' => '영구적으로 로그인',
'Please use one of the extensions %s.' => '확장 %s 중 하나를 사용하십시오.',
'Privileges' => '권한',
'Process list' => '프로세스 목록',
'Query executed OK, %d row(s) affected.' => '쿼리를 잘 실행했습니다. %d행을 변경했습니다.',
'Refresh' => '새로 고침',
'Relations' => '관계',
'Remove' => '제거',
'Repair' => '복구',
'Return type' => '반환 형식',
'Revoke' => '권한 취소',
'Routine has been altered.' => '루틴을 변경했습니다.',
'Routine has been called, %d row(s) affected.' => '루틴을 호출했습니다. %d 행을 변경했습니다.',
'Routine has been created.' => '루틴을 추가했습니다.',
'Routine has been dropped.' => '루틴을 제거했습니다.',
'Routine' => '루틴',
'Routines' => '루틴',
'Rows' => '행',
'Run file' => '파일을 실행',
'Save and continue edit' => '저장하고 계속 편집하기',
'Save and insert next' => '저장하고 다음에 추가',
'Save' => '저장',
'save' => '저장',
'Schedule' => '예약',
'Schema has been altered.' => '스키마를 변경했습니다.',
'Schema has been created.' => '스키마를 추가했습니다.',
'Schema has been dropped.' => '스키마를 삭제했습니다.',
'Schema' => '스키마',
'Search data in tables' => '테이블 내 데이터 검색',
'Search' => '검색',
'Select data' => '데이터를 선택하십시오.',
'Select database' => '데이터베이스를 선택하십시오.',
'Select' => '선택',
'select' => '선택',
'Selected' => '선택됨',
'Send' => '보내기',
'Sequence has been altered.' => '시퀀스를 변경했습니다.',
'Sequence has been created.' => '시퀀스를 추가했습니다.',
'Sequence has been dropped.' => '시퀀스를 제거했습니다.',
'Sequences' => '시퀀스',
'Server' => '서버',
'Session expired, please login again.' => '세션이 만료되었습니다. 다시 로그인하십시오.',
'Session support must be enabled.' => '세션 지원을 사용해야만 합니다.',
'Show only errors' => '오류 만 표시',
'Show structure' => '구조 표시',
'Size' => '크기',
'Sort' => '정렬',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => '원본과 대상 열은 동일한 데이터 형식이어야만 합니다. 목표 열에 색인과 데이터가 존재해야만 합니다.',
'Source' => '소스',
'SQL command' => 'SQL 명령',
'Start' => '시작',
'Status' => '상태',
'Stop on error' => '오류의 경우 중지',
'Strings' => '문자열',
'Subject' => '제목',
'System' => '데이터베이스 형식',
'Table has been altered.' => '테이블을 변경했습니다.',
'Table has been created.' => '테이블을 만들었습니다.',
'Table has been dropped.' => '테이블을 삭제했습니다.',
'Table name' => '테이블 이름',
'Table' => '테이블',
'Tables and views' => '테이블과 뷰',
'Tables have been copied.' => '테이블을 복사했습니다',
'Tables have been dropped.' => '테이블을 삭제했습니다.',
'Tables have been moved.' => '테이블을 옮겼습니다.',
'Tables have been truncated.' => '테이블의 데이터 내용만 지웠습니다.',
'Tables' => '테이블',
'Target table' => '테이블',
'Target' => '타겟',
'Text length' => '문자열의 길이',
'Time' => '시간',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'POST 데이터가 너무 큽니다. 데이터 크기를 줄이거나 %s 설정을 늘리십시오.',
'Trigger has been altered.' => '트리거를 변경했습니다.',
'Trigger has been created.' => '트리거를 추가했습니다.',
'Trigger has been dropped.' => '트리거를 제거했습니다.',
'Triggers' => '트리거',
'Truncate' => '데이터 내용만 지우기',
'Type has been created.' => '유형을 추가했습니다.',
'Type has been dropped.' => '유형을 삭제했습니다.',
'Type' => '형',
'Unable to select the table' => '테이블을 선택할 수 없습니다.',
'Unable to upload a file.' => '파일을 업로드 할 수 없습니다.',
'Use edit link to modify this value.' => '이 값을 수정하려면 편집 링크를 사용하십시오.',
'Use' => '사용',
'User has been altered.' => '사용자를 변경했습니다.',
'User has been created.' => '사용자를 만들었습니다.',
'User has been dropped.' => '사용자를 제거했습니다.',
'Username' => '사용자이름',
'Vacuum' => '청소',
'Values' => '값',
'Variables' => '변수',
'View has been altered.' => '보기를 변경했습니다.',
'View has been created.' => '보기를 만들었습니다.',
'View has been dropped.' => '보기를 삭제했습니다.',
'View' => '보기',
'Warnings' => '경고',
'Webserver file %s' => '웹서버 파일 %s',
'Whole result' => '모든 결과',
'yes' => '네',
'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.' => '이 테이블을 업데이트할 권한이 없습니다.',
); );

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistema', 'System' => 'Sistema',
@@ -73,7 +75,6 @@ $translations = array(
'Data' => 'Duomenys', 'Data' => 'Duomenys',
'Database' => 'Duomenų bazė', 'Database' => 'Duomenų bazė',
'database' => 'duomenų bazė',
'Use' => 'Naudoti', 'Use' => 'Naudoti',
'Select database' => 'Pasirinkti duomenų bazę', 'Select database' => 'Pasirinkti duomenų bazę',
'Invalid database.' => 'Neteisinga duomenų bazė.', 'Invalid database.' => 'Neteisinga duomenų bazė.',
@@ -182,7 +183,7 @@ $translations = array(
'Alter indexes' => 'Redaguoti indeksus', 'Alter indexes' => 'Redaguoti indeksus',
'Add next' => 'Pridėti kitą', 'Add next' => 'Pridėti kitą',
'Index Type' => 'Indekso tipas', 'Index Type' => 'Indekso tipas',
'Column (length)' => 'Stulpelis (ilgis)', 'length' => 'ilgis',
'Foreign keys' => 'Išoriniai raktai', 'Foreign keys' => 'Išoriniai raktai',
'Foreign key' => 'Išorinis raktas', 'Foreign key' => 'Išorinis raktas',

304
adminer/lang/lv.inc.php Normal file
View File

@@ -0,0 +1,304 @@
<?php
namespace Adminer;
$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.',
'Server' => 'Serveris',
'Username' => 'Lietotājs',
'Password' => 'Parole',
'Select database' => 'Izvēlēties datubāzi',
'Invalid database.' => 'Nederīga datubāze.',
'Table has been dropped.' => 'Tabula dzēsta.',
'Table has been altered.' => 'Tabula mainīta.',
'Table has been created.' => 'Tabula izveidota.',
'Alter table' => 'Mainīt tabulu',
'Create table' => 'Izveidot tabulu',
'Table name' => 'Tabulas nosaukums',
'engine' => 'Tabulas tips',
'collation' => 'Kolācija',
'Column name' => 'Lauka nosaukums',
'Type' => 'Tips',
'Length' => 'Garums',
'Auto Increment' => 'Auto inkrements',
'Options' => 'Opcijas',
'Save' => 'Saglabāt',
'Drop' => 'Dzēst',
'Database has been dropped.' => 'Datubāze tika nodzēsta.',
'Database has been created.' => 'Datubāze tika izveidota.',
'Database has been renamed.' => 'Datubāze tika pārsaukta.',
'Database has been altered.' => 'Datubāze tika mainīta.',
'Alter database' => 'Mainīt datubāzi',
'Create database' => 'Izveidot datubāzi',
'SQL command' => 'SQL pieprasījums',
'Logout' => 'Iziet',
'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 tika ievietoti.',
'Edit' => 'Rediģēt',
'Insert' => 'Ievietot',
'Save and insert next' => 'Saglabāt un ievietot nākamo',
'Delete' => 'Dzēst',
'Database' => 'Datubāze',
'Routines' => 'Procedūras un funkcijas',
'Indexes have been altered.' => 'Indeksi mainīti.',
'Indexes' => 'Indeksi',
'Alter indexes' => 'Izmainīt indeksus',
'Add next' => 'Pievienot vēl',
'Language' => 'Valoda',
'Select' => 'Izvēlēties',
'New item' => 'Jauns ieraksts',
'Search' => 'Meklēšana',
'Sort' => 'Kārtošana',
'descending' => 'dilstoši',
'Limit' => 'Limits',
'No rows.' => 'Nav rindu.',
'Action' => 'Darbība',
'edit' => 'rediģēt',
'Page' => 'Lapa',
'Query executed OK, %d row(s) affected.' => array('Pieprasījums pabeigts, izmainīts %d ieraksts.', 'Pieprasījums pabeigts, izmainīti %d ieraksti.', 'Pieprasījums pabeigts, izmainīti %d ieraksti.'),
'Error in query' => 'Kļūda pieprasījumā',
'Execute' => 'Izpidīt',
'Table' => 'Tabula',
'Foreign keys' => 'Ārejā atslēgas',
'Triggers' => 'Trigeri',
'View' => 'Skats',
'Unable to select the table' => 'Tabula nav pieejama',
'Invalid CSRF token. Send the form again.' => 'Nederīgs CSRF žetons. Nosūtiet formu vēl vienu reizi.',
'Comment' => 'Komentārs',
'Default values' => 'Noklusētā vērtība',
'%d byte(s)' => array('%d baits', '%d baiti', '%d baiti'),
'No commands to execute.' => 'Nav izpildāmu komandu.',
'Unable to upload a file.' => 'Neizdevās ielādēt failu uz servera.',
'File upload' => 'Augšupielāde',
'File uploads are disabled.' => 'Augšupielādes aizliegtas.',
'Routine has been called, %d row(s) affected.' => array('Procedūra izsaukta, izmainīts %d ieraksts.', 'Procedūra izsaukta, izmainīti %d ieraksti.', 'Procedūra izsaukta, izmainīti %d ieraksti.'),
'Call' => 'Izsaukt',
'No extension' => 'Nav paplašinājuma',
'None of the supported PHP extensions (%s) are available.' => 'Neviens PHP no atbalstītajiem paplašinājumiem (%s) nav pieejams.',
'Session support must be enabled.' => 'Sesiju atbalstam jābūt ieslēgtam.',
'Session expired, please login again.' => 'Sesijas laiks ir beidzies, piesakies no jauna sistēmā.',
'Text length' => 'Teksta garums',
'Foreign key has been dropped.' => 'Ārejā atslēga dzēsta.',
'Foreign key has been altered.' => 'Ārejā atslēga izmainīta.',
'Foreign key has been created.' => 'Ārejā atslēga izveidota.',
'Foreign key' => 'Ārejā atslēga',
'Target table' => 'Mērķa tabula',
'Change' => 'Mainīt',
'Source' => 'Avots',
'Target' => 'Mērķis',
'Add column' => 'Pievienot lauku',
'Alter' => 'Izmainīt',
'Add foreign key' => 'Pievienot ārējo atslēgu',
'ON DELETE' => 'Pie dzēšanas',
'ON UPDATE' => 'Pie atjaunošanas',
'Index Type' => 'Indeksa tips',
'length' => 'garums',
'View has been dropped.' => 'Skats dzēsts.',
'View has been altered.' => 'Skats izmainīts.',
'View has been created.' => 'Skats izveidots.',
'Alter view' => 'Izmainīt skatu',
'Create view' => 'Izveidot skatu',
'Name' => 'Nosaukums',
'Process list' => 'Procesu saraksts',
'%d process(es) have been killed.' => array('Pabeigts %d process.', 'Pabeigti %d procesi.', 'Pabeigti %d procesi.'),
'Kill' => 'Nobeigt',
'Parameter name' => 'Parametra nosaukums',
'Database schema' => 'Datubāzes shēma',
'Create procedure' => 'Izveidot procedūru',
'Create function' => 'Izveidot funkciju',
'Routine has been dropped.' => 'Procedūru dzēsta.',
'Routine has been altered.' => 'Procedūru izmainīta.',
'Routine has been created.' => 'Procedūru izveidota.',
'Alter function' => 'Mainīt funkciju',
'Alter procedure' => 'Mainīt procedūru',
'Return type' => 'Atgriezt tips',
'Add trigger' => 'Pievienot trigeri',
'Trigger has been dropped.' => 'Trigeris dzēsts.',
'Trigger has been altered.' => 'Trigeris izmainīts.',
'Trigger has been created.' => 'Trigeris izveidots.',
'Alter trigger' => 'Izmainīt trigeri',
'Create trigger' => 'Izveidot trigeri',
'Time' => 'Laiks',
'Event' => 'Notikums',
'%s version: %s through PHP extension %s' => 'Versija %s: %s ar PHP paplašinājumu %s',
'%d row(s)' => array('%d rinda', '%d rindas', '%d rindu'),
'Remove' => 'Noņemt',
'Are you sure?' => 'Vai Tu esi pārliecināts?',
'Privileges' => 'Tiesības',
'Create user' => 'Izveidot lietotāju',
'User has been dropped.' => 'Lietotājs dzests.',
'User has been altered.' => 'Lietotājs izmainīts.',
'User has been created.' => 'Lietotājs izveidots.',
'Hashed' => 'Sajaukts',
'Column' => 'Lauks',
'Routine' => 'Procedūra',
'Grant' => 'Atļaut',
'Revoke' => 'Aizliegt',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'POST metodes pieprasījums apjoms par lielu. Atsūtiet mazāka apjoma pieprasījumu kā konfigurācijas %s.',
'Logged as: %s' => 'Ielogojies kā: %s',
'Move up' => 'Pārvietot uz augšu',
'Move down' => 'Pārvietot uz leju',
'Functions' => 'Funkcijas',
'Aggregation' => 'Agregācija',
'Export' => 'Eksports',
'Output' => 'Izejas dati',
'open' => 'atvērt',
'save' => 'saglabāt',
'Format' => 'Formāts',
'Tables' => 'Tabulas',
'Data' => 'Dati',
'Event has been dropped.' => 'Notikums dzēsts.',
'Event has been altered.' => 'Notikums izmainīts.',
'Event has been created.' => 'Notikums izveidots.',
'Alter event' => 'Izmainīt notikumu',
'Create event' => 'Izveidot notikumu',
'At given time' => 'Norāditā laikā',
'Every' => 'Katru',
'Events' => 'Notikumi',
'Schedule' => 'Grafiks',
'Start' => 'Sākums',
'End' => 'Beigas',
'Status' => 'Statuss',
'On completion preserve' => 'Beigās saglabāt',
'Tables and views' => 'Tabulas un skati',
'Data Length' => 'Datu apjoms',
'Index Length' => 'Indeksu izmērs',
'Data Free' => 'Brīvā vieta',
'Collation' => 'Kolācija',
'Analyze' => 'Analizēt',
'Optimize' => 'Optimizēt',
'Check' => 'Pārbaudīt',
'Repair' => 'Salabot',
'Truncate' => 'Iztīrīt',
'Tables have been truncated.' => 'Tabulas iztīrītas.',
'Rows' => 'Rindas',
',' => ' ',
'0123456789' => '0123456789',
'Tables have been moved.' => 'Tabulas pārvietotas.',
'Move to other database' => 'Pārvietot uz citu datubāzi',
'Move' => 'Pārvietot',
'Engine' => 'Dzinējs',
'Save and continue edit' => 'Saglabāt un turpināt rediģēt',
'original' => 'oriģināls',
'%d item(s) have been affected.' => array('Izmainīts %d ieraksts.', 'Izmainīti %d ieraksti.', 'Izmainīti %d ieraksti.'),
'Whole result' => 'Viss rezultāts',
'Tables have been dropped.' => 'Tabulas dzēstas.',
'Clone' => 'Klonēt',
'Partition by' => 'Sadalīt pēc',
'Partitions' => 'Partīcijas',
'Partition name' => 'Partīcijas nosaukums',
'Values' => 'Vērtības',
'%d row(s) have been imported.' => array('Importēta %d rinda.', 'Importētas %d rindas.', 'Importētas %d rindas.'),
'Import' => 'Imports',
'Stop on error' => 'Astāties kļūdas gadījumā',
'Maximum number of allowed fields exceeded. Please increase %s.' => 'Sasniegts maksimālais lauku skaita ierobežojums. Palieliniet %s.',
'anywhere' => 'jebkurā vietā',
'%.3f s' => '%.3f s',
'$1-$3-$5' => '$5.$3.$1',
'[yyyy]-mm-dd' => 'dd.mm.[gggg]',
'History' => 'Vēsture',
'Variables' => 'Mainīgie',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'Lauku tipiem jābūt vienādiem, rezultējošā laukā jābut indeksa datiem.',
'Relations' => 'Relācijas',
'Run file' => 'Izpildīt failu',
'Clear' => 'Notīrīt',
'Maximum allowed file size is %sB.' => 'Faila maksimālais izmērs — %sB.',
'Numbers' => 'Skaitļi',
'Date and time' => 'Datums un laiks',
'Strings' => 'Virknes',
'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',
'Permanent login' => 'Atcerēties mani',
'Databases have been dropped.' => 'Datubāzes dzēstas.',
'Search data in tables' => 'Meklēt tabulās',
'Schema' => 'Shēma',
'Alter schema' => 'Izmainīt shēmu',
'Create schema' => 'Jauna shēma',
'Schema has been dropped.' => 'Shēma dzēsta.',
'Schema has been created.' => 'Izveidota jauna shēma.',
'Schema has been altered.' => 'Shēma izmainīta.',
'Sequences' => 'Virknes',
'Create sequence' => 'Izveidot virkni',
'Alter sequence' => 'Izmainīt virkni',
'Sequence has been dropped.' => 'Virkne dzēsta.',
'Sequence has been created.' => 'Izveidota virkne.',
'Sequence has been altered.' => 'Virkne izmainīta.',
'User types' => 'Lietotāju tipi',
'Create type' => 'Izveidot tipu',
'Alter type' => 'Izmainīt tipu',
'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".',
'last' => 'pēdējā',
'From server' => 'No servera',
'System' => 'Sistēma',
'Select data' => 'Izvēlēties datus',
'Show structure' => 'Parādīt struktūru',
'empty' => 'tukšs',
'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',
'Invalid schema.' => 'Nederīga shēma.',
'Please use one of the extensions %s.' => 'Izmainojiet kādu no paplašinājumiem %s.',
'now' => 'tagad',
'ltr' => 'ltr',
'Tables have been copied.' => 'Tabulas nokopētas.',
'Copy' => 'kopēt',
'Permanent link' => 'Pastāvīga saite',
'Edit all' => 'Rediģēt visus',
'HH:MM:SS' => 'HH:MM:SS',
'Tables have been optimized.' => 'Tabulas optimizētas.',
'Materialized view' => 'Matrializēts skats',
'Vacuum' => 'Vakums',
'Selected' => 'Izvēlētie',
'File must be in UTF-8 encoding.' => 'Failam jābūt UTF-8 kodējumam.',
'Modify' => 'Izmainīt',
'Loading' => 'Ielāde',
'Load more data' => 'Ielādēt vēl datus',
'ATTACH queries are not supported.' => 'ATTACH-pieprasījumi nav atbalstīti.',
'%d / ' => '%d / ',
'Limit rows' => 'Rindu limits',
'Default value' => 'Noklusētā vērtība',
'Full table scan' => 'Pilna tabulas analīze',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Pieteikšanās mēģinājumu skaits par lielu. Mēginiet pēc %d minūtes.', 'Pieteikšanās mēģinājumu skaits par lielu. Mēginiet pēc %d minūtēm.', 'Pieteikšanās mēģinājumu skaits par lielu. Mēginiet pēc %d minūtēm.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-parole nav derīga. <a href="https://www.adminer.org/en/extension/"%s>Implementējiet</a> metodi %s, lai padarīgu šo par ierastu metodi.',
'If you did not send this request from Adminer then close this page.' => 'Ja nesūtījāt šo pieprasījumu no Adminer, tad aizveriet pārlūka logu.',
'You can upload a big SQL file via FTP and import it from server.' => 'Varat ielādēt lielu SQL failu uz servera un tad importēt to.',
'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.',
'Saving' => 'Saglabāšana',
'yes' => 'Jā',
'no' => 'Nē',
'Drop %s?' => 'Dzēst %s?',
'overwrite' => 'pārrakstīt',
'DB' => 'DB',
'Warnings' => 'Brīdinājumi',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer neatbalsta pieeju bez paroles, <a href="https://www.adminer.org/en/password/"%s>vairāk informācijas šeit</a>.',
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => 'Paldies, ka izmantoji Adminer, vai vēlies veikt <a href="https://www.adminer.org/en/donation/">ziedojumu</a>.',
'The action will be performed after successful login with the same credentials.' => 'Darbība tiks pabeigta pēc derīgas pieteikšanās sistēmā.',
'Connecting to privileged ports is not allowed.' => 'Pieeja priviliģētiem portiem nav atļauta.',
'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.',
);

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem', 'System' => 'Sistem',
@@ -82,7 +84,6 @@ $translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Pangkalan data', 'Database' => 'Pangkalan data',
'database' => 'pangkalan data',
'Use' => 'Guna', 'Use' => 'Guna',
'Select database' => 'Pilih pangkalan data', 'Select database' => 'Pilih pangkalan data',
'Invalid database.' => 'Pangkalan data tidak sah.', 'Invalid database.' => 'Pangkalan data tidak sah.',
@@ -198,7 +199,7 @@ $translations = array(
'Alter indexes' => 'Ubah indeks', 'Alter indexes' => 'Ubah indeks',
'Add next' => 'Tambah yang seterusnya', 'Add next' => 'Tambah yang seterusnya',
'Index Type' => 'Jenis Indeks', 'Index Type' => 'Jenis Indeks',
'Column (length)' => 'Kolum (kepanjangan)', 'length' => 'kepanjangan',
'Foreign keys' => 'Kunci asing', 'Foreign keys' => 'Kunci asing',
'Foreign key' => 'Kunci asing', 'Foreign key' => 'Kunci asing',

View File

@@ -1,8 +1,10 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Inloggen', 'Login' => 'Aanmelden',
'Logout successful.' => 'Uitloggen geslaagd.', 'Logout successful.' => 'Successvol afgemeld.',
'Invalid credentials.' => 'Ongeldige logingegevens.', 'Invalid credentials.' => 'Ongeldige gebruikersgegevens.',
'Server' => 'Server', 'Server' => 'Server',
'Username' => 'Gebruikersnaam', 'Username' => 'Gebruikersnaam',
'Password' => 'Wachtwoord', 'Password' => 'Wachtwoord',
@@ -31,8 +33,7 @@ $translations = array(
'Alter database' => 'Database aanpassen', 'Alter database' => 'Database aanpassen',
'Create database' => 'Database aanmaken', 'Create database' => 'Database aanmaken',
'SQL command' => 'SQL opdracht', 'SQL command' => 'SQL opdracht',
'Logout' => 'Uitloggen', 'Logout' => 'Afmelden',
'database' => 'database',
'Use' => 'Gebruik', 'Use' => 'Gebruik',
'No tables.' => 'Geen tabellen.', 'No tables.' => 'Geen tabellen.',
'select' => 'kies', 'select' => 'kies',
@@ -41,7 +42,7 @@ $translations = array(
'Item%s has been inserted.' => 'Item%s toegevoegd.', 'Item%s has been inserted.' => 'Item%s toegevoegd.',
'Edit' => 'Bewerk', 'Edit' => 'Bewerk',
'Insert' => 'Toevoegen', 'Insert' => 'Toevoegen',
'Save and insert next' => 'Opslaan, daarna toevoegen', 'Save and insert next' => 'Opslaan en volgende toevoegen',
'Delete' => 'Verwijderen', 'Delete' => 'Verwijderen',
'Database' => 'Database', 'Database' => 'Database',
'Routines' => 'Procedures', 'Routines' => 'Procedures',
@@ -60,7 +61,7 @@ $translations = array(
'Action' => 'Acties', 'Action' => 'Acties',
'edit' => 'bewerk', 'edit' => 'bewerk',
'Page' => 'Pagina', 'Page' => 'Pagina',
'Query executed OK, %d row(s) affected.' => array('Query uitgevoerd, %d rij geraakt.', 'Query uitgevoerd, %d rijen beïnvloed.'), 'Query executed OK, %d row(s) affected.' => array('Query uitgevoerd, %d rij aangepast.', 'Query uitgevoerd, %d rijen aangepast.'),
'Error in query' => 'Fout in query', 'Error in query' => 'Fout in query',
'Execute' => 'Uitvoeren', 'Execute' => 'Uitvoeren',
'Table' => 'Tabel', 'Table' => 'Tabel',
@@ -81,7 +82,7 @@ $translations = array(
'No extension' => 'Geen extensie', 'No extension' => 'Geen extensie',
'None of the supported PHP extensions (%s) are available.' => 'Geen geldige PHP extensies beschikbaar (%s).', 'None of the supported PHP extensions (%s) are available.' => 'Geen geldige PHP extensies beschikbaar (%s).',
'Session support must be enabled.' => 'Sessies moeten geactiveerd zijn.', 'Session support must be enabled.' => 'Sessies moeten geactiveerd zijn.',
'Session expired, please login again.' => 'Uw sessie is verlopen. Gelieve opnieuw in te loggen.', 'Session expired, please login again.' => 'Uw sessie is verlopen. Gelieve opnieuw aan te melden.',
'Text length' => 'Tekst lengte', 'Text length' => 'Tekst lengte',
'Foreign key has been dropped.' => 'Foreign key verwijderd.', 'Foreign key has been dropped.' => 'Foreign key verwijderd.',
'Foreign key has been altered.' => 'Foreign key aangepast.', 'Foreign key has been altered.' => 'Foreign key aangepast.',
@@ -97,7 +98,7 @@ $translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Index type', 'Index Type' => 'Index type',
'Column (length)' => 'Kolom (lengte)', 'length' => 'lengte',
'View has been dropped.' => 'View verwijderd.', 'View has been dropped.' => 'View verwijderd.',
'View has been altered.' => 'View aangepast.', 'View has been altered.' => 'View aangepast.',
'View has been created.' => 'View aangemaakt.', 'View has been created.' => 'View aangemaakt.',
@@ -265,4 +266,39 @@ $translations = array(
'Permanent link' => 'Permanente link', 'Permanent link' => 'Permanente link',
'Edit all' => 'Alles bewerken', 'Edit all' => 'Alles bewerken',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
'Drop %s?' => 'Verwijder %s?',
'Tables have been optimized.' => 'Tabellen zijn geoptimaliseerd.',
'Materialized view' => 'Materialized view',
'Vacuum' => 'Vacuum',
'Selected' => 'Geselecteerd',
'overwrite' => 'overschrijven',
'DB' => 'DB',
'File must be in UTF-8 encoding.' => 'Het bestand moet met UTF-8 encodering zijn opgeslagen.',
'Modify' => 'Aanpassen',
'Load more data' => 'Meer data inladen',
'Loading' => 'Aan het laden',
'ATTACH queries are not supported.' => 'ATTACH queries worden niet ondersteund',
'Warnings' => 'Waarschuwingen',
'%d / ' => '%d / ',
'Limit rows' => 'Rijen beperken',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer ondersteunt geen toegang tot databases zonder wachtwoord, <a href="https://www.adminer.org/en/password/"%s>meer informatie</a>.',
'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.'),
'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',
'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.',
'You can upload a big SQL file via FTP and import it from server.' => 'U kan een groot SQL-bestand uploaden via FTP en het importeren via de server.',
'Size' => 'Grootte',
'Compute' => 'Bereken',
'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',
'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',
); );

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'System' => 'System', 'System' => 'System',
'Server' => 'Server', 'Server' => 'Server',
@@ -64,7 +66,6 @@ $translations = array(
'Format' => 'Format', 'Format' => 'Format',
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Database', 'Database' => 'Database',
'database' => 'database',
'Use' => 'Bruk', 'Use' => 'Bruk',
'Select database' => 'Velg database', 'Select database' => 'Velg database',
'Invalid database.' => 'Ugyldig database.', 'Invalid database.' => 'Ugyldig database.',
@@ -165,7 +166,7 @@ $translations = array(
'Alter indexes' => 'Endre indekser', 'Alter indexes' => 'Endre indekser',
'Add next' => 'Legg til neste', 'Add next' => 'Legg til neste',
'Index Type' => 'Indekstype', 'Index Type' => 'Indekstype',
'Column (length)' => 'Kolonne (lengde)', 'length' => 'lengde',
'Foreign keys' => 'Fremmednøkler', 'Foreign keys' => 'Fremmednøkler',
'Foreign key' => 'Fremmednøkkel', 'Foreign key' => 'Fremmednøkkel',
'Foreign key has been dropped.' => 'Fremmednøkkelen er slettet.', 'Foreign key has been dropped.' => 'Fremmednøkkelen er slettet.',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Rodzaj bazy', 'System' => 'Rodzaj bazy',
@@ -81,7 +83,6 @@ $translations = array(
'Data' => 'Dane', 'Data' => 'Dane',
'Database' => 'Baza danych', 'Database' => 'Baza danych',
'database' => 'baza danych',
'Use' => 'Wybierz', 'Use' => 'Wybierz',
'Select database' => 'Wybierz bazę danych', 'Select database' => 'Wybierz bazę danych',
'Invalid database.' => 'Nie znaleziono bazy danych.', 'Invalid database.' => 'Nie znaleziono bazy danych.',
@@ -197,7 +198,7 @@ $translations = array(
'Alter indexes' => 'Zmień indeksy', 'Alter indexes' => 'Zmień indeksy',
'Add next' => 'Dodaj następny', 'Add next' => 'Dodaj następny',
'Index Type' => 'Typ indeksu', 'Index Type' => 'Typ indeksu',
'Column (length)' => 'Kolumna (długość)', 'length' => 'długość',
'Foreign keys' => 'Klucze obce', 'Foreign keys' => 'Klucze obce',
'Foreign key' => 'Klucz obcy', 'Foreign key' => 'Klucz obcy',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Entrar', 'Login' => 'Entrar',
'Logout successful.' => 'Saída bem sucedida.', 'Logout successful.' => 'Saída bem sucedida.',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'Criar Base de dados', 'Create database' => 'Criar Base de dados',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Sair', 'Logout' => 'Sair',
'database' => 'base de dados',
'Use' => 'Usar', 'Use' => 'Usar',
'No tables.' => 'Não existem tabelas.', 'No tables.' => 'Não existem tabelas.',
'select' => 'selecionar', 'select' => 'selecionar',
@@ -47,7 +48,7 @@ $translations = array(
'Indexes have been altered.' => 'Os Índices foram alterados.', 'Indexes have been altered.' => 'Os Índices foram alterados.',
'Indexes' => 'Índices', 'Indexes' => 'Índices',
'Alter indexes' => 'Alterar índices', 'Alter indexes' => 'Alterar índices',
'Add next' => 'Adicionar proximo', 'Add next' => 'Adicionar próximo',
'Language' => 'Idioma', 'Language' => 'Idioma',
'Select' => 'Selecionar', 'Select' => 'Selecionar',
'New item' => 'Novo Registro', 'New item' => 'Novo Registro',
@@ -66,19 +67,19 @@ $translations = array(
'Foreign keys' => 'Chaves estrangeiras', 'Foreign keys' => 'Chaves estrangeiras',
'Triggers' => 'Triggers', 'Triggers' => 'Triggers',
'View' => 'Visão', 'View' => 'Visão',
'Unable to select the table' => 'Não é possivel selecionar a Tabela', 'Unable to select the table' => 'Não é possível selecionar a Tabela',
'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Enviar o formulario novamente.', 'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Enviar o formulário novamente.',
'Comment' => 'Comentário', 'Comment' => 'Comentário',
'Default values' => 'Valores padrões', 'Default values' => 'Valores padrões',
'%d byte(s)' => array('%d byte', '%d bytes'), '%d byte(s)' => array('%d byte', '%d bytes'),
'No commands to execute.' => 'Nenhum comando para executar.', 'No commands to execute.' => 'Nenhum comando para executar.',
'Unable to upload a file.' => 'Não é possível enviar o arquivo.', 'Unable to upload a file.' => 'Não é possível enviar o arquivo.',
'File upload' => 'Importar arquivo', 'File upload' => 'Importar arquivo',
'File uploads are disabled.' => 'Importação de arquivos desablilitada.', 'File uploads are disabled.' => 'Importação de arquivos desabilitada.',
'Routine has been called, %d row(s) affected.' => array('Rotina executada, %d registro afetado.', 'Rotina executada, %d registros afetados.'), 'Routine has been called, %d row(s) affected.' => array('Rotina executada, %d registro afetado.', 'Rotina executada, %d registros afetados.'),
'Call' => 'Chamar', 'Call' => 'Chamar',
'No extension' => 'Não há extension', 'No extension' => 'Não há extension',
'None of the supported PHP extensions (%s) are available.' => 'Nenhuma das extensões PHP suportadas (%s) está disponivel.', 'None of the supported PHP extensions (%s) are available.' => 'Nenhuma das extensões PHP suportadas (%s) está disponível.',
'Session support must be enabled.' => 'Suporte a sessões deve estar habilitado.', 'Session support must be enabled.' => 'Suporte a sessões deve estar habilitado.',
'Session expired, please login again.' => 'Sessão expirada, por favor logue-se novamente.', 'Session expired, please login again.' => 'Sessão expirada, por favor logue-se novamente.',
'Text length' => 'Tamanho de texto', 'Text length' => 'Tamanho de texto',
@@ -96,7 +97,7 @@ $translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Tipo de índice', 'Index Type' => 'Tipo de índice',
'Column (length)' => 'Coluna (tamanho)', 'length' => 'tamanho',
'View has been dropped.' => 'A Visão foi apagada.', 'View has been dropped.' => 'A Visão foi apagada.',
'View has been altered.' => 'A Visão foi alterada.', 'View has been altered.' => 'A Visão foi alterada.',
'View has been created.' => 'A Visão foi criada.', 'View has been created.' => 'A Visão foi criada.',
@@ -169,7 +170,7 @@ $translations = array(
'Index Length' => 'Tamanho de índice', 'Index Length' => 'Tamanho de índice',
'Data Free' => 'Espaço Livre', 'Data Free' => 'Espaço Livre',
'Collation' => 'Colação', 'Collation' => 'Colação',
'Analyze' => 'Analizar', 'Analyze' => 'Analisar',
'Optimize' => 'Otimizar', 'Optimize' => 'Otimizar',
'Check' => 'Verificar', 'Check' => 'Verificar',
'Repair' => 'Reparar', 'Repair' => 'Reparar',
@@ -209,7 +210,7 @@ $translations = array(
'Maximum allowed file size is %sB.' => 'Tamanho máximo do arquivo permitido é %sB.', 'Maximum allowed file size is %sB.' => 'Tamanho máximo do arquivo permitido é %sB.',
'Numbers' => 'Números', 'Numbers' => 'Números',
'Date and time' => 'Data e hora', 'Date and time' => 'Data e hora',
'Strings' => 'Cadena', 'Strings' => 'Strings',
'Binary' => 'Binário', 'Binary' => 'Binário',
'Lists' => 'Listas', 'Lists' => 'Listas',
'Editor' => 'Editor', 'Editor' => 'Editor',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Entrar', 'Login' => 'Entrar',
'Logout successful.' => 'Sessão terminada com sucesso.', 'Logout successful.' => 'Sessão terminada com sucesso.',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'Criar Base de dados', 'Create database' => 'Criar Base de dados',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Terminar sessão', 'Logout' => 'Terminar sessão',
'database' => 'base de dados',
'Use' => 'Usar', 'Use' => 'Usar',
'No tables.' => 'Não existem tabelas.', 'No tables.' => 'Não existem tabelas.',
'select' => 'registos', 'select' => 'registos',
@@ -96,7 +97,7 @@ $translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'Tipo de índice', 'Index Type' => 'Tipo de índice',
'Column (length)' => 'coluna (tamanho)', 'length' => 'tamanho',
'View has been dropped.' => 'Vista eliminada.', 'View has been dropped.' => 'Vista eliminada.',
'View has been altered.' => 'Vista modificada.', 'View has been altered.' => 'Vista modificada.',
'View has been created.' => 'Vista criada.', 'View has been created.' => 'Vista criada.',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Intră', 'Login' => 'Intră',
'Logout successful.' => 'Ați ieșit cu succes.', 'Logout successful.' => 'Ați ieșit cu succes.',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'Crează baza de date', 'Create database' => 'Crează baza de date',
'SQL command' => 'SQL query', 'SQL command' => 'SQL query',
'Logout' => 'Ieșire', 'Logout' => 'Ieșire',
'database' => 'baza de date',
'Use' => 'Alege', 'Use' => 'Alege',
'No tables.' => 'În baza de date nu sunt tabele.', 'No tables.' => 'În baza de date nu sunt tabele.',
'select' => 'selectează', 'select' => 'selectează',
@@ -96,7 +97,7 @@ $translations = array(
'ON DELETE' => 'La ștergere', 'ON DELETE' => 'La ștergere',
'ON UPDATE' => 'La modificare', 'ON UPDATE' => 'La modificare',
'Index Type' => 'Tipul indexului', 'Index Type' => 'Tipul indexului',
'Column (length)' => 'Coloană (lungimea)', 'length' => 'lungimea',
'View has been dropped.' => 'Reprezentarea a fost ștearsă.', 'View has been dropped.' => 'Reprezentarea a fost ștearsă.',
'View has been altered.' => 'Reprezentarea a fost modificată.', 'View has been altered.' => 'Reprezentarea a fost modificată.',
'View has been created.' => 'Reprezentarea a fost creată.', 'View has been created.' => 'Reprezentarea a fost creată.',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Войти', 'Login' => 'Войти',
'Logout successful.' => 'Вы успешно покинули систему.', 'Logout successful.' => 'Вы успешно покинули систему.',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'Создать базу данных', 'Create database' => 'Создать базу данных',
'SQL command' => 'SQL-запрос', 'SQL command' => 'SQL-запрос',
'Logout' => 'Выйти', 'Logout' => 'Выйти',
'database' => 'база данных',
'Use' => 'Выбрать', 'Use' => 'Выбрать',
'No tables.' => 'В базе данных нет таблиц.', 'No tables.' => 'В базе данных нет таблиц.',
'select' => 'выбрать', 'select' => 'выбрать',
@@ -96,7 +97,7 @@ $translations = array(
'ON DELETE' => 'При стирании', 'ON DELETE' => 'При стирании',
'ON UPDATE' => 'При обновлении', 'ON UPDATE' => 'При обновлении',
'Index Type' => 'Тип индекса', 'Index Type' => 'Тип индекса',
'Column (length)' => 'Поле (длина)', 'length' => 'длина',
'View has been dropped.' => 'Представление было удалено.', 'View has been dropped.' => 'Представление было удалено.',
'View has been altered.' => 'Представление было изменено.', 'View has been altered.' => 'Представление было изменено.',
'View has been created.' => 'Представление было создано.', 'View has been created.' => 'Представление было создано.',
@@ -289,4 +290,16 @@ $translations = array(
'Saving' => 'Сохранение', 'Saving' => 'Сохранение',
'yes' => 'Да', 'yes' => 'Да',
'no' => 'Нет', 'no' => 'Нет',
'Drop %s?' => 'Удалить %s?',
'overwrite' => 'перезаписать',
'DB' => 'DB',
'Warnings' => 'Предупреждения',
'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>.',
'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>.',
'The action will be performed after successful login with the same credentials.' => 'Действие будет выполнено после успешного входа в систему с теми же учетными данными.',
'Connecting to privileged ports is not allowed.' => 'Подключение к привилегированным портам не допускается.',
'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.',
); );

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'Prihlásiť sa', 'Login' => 'Prihlásiť sa',
'Logout successful.' => 'Odhlásenie prebehlo v poriadku.', 'Logout successful.' => 'Odhlásenie prebehlo v poriadku.',
@@ -32,7 +34,6 @@ $translations = array(
'Create database' => 'Vytvoriť databázu', 'Create database' => 'Vytvoriť databázu',
'SQL command' => 'SQL príkaz', 'SQL command' => 'SQL príkaz',
'Logout' => 'Odhlásiť', 'Logout' => 'Odhlásiť',
'database' => 'databáza',
'Use' => 'Vybrať', 'Use' => 'Vybrať',
'No tables.' => 'Žiadne tabuľky.', 'No tables.' => 'Žiadne tabuľky.',
'select' => 'vypísať', 'select' => 'vypísať',
@@ -70,7 +71,7 @@ $translations = array(
'Unable to select the table' => 'Tabuľku sa nepodarilo vypísať', 'Unable to select the table' => 'Tabuľku sa nepodarilo vypísať',
'Invalid CSRF token. Send the form again.' => 'Neplatný token CSRF. Odošlite formulár znova.', 'Invalid CSRF token. Send the form again.' => 'Neplatný token CSRF. Odošlite formulár znova.',
'Comment' => 'Komentár', 'Comment' => 'Komentár',
'Default values' => 'Východzie hodnoty', 'Default values' => 'Predvolené hodnoty',
'%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtov'), '%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtov'),
'No commands to execute.' => 'Žiadne príkazy na vykonanie.', 'No commands to execute.' => 'Žiadne príkazy na vykonanie.',
'Unable to upload a file.' => 'Súbor sa nepodarilo nahrať.', 'Unable to upload a file.' => 'Súbor sa nepodarilo nahrať.',
@@ -94,10 +95,10 @@ $translations = array(
'Add column' => 'Pridať stĺpec', 'Add column' => 'Pridať stĺpec',
'Alter' => 'Zmeniť', 'Alter' => 'Zmeniť',
'Add foreign key' => 'Pridať cudzí kľúč', 'Add foreign key' => 'Pridať cudzí kľúč',
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'Pri zmazaní',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'Pri aktualizácii',
'Index Type' => 'Typ indexu', 'Index Type' => 'Typ indexu',
'Column (length)' => 'Stĺpec (dĺžka)', 'length' => 'dĺžka',
'View has been dropped.' => 'Pohľad bol odstránený.', 'View has been dropped.' => 'Pohľad bol odstránený.',
'View has been altered.' => 'Pohľad bol zmenený.', 'View has been altered.' => 'Pohľad bol zmenený.',
'View has been created.' => 'Pohľad bol vytvorený.', 'View has been created.' => 'Pohľad bol vytvorený.',
@@ -265,4 +266,40 @@ $translations = array(
'Permanent link' => 'Permanentný odkaz', 'Permanent link' => 'Permanentný odkaz',
'Edit all' => 'Upraviť všetko', 'Edit all' => 'Upraviť všetko',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
'Drop %s?' => 'Odstrániť %s?',
'Tables have been optimized.' => 'Tabuľky boli optimalizované.',
'Materialized view' => 'Materializovaný pohľad',
'Vacuum' => 'Vyčistiť',
'Selected' => 'Označené',
'overwrite' => 'prepísať',
'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',
'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/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/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.',
'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ť',
'Compute' => 'Spočítať',
'You are offline.' => 'Ste offline.',
'You have no privileges to update this table.' => 'Nemáte oprávnenie na aktualizáciu tejto tabuľky.',
'Saving' => 'Ukladá sa',
'Unknown error.' => 'Neznáma chyba.',
'Database does not support password.' => 'Databáza nepodporuje heslo.',
'Disable %s or enable %s or %s extensions.' => 'Zakážte %s alebo povoľte rozšírenie %s alebo %s.',
'yes' => 'áno',
'no' => 'nie',
); );

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem', 'System' => 'Sistem',
@@ -72,7 +74,6 @@ $translations = array(
'Data' => 'Podatki', 'Data' => 'Podatki',
'Database' => 'Baza', 'Database' => 'Baza',
'database' => 'baza',
'Use' => 'Uporabi', 'Use' => 'Uporabi',
'Select database' => 'Izberi bazo', 'Select database' => 'Izberi bazo',
'Invalid database.' => 'Neveljavna baza.', 'Invalid database.' => 'Neveljavna baza.',
@@ -178,7 +179,7 @@ $translations = array(
'Alter indexes' => 'Spremeni indekse', 'Alter indexes' => 'Spremeni indekse',
'Add next' => 'Dodaj naslednjega', 'Add next' => 'Dodaj naslednjega',
'Index Type' => 'Tip indeksa', 'Index Type' => 'Tip indeksa',
'Column (length)' => 'Stolpec (dolžina)', 'length' => 'dolžina',
'Foreign keys' => 'Tuji ključi', 'Foreign keys' => 'Tuji ključi',
'Foreign key' => 'Tuj ključ', 'Foreign key' => 'Tuj ključ',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Систем', 'System' => 'Систем',
@@ -73,7 +75,6 @@ $translations = array(
'Data' => 'Податци', 'Data' => 'Податци',
'Database' => 'База података', 'Database' => 'База података',
'database' => 'база података',
'Use' => 'Користи', 'Use' => 'Користи',
'Select database' => 'Изаберите базу', 'Select database' => 'Изаберите базу',
'Invalid database.' => 'Неисправна база података.', 'Invalid database.' => 'Неисправна база података.',
@@ -183,7 +184,7 @@ $translations = array(
'Alter indexes' => 'Уреди индексе', 'Alter indexes' => 'Уреди индексе',
'Add next' => 'Додај следећи', 'Add next' => 'Додај следећи',
'Index Type' => 'Тип индекса', 'Index Type' => 'Тип индекса',
'Column (length)' => 'Колона (дужина)', 'length' => 'дужина',
'Foreign keys' => 'Страни кључеви', 'Foreign keys' => 'Страни кључеви',
'Foreign key' => 'Страни кључ', 'Foreign key' => 'Страни кључ',

350
adminer/lang/sv.inc.php Normal file
View File

@@ -0,0 +1,350 @@
<?php
namespace Adminer;
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'System',
'Server' => 'Server',
'Username' => 'Användarnamn',
'Password' => 'Lösenord',
'Permanent login' => 'Permanent inloggning',
'Login' => 'Logga in',
'Logout' => 'Logga ut',
'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.',
'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.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('För många misslyckade inloggningar, försök igen om %d minut.', 'För många misslyckade inloggningar, försök igen om %d minuter.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Huvudlösenordet har löpt ut. <a href="https://www.adminer.org/en/extension/"%s>Implementera</a> %s en metod för att göra det permanent.',
'Language' => 'Språk',
'Invalid CSRF token. Send the form again.' => 'Ogiltig CSRF-token. Skicka formuläret igen.',
'If you did not send this request from Adminer then close this page.' => 'Om du inte skickade en förfrågan från Adminer så kan du stänga den här sidan.',
'No extension' => 'Inget tillägg',
'None of the supported PHP extensions (%s) are available.' => 'Inga av de PHP-tilläggen som stöds (%s) är tillgängliga.',
'Connecting to privileged ports is not allowed.' => 'Anslutning till privilegierade portar är inte tillåtet.',
'Disable %s or enable %s or %s extensions.' => 'Stäng av %s eller sätt på %s eller %s tilläggen.',
'Session support must be enabled.' => 'Support för sessioner måste vara på.',
'Session expired, please login again.' => 'Session har löpt ut, vänligen logga in igen.',
'The action will be performed after successful login with the same credentials.' => 'Åtgärden kommer att utföras efter en lyckad inloggning med samma inloggningsuppgifter.',
'%s version: %s through PHP extension %s' => '%s version: %s genom PHP-tillägg %s',
'Refresh' => 'Ladda om',
// text direction - 'ltr' or 'rtl'
'ltr' => 'ltr',
'Privileges' => 'Privilegier',
'Create user' => 'Skapa användare',
'User has been dropped.' => 'Användare har blivit borttagen.',
'User has been altered.' => 'Användare har blivit ändrad.',
'User has been created.' => 'Användare har blivit skapad.',
'Hashed' => 'Hashad',
'Column' => 'Kolumn',
'Routine' => 'Rutin',
'Grant' => 'Tillåt',
'Revoke' => 'Neka',
'Process list' => 'Processlista',
'%d process(es) have been killed.' => array('%d process har avslutats.', '%d processer har avslutats.'),
'Kill' => 'Avsluta',
'Variables' => 'Variabler',
'Status' => 'Status',
'SQL command' => 'SQL-kommando',
'%d query(s) executed OK.' => array('%d förfrågan lyckades.', '%d förfrågor lyckades.'),
'Query executed OK, %d row(s) affected.' => array('Förfrågan lyckades, %d rad påverkades.', 'Förfrågan lyckades, %d rader påverkades.'),
'No commands to execute.' => 'Inga kommandon att köra.',
'Error in query' => 'Fel i förfrågan',
'Unknown error.' => 'Okänt fel.',
'Warnings' => 'Varningar',
'ATTACH queries are not supported.' => 'ATTACH-förfrågor stöds inte.',
'Execute' => 'Kör',
'Stop on error' => 'Stanna på fel',
'Show only errors' => 'Visa bara fel',
// sprintf() format for time of the command
'%.3f s' => '%.3f s',
'History' => 'Historia',
'Clear' => 'Rensa',
'Edit all' => 'Redigera alla',
'File upload' => 'Ladda upp fil',
'From server' => 'Från server',
'Webserver file %s' => 'Serverfil %s',
'Run file' => 'Kör fil',
'File does not exist.' => 'Filen finns inte.',
'File uploads are disabled.' => 'Filuppladdningar är avstängda.',
'Unable to upload a file.' => 'Det går inte add ladda upp filen.',
'Maximum allowed file size is %sB.' => 'Högsta tillåtna storlek är %sB.',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'POST-datan är för stor. Minska det eller höj %s-direktivet.',
'You can upload a big SQL file via FTP and import it from server.' => 'Du kan ladda upp en stor SQL-fil via FTP och importera det från servern.',
'You are offline.' => 'Du är offline.',
'Export' => 'Exportera',
'Output' => 'Utmatning',
'open' => 'Öppna',
'save' => 'Spara',
'Saving' => 'Sparar',
'Format' => 'Format',
'Data' => 'Data',
'Database' => 'Databas',
'DB' => 'DB',
'Use' => 'Använd',
'Select database' => 'Välj databas',
'Invalid database.' => 'Ogiltig databas.',
'Database has been dropped.' => 'Databasen har tagits bort.',
'Databases have been dropped.' => 'Databaserna har tagits bort.',
'Database has been created.' => 'Databasen har skapats.',
'Database has been renamed.' => 'Databasen har fått sitt namn ändrat.',
'Database has been altered.' => 'Databasen har ändrats.',
'Alter database' => 'Ändra databas',
'Create database' => 'Skapa databas',
'Database schema' => 'Databasschema',
// link to current database schema layout
'Permanent link' => 'Permanent länk',
// thousands separator - must contain single byte
',' => ',',
'0123456789' => '0123456789',
'Engine' => 'Motor',
'Collation' => 'Kollationering',
'Data Length' => 'Datalängd',
'Index Length' => 'Indexlängd',
'Data Free' => 'Ledig data',
'Rows' => 'Rader',
'%d in total' => 'totalt %d',
'Analyze' => 'Analysera',
'Optimize' => 'Optimera',
'Vacuum' => 'Städa',
'Check' => 'Kolla',
'Repair' => 'Reparera',
'Truncate' => 'Avkorta',
'Tables have been truncated.' => 'Tabeller har blivit avkortade.',
'Move to other database' => 'Flytta till en annan databas',
'Move' => 'Flytta',
'Tables have been moved.' => 'Tabeller har flyttats.',
'Copy' => 'Kopiera',
'Tables have been copied.' => 'Tabeller har kopierats.',
'overwrite' => 'Skriv över',
'Routines' => 'Rutiner',
'Routine has been called, %d row(s) affected.' => array('Rutin har kallats, %d rad påverkades.', 'Rutin har kallats, %d rader påverkades.'),
'Call' => 'Kalla',
'Parameter name' => 'Namn på parameter',
'Create procedure' => 'Skapa procedur',
'Create function' => 'Skapa funktion',
'Routine has been dropped.' => 'Rutin har tagits bort.',
'Routine has been altered.' => 'Rutin har ändrats.',
'Routine has been created.' => 'Rutin har skapats.',
'Alter function' => 'Ändra funktion',
'Alter procedure' => 'Ändra procedur',
'Return type' => 'Återvändningstyp',
'Events' => 'Event',
'Event has been dropped.' => 'Event har tagits bort.',
'Event has been altered.' => 'Event har ändrats.',
'Event has been created.' => 'Event har skapats.',
'Alter event' => 'Ändra event',
'Create event' => 'Skapa event',
'At given time' => 'Vid en tid',
'Every' => 'Varje',
'Schedule' => 'Schemalägga',
'Start' => 'Start',
'End' => 'Slut',
'On completion preserve' => 'Bibehåll vid slutet',
'Tables' => 'Tabeller',
'Tables and views' => 'Tabeller och vyer',
'Table' => 'Tabell',
'No tables.' => 'Inga tabeller.',
'Alter table' => 'Ändra tabell',
'Create table' => 'Skapa tabell',
'Table has been dropped.' => 'Tabell har tagits bort.',
'Tables have been dropped.' => 'Tabeller har tagits bort.',
'Tables have been optimized.' => 'Tabeller har optimerats.',
'Table has been altered.' => 'Tabell har ändrats.',
'Table has been created.' => 'Tabell har skapats.',
'Table name' => 'Tabellnamn',
'Show structure' => 'Visa struktur',
'engine' => 'motor',
'collation' => 'kollationering',
'Column name' => 'Kolumnnamn',
'Type' => 'Typ',
'Length' => 'Längd',
'Auto Increment' => 'Automatisk uppräkning',
'Options' => 'Inställningar',
'Comment' => 'Kommentar',
'Default value' => 'Standardvärde',
'Default values' => 'Standardvärden',
'Drop' => 'Ta bort',
'Drop %s?' => 'Ta bort %s?',
'Are you sure?' => 'Är du säker?',
'Size' => 'Storlek',
'Compute' => 'Beräkna',
'Move up' => 'Flytta upp',
'Move down' => 'Flytta ner',
'Remove' => 'Ta bort',
'Maximum number of allowed fields exceeded. Please increase %s.' => 'Högsta nummer tillåtna fält är överskridet. Vänligen höj %s.',
'Partition by' => 'Partitionera om',
'Partitions' => 'Partitioner',
'Partition name' => 'Partition',
'Values' => 'Värden',
'View' => 'Vy',
'Materialized view' => 'Materialiserad vy',
'View has been dropped.' => 'Vy har tagits bort.',
'View has been altered.' => 'Vy har ändrats.',
'View has been created.' => 'Vy har skapats.',
'Alter view' => 'Ändra vy',
'Create view' => 'Skapa vy',
'Indexes' => 'Index',
'Indexes have been altered.' => 'Index har ändrats.',
'Alter indexes' => 'Ändra index',
'Add next' => 'Lägg till nästa',
'Index Type' => 'Indextyp',
'length' => 'längd',
'Foreign keys' => 'Främmande nycklar',
'Foreign key' => 'Främmande nyckel',
'Foreign key has been dropped.' => 'Främmande nyckel har tagits bort.',
'Foreign key has been altered.' => 'Främmande nyckel har ändrats.',
'Foreign key has been created.' => 'Främmande nyckel har skapats.',
'Target table' => 'Måltabell',
'Change' => 'Ändra',
'Source' => 'Källa',
'Target' => 'Mål',
'Add column' => 'Lägg till kolumn',
'Alter' => 'Ändra',
'Add foreign key' => 'Lägg till främmande nyckel',
'ON DELETE' => 'VID BORTTAGNING',
'ON UPDATE' => 'VID UPPDATERING',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'Käll- och mål-tabellen måste ha samma datatyp, ett index på målkolumnerna och refererad data måste finnas.',
'Triggers' => 'Avtryckare',
'Add trigger' => 'Lägg till avtryckare',
'Trigger has been dropped.' => 'Avtryckare har tagits bort.',
'Trigger has been altered.' => 'Avtryckare har ändrats.',
'Trigger has been created.' => 'Avtryckare har skapats.',
'Alter trigger' => 'Ändra avtryckare',
'Create trigger' => 'Skapa avtryckare',
'Time' => 'Tid',
'Event' => 'Event',
'Name' => 'Namn',
'select' => 'välj',
'Select' => 'Välj',
'Select data' => 'Välj data',
'Functions' => 'Funktioner',
'Aggregation' => 'Aggregation',
'Search' => 'Sök',
'anywhere' => 'överallt',
'Search data in tables' => 'Sök data i tabeller',
'Sort' => 'Sortera',
'descending' => 'Fallande',
'Limit' => 'Begränsning',
'Limit rows' => 'Begränsa rader',
'Text length' => 'Textlängd',
'Action' => 'Åtgärd',
'Full table scan' => 'Full tabellskanning',
'Unable to select the table' => 'Kunde inte välja tabellen',
'No rows.' => 'Inga rader.',
'%d / ' => '%d / ',
'%d row(s)' => array('%d rad', '%d rader'),
'Page' => 'Sida',
'last' => 'sist',
'Load more data' => 'Ladda mer data',
'Loading' => 'Laddar',
'Whole result' => 'Hela resultatet',
'%d byte(s)' => array('%d byte', '%d bytes'),
'Import' => 'Importera',
'%d row(s) have been imported.' => array('%d rad har importerats.', '%d rader har importerats.'),
'File must be in UTF-8 encoding.' => 'Filer måste vara i UTF-8-format.',
// in-place editing in select
'Modify' => 'Ändra',
'Ctrl+click on a value to modify it.' => 'Ctrl+klicka på ett värde för att ändra det.',
'Use edit link to modify this value.' => 'Använd redigeringslänken för att ändra värdet.',
// %s can contain auto-increment value
'Item%s has been inserted.' => 'Sak%s har skapats.',
'Item has been deleted.' => 'En sak har tagits bort.',
'Item has been updated.' => 'En sak har ändrats.',
'%d item(s) have been affected.' => array('%d sak har blivit förändrad.', '%d saker har blivit förändrade.'),
'New item' => 'Ny sak',
'original' => 'original',
// label for value '' in enum data type
'empty' => 'tom',
'edit' => 'redigera',
'Edit' => 'Redigera',
'Insert' => 'Infoga',
'Save' => 'Spara',
'Save and continue edit' => 'Spara och fortsätt att redigera',
'Save and insert next' => 'Spara och infoga nästa',
'Selected' => 'Vald',
'Clone' => 'Klona',
'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',
'Strings' => 'Strängar',
'Binary' => 'Binärt',
'Lists' => 'Listor',
'Network' => 'Nätverk',
'Geometry' => 'Geometri',
'Relations' => 'Relationer',
'Editor' => 'Redigerare',
// date format in Editor: $1 yyyy, $2 yy, $3 mm, $4 m, $5 dd, $6 d
'$1-$3-$5' => '$1-$3-$5',
// hint for date format - use language equivalents for day, month and year shortcuts
'[yyyy]-mm-dd' => 'yyyy-mm-dd',
// hint for time format - use language equivalents for hour, minute and second shortcuts
'HH:MM:SS' => 'HH:MM:SS',
'now' => 'nu',
'yes' => 'ja',
'no' => 'nej',
// general SQLite error in create, drop or rename database
'File exists.' => 'Filen finns redan.',
'Please use one of the extensions %s.' => 'Vänligen använd en av filändelserna %s.',
// PostgreSQL and MS SQL schema support
'Alter schema' => 'Redigera schema',
'Create schema' => 'Skapa schema',
'Schema has been dropped.' => 'Schema har tagits bort.',
'Schema has been created.' => 'Schema har skapats.',
'Schema has been altered.' => 'Schema har ändrats.',
'Schema' => 'Schema',
'Invalid schema.' => 'Ogiltigt schema.',
// PostgreSQL sequences support
'Sequences' => 'Sekvenser',
'Create sequence' => 'Skapa sekvens',
'Sequence has been dropped.' => 'Sekvens har tagits bort.',
'Sequence has been created.' => 'Sekvens har skapats.',
'Sequence has been altered.' => 'Sekvens har ändrats.',
'Alter sequence' => 'Ändra sekvens',
// PostgreSQL user types support
'User types' => 'Användartyper',
'Create type' => 'Skapa typ',
'Type has been dropped.' => 'Typ har, typ, tagits bort.',
'Type has been created.' => 'Typ har skapats.',
'Alter type' => 'Ändra typ',
);

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'நுழை', 'Login' => 'நுழை',
'Logout successful.' => 'வெற்றிக‌ர‌மாய் வெளியேறியாயிற்று.', 'Logout successful.' => 'வெற்றிக‌ர‌மாய் வெளியேறியாயிற்று.',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'த‌க‌வ‌ல்த‌ள‌த்தை உருவாக்கு', 'Create database' => 'த‌க‌வ‌ல்த‌ள‌த்தை உருவாக்கு',
'SQL command' => 'SQL க‌ட்ட‌ளை', 'SQL command' => 'SQL க‌ட்ட‌ளை',
'Logout' => 'வெளியேறு', 'Logout' => 'வெளியேறு',
'database' => 'த‌க‌வ‌ல்த‌ள‌ம்',
'Use' => 'உப‌யோகி', 'Use' => 'உப‌யோகி',
'No tables.' => 'அட்ட‌வ‌ணை இல்லை.', 'No tables.' => 'அட்ட‌வ‌ணை இல்லை.',
'select' => 'தேர்வு செய்', 'select' => 'தேர்வு செய்',
@@ -94,7 +95,7 @@ $translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'அக‌வ‌ரிசை வ‌கை (Index Type)', 'Index Type' => 'அக‌வ‌ரிசை வ‌கை (Index Type)',
'Column (length)' => 'நெடுவ‌ரிசை (நீள‌ம்)', 'length' => 'நீள‌ம்',
'View has been dropped.' => 'தோற்ற‌ம் நீக்க‌ப்ப‌ட்ட‌து.', 'View has been dropped.' => 'தோற்ற‌ம் நீக்க‌ப்ப‌ட்ட‌து.',
'View has been altered.' => 'தோற்றம் மாற்றப்ப‌ட்ட‌து.', 'View has been altered.' => 'தோற்றம் மாற்றப்ப‌ட்ட‌து.',
'View has been created.' => 'தோற்ற‌ம் உருவாக்க‌ப்ப‌ட்ட‌து.', 'View has been created.' => 'தோற்ற‌ம் உருவாக்க‌ப்ப‌ட்ட‌து.',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
'Login' => 'เข้าสู่ระบบ', 'Login' => 'เข้าสู่ระบบ',
'Logout successful.' => 'ออกจากระบบเรียบร้อยแล้ว.', 'Logout successful.' => 'ออกจากระบบเรียบร้อยแล้ว.',
@@ -31,7 +33,6 @@ $translations = array(
'Create database' => 'สร้างฐานข้อมูล', 'Create database' => 'สร้างฐานข้อมูล',
'SQL command' => 'คำสั่ง SQL', 'SQL command' => 'คำสั่ง SQL',
'Logout' => 'ออกจากระบบ', 'Logout' => 'ออกจากระบบ',
'database' => 'ฐานข้อมูล',
'Use' => 'ใช้งาน', 'Use' => 'ใช้งาน',
'No tables.' => 'ไม่พบตาราง.', 'No tables.' => 'ไม่พบตาราง.',
'select' => 'เลือก', 'select' => 'เลือก',
@@ -96,7 +97,7 @@ $translations = array(
'ON DELETE' => 'ON DELETE', 'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE', 'ON UPDATE' => 'ON UPDATE',
'Index Type' => 'ชนิดของดัชนี', 'Index Type' => 'ชนิดของดัชนี',
'Column (length)' => 'คอลัมน์ (ความยาว)', 'length' => 'ความยาว',
'View has been dropped.' => 'วิวถูกลบแล้ว.', 'View has been dropped.' => 'วิวถูกลบแล้ว.',
'View has been altered.' => 'วิวถูกเปลี่ยนแปลงแล้ว.', 'View has been altered.' => 'วิวถูกเปลี่ยนแปลงแล้ว.',
'View has been created.' => 'วิวถูกสร้างแล้ว.', 'View has been created.' => 'วิวถูกสร้างแล้ว.',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem', 'System' => 'Sistem',
@@ -84,7 +86,6 @@ $translations = array(
'Data' => 'Veri', 'Data' => 'Veri',
'Database' => 'Veri Tabanı', 'Database' => 'Veri Tabanı',
'database' => 'veri tabanı',
'DB' => 'DB', 'DB' => 'DB',
'Use' => 'Kullan', 'Use' => 'Kullan',
'Select database' => 'Veri tabanı seç', 'Select database' => 'Veri tabanı seç',
@@ -201,7 +202,7 @@ $translations = array(
'Alter indexes' => 'İndeksleri değiştir', 'Alter indexes' => 'İndeksleri değiştir',
'Add next' => 'Bundan sonra ekle', 'Add next' => 'Bundan sonra ekle',
'Index Type' => 'İndex Türü', 'Index Type' => 'İndex Türü',
'Column (length)' => 'Kolon (uzunluğu)', 'length' => 'uzunluğu',
'Foreign keys' => 'Dış anahtarlar', 'Foreign keys' => 'Dış anahtarlar',
'Foreign key' => 'Dış anahtar', 'Foreign key' => 'Dış anahtar',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Система Бази Даних', 'System' => 'Система Бази Даних',
@@ -73,7 +75,6 @@ $translations = array(
'Data' => 'Дані', 'Data' => 'Дані',
'Database' => 'База даних', 'Database' => 'База даних',
'database' => 'база даних',
'Use' => 'Обрати', 'Use' => 'Обрати',
'Select database' => 'Обрати базу даних', 'Select database' => 'Обрати базу даних',
'Invalid database.' => 'Погана база даних.', 'Invalid database.' => 'Погана база даних.',
@@ -183,7 +184,7 @@ $translations = array(
'Alter indexes' => 'Змінити індексування', 'Alter indexes' => 'Змінити індексування',
'Add next' => 'Додати ще', 'Add next' => 'Додати ще',
'Index Type' => 'Тип індексу', 'Index Type' => 'Тип індексу',
'Column (length)' => 'Стовпець (довжина)', 'length' => 'довжина',
'Foreign keys' => 'Зовнішні ключі', 'Foreign keys' => 'Зовнішні ключі',
'Foreign key' => 'Зовнішній ключ', 'Foreign key' => 'Зовнішній ключ',
@@ -313,4 +314,34 @@ $translations = array(
'Type has been dropped.' => 'Тип було видалено.', 'Type has been dropped.' => 'Тип було видалено.',
'Type has been created.' => 'Тип було створено.', 'Type has been created.' => 'Тип було створено.',
'Alter type' => 'Змінити тип', 'Alter type' => 'Змінити тип',
'Drop %s?' => 'Вилучити %s?',
'Materialized view' => 'Матеріалізований вигляд',
'Selected' => 'Вибрані',
'overwrite' => 'перезаписати',
'DB' => 'DB',
'File must be in UTF-8 encoding.' => 'Файл повинен бути в кодуванні UTF-8.',
'Modify' => 'Змінити',
'Load more data' => 'Завантажити ще дані',
'Loading' => 'Завантаження',
'ATTACH queries are not supported.' => 'ATTACH-запити не підтримуються.',
'Warnings' => 'Попередження',
'Limit rows' => 'Обмеження рядків',
'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>.',
'Default value' => 'Значення за замовчуванням',
'Full table scan' => 'Повне сканування таблиці',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Занадто багато невдалих спроб входу. Спробуйте знову через %d хвилину.', 'Занадто багато невдалих спроб входу. Спробуйте знову через %d хвилини.', 'Занадто багато невдалих спроб входу. Спробуйте знову через %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>.',
'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, щоб зробити його постійним.',
'The action will be performed after successful login with the same credentials.' => 'Дія буде виконуватися після успішного входу в систему з тими ж обліковими даними.',
'Connecting to privileged ports is not allowed.' => 'Підключення до привілейованих портів заборонено.',
'There is a space in the input password which might be the cause.' => 'У вхідному паролі є пробіл, який може бути причиною.',
'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.' => 'Ви можете завантажити великий файл SQL через FTP та імпортувати його з сервера.',
'Size' => 'Розмір',
'Compute' => 'Обчислити',
'You are offline.' => 'Ви офлайн.',
'You have no privileges to update this table.' => 'Ви не маєте привілеїв для оновлення цієї таблиці.',
'Saving' => 'Збереження',
'Unknown error.' => 'Невідома помилка.',
'Database does not support password.' => 'База даних не підтримує пароль.',
); );

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Hệ thống', 'System' => 'Hệ thống',
@@ -76,7 +78,6 @@ $translations = array(
'Data' => 'Dữ liệu', 'Data' => 'Dữ liệu',
'Database' => 'Cơ sở dữ liệu', 'Database' => 'Cơ sở dữ liệu',
'database' => 'cơ sở dữ liệu',
'Use' => 'Sử dụng', 'Use' => 'Sử dụng',
'Select database' => 'Chọn CSDL', 'Select database' => 'Chọn CSDL',
'Invalid database.' => 'CSDL sai.', 'Invalid database.' => 'CSDL sai.',
@@ -188,7 +189,7 @@ $translations = array(
'Alter indexes' => 'Sửa chỉ mục', 'Alter indexes' => 'Sửa chỉ mục',
'Add next' => 'Thêm tiếp', 'Add next' => 'Thêm tiếp',
'Index Type' => 'Loại chỉ mục', 'Index Type' => 'Loại chỉ mục',
'Column (length)' => 'Cột (độ dài)', 'length' => 'độ dài',
'Foreign keys' => 'Các khoá ngoại', 'Foreign keys' => 'Các khoá ngoại',
'Foreign key' => 'Khoá ngoại', 'Foreign key' => 'Khoá ngoại',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => 'Xx', 'System' => 'Xx',
@@ -89,7 +91,6 @@ $translations = array(
'Data' => 'Xx', 'Data' => 'Xx',
'Database' => 'Xx', 'Database' => 'Xx',
'database' => 'xx',
'DB' => 'XX', 'DB' => 'XX',
'Use' => 'Xx', 'Use' => 'Xx',
'Select database' => 'Xx', 'Select database' => 'Xx',
@@ -207,7 +208,7 @@ $translations = array(
'Alter indexes' => 'Xx', 'Alter indexes' => 'Xx',
'Add next' => 'Xx', 'Add next' => 'Xx',
'Index Type' => 'Xx', 'Index Type' => 'Xx',
'Column (length)' => 'Xx', 'length' => 'xx',
'Foreign keys' => 'Xx', 'Foreign keys' => 'Xx',
'Foreign key' => 'Xx', 'Foreign key' => 'Xx',
@@ -346,4 +347,12 @@ $translations = array(
'Type has been dropped.' => 'Xx.', 'Type has been dropped.' => 'Xx.',
'Type has been created.' => 'Xx.', 'Type has been created.' => 'Xx.',
'Alter type' => 'Xx', 'Alter type' => 'Xx',
// Table check constraints
'Checks' => 'Xx',
'Create check' => 'Xx',
'Alter check' => 'Xx',
'Check has been created.' => 'Xx.',
'Check has been altered.' => 'Xx.',
'Check has been dropped.' => 'Xx.',
); );

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => '資料庫系統', 'System' => '資料庫系統',
@@ -89,7 +91,6 @@ $translations = array(
'Data' => '資料', 'Data' => '資料',
'Database' => '資料庫', 'Database' => '資料庫',
'database' => '資料庫',
'DB' => '資料庫', 'DB' => '資料庫',
'Use' => '使用', 'Use' => '使用',
'Select database' => '選擇資料庫', 'Select database' => '選擇資料庫',
@@ -128,6 +129,7 @@ $translations = array(
'Tables have been moved.' => '已轉移資料表。', 'Tables have been moved.' => '已轉移資料表。',
'Copy' => '複製', 'Copy' => '複製',
'Tables have been copied.' => '資料表已經複製', 'Tables have been copied.' => '資料表已經複製',
'overwrite' => '覆蓋',
'Routines' => '程序', 'Routines' => '程序',
'Routine has been called, %d row(s) affected.' => '程序已被執行,%d 行被影響', 'Routine has been called, %d row(s) affected.' => '程序已被執行,%d 行被影響',
@@ -206,7 +208,7 @@ $translations = array(
'Alter indexes' => '修改索引', 'Alter indexes' => '修改索引',
'Add next' => '新增下一筆', 'Add next' => '新增下一筆',
'Index Type' => '索引類型', 'Index Type' => '索引類型',
'Column (length)' => '欄位(長度', 'length' => '長度',
'Foreign keys' => '外來鍵', 'Foreign keys' => '外來鍵',
'Foreign key' => '外來鍵', 'Foreign key' => '外來鍵',

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$translations = array( $translations = array(
// label for database system selection (MySQL, SQLite, ...) // label for database system selection (MySQL, SQLite, ...)
'System' => '系统', 'System' => '系统',
@@ -89,7 +91,6 @@ $translations = array(
'Data' => '数据', 'Data' => '数据',
'Database' => '数据库', 'Database' => '数据库',
'database' => '数据库',
'DB' => '数据库', 'DB' => '数据库',
'Use' => '使用', 'Use' => '使用',
'Select database' => '选择数据库', 'Select database' => '选择数据库',
@@ -128,6 +129,7 @@ $translations = array(
'Tables have been moved.' => '已转移表。', 'Tables have been moved.' => '已转移表。',
'Copy' => '复制', 'Copy' => '复制',
'Tables have been copied.' => '已复制表。', 'Tables have been copied.' => '已复制表。',
'overwrite' => '覆盖',
'Routines' => '子程序', 'Routines' => '子程序',
'Routine has been called, %d row(s) affected.' => '子程序被调用,%d 行被影响。', 'Routine has been called, %d row(s) affected.' => '子程序被调用,%d 行被影响。',

View File

@@ -8,6 +8,9 @@ function adminer_object() {
include_once $filename; include_once $filename;
} }
// enable extra drivers just by including them
//~ include "../plugins/drivers/simpledb.php";
$plugins = array( $plugins = array(
// specify enabled plugins here // specify enabled plugins here
new AdminerDatabaseHide(array('information_schema')), new AdminerDatabaseHide(array('information_schema')),
@@ -17,9 +20,7 @@ function adminer_object() {
new AdminerDumpXml, new AdminerDumpXml,
new AdminerDumpAlter, new AdminerDumpAlter,
//~ new AdminerSqlLog("past-" . rtrim(`git describe --tags --abbrev=0`) . ".sql"), //~ 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 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 AdminerFileUpload(""),
new AdminerJsonColumn, new AdminerJsonColumn,
new AdminerSlugify, new AdminerSlugify,

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
page_header(lang('Privileges')); page_header(lang('Privileges'));
echo '<p class="links"><a href="' . h(ME) . 'user=">' . lang('Create user') . "</a>"; echo '<p class="links"><a href="' . h(ME) . 'user=">' . lang('Create user') . "</a>";
@@ -14,15 +16,15 @@ echo "<form action=''><p>\n";
hidden_fields_get(); hidden_fields_get();
echo "<input type='hidden' name='db' value='" . h(DB) . "'>\n"; echo "<input type='hidden' name='db' value='" . h(DB) . "'>\n";
echo ($grant ? "" : "<input type='hidden' name='grant' value=''>\n"); echo ($grant ? "" : "<input type='hidden' name='grant' value=''>\n");
echo "<table cellspacing='0'>\n"; echo "<table class='odds'>\n";
echo "<thead><tr><th>" . lang('Username') . "<th>" . lang('Server') . "<th></thead>\n"; echo "<thead><tr><th>" . lang('Username') . "<th>" . lang('Server') . "<th></thead>\n";
while ($row = $result->fetch_assoc()) { while ($row = $result->fetch_assoc()) {
echo '<tr' . odd() . '><td>' . h($row["User"]) . "<td>" . h($row["Host"]) . '<td><a href="' . h(ME . 'user=' . urlencode($row["User"]) . '&host=' . urlencode($row["Host"])) . '">' . lang('Edit') . "</a>\n"; echo '<tr><td>' . h($row["User"]) . "<td>" . h($row["Host"]) . '<td><a href="' . h(ME . 'user=' . urlencode($row["User"]) . '&host=' . urlencode($row["Host"])) . '">' . lang('Edit') . "</a>\n";
} }
if (!$grant || DB != "") { if (!$grant || DB != "") {
echo "<tr" . odd() . "><td><input name='user' autocapitalize='off'><td><input name='host' value='localhost' autocapitalize='off'><td><input type='submit' value='" . lang('Edit') . "'>\n"; echo "<tr><td><input name='user' autocapitalize='off'><td><input name='host' value='localhost' autocapitalize='off'><td><input type='submit' value='" . lang('Edit') . "'>\n";
} }
echo "</table>\n"; echo "</table>\n";

View File

@@ -1,5 +1,7 @@
<?php <?php
$PROCEDURE = ($_GET["name"] ? $_GET["name"] : $_GET["procedure"]); namespace Adminer;
$PROCEDURE = ($_GET["name"] ?: $_GET["procedure"]);
$routine = (isset($_GET["function"]) ? "FUNCTION" : "PROCEDURE"); $routine = (isset($_GET["function"]) ? "FUNCTION" : "PROCEDURE");
$row = $_POST; $row = $_POST;
$row["fields"] = (array) $row["fields"]; $row["fields"] = (array) $row["fields"];
@@ -39,19 +41,22 @@ $routine_languages = routine_languages();
<?php echo ($routine_languages ? lang('Language') . ": " . html_select("language", $routine_languages, $row["language"]) . "\n" : ""); ?> <?php echo ($routine_languages ? lang('Language') . ": " . html_select("language", $routine_languages, $row["language"]) . "\n" : ""); ?>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<div class="scrollable"> <div class="scrollable">
<table cellspacing="0" class="nowrap"> <table class="nowrap">
<?php <?php
edit_fields($row["fields"], $collations, $routine); edit_fields($row["fields"], $collations, $routine);
if (isset($_GET["function"])) { if (isset($_GET["function"])) {
echo "<tr><td>" . lang('Return type'); echo "<tr><td>" . lang('Return type');
edit_type("returns", $row["returns"], $collations, array(), ($jush == "pgsql" ? array("void", "trigger") : array())); edit_type("returns", $row["returns"], $collations, array(), (JUSH == "pgsql" ? array("void", "trigger") : array()));
} }
?> ?>
</table> </table>
<?php echo script("editFields();"); ?>
</div> </div>
<p><?php textarea("definition", $row["definition"]); ?> <p><?php textarea("definition", $row["definition"]); ?>
<p> <p>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php if ($PROCEDURE != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $PROCEDURE)); ?><?php } ?> <?php if ($PROCEDURE != "") { ?>
<input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $PROCEDURE)); ?>
<?php } ?>
<input type="hidden" name="token" value="<?php echo $token; ?>"> <input type="hidden" name="token" value="<?php echo $token; ?>">
</form> </form>

View File

@@ -1,5 +1,8 @@
<?php <?php
if (support("kill") && $_POST && !$error) { namespace Adminer;
if (support("kill")) {
if ($_POST && !$error) {
$killed = 0; $killed = 0;
foreach ((array) $_POST["kill"] as $val) { foreach ((array) $_POST["kill"] as $val) {
if (kill_process($val)) { if (kill_process($val)) {
@@ -8,19 +11,19 @@ if (support("kill") && $_POST && !$error) {
} }
queries_redirect(ME . "processlist=", lang('%d process(es) have been killed.', $killed), $killed || !$_POST["kill"]); queries_redirect(ME . "processlist=", lang('%d process(es) have been killed.', $killed), $killed || !$_POST["kill"]);
} }
}
page_header(lang('Process list'), $error); page_header(lang('Process list'), $error);
?> ?>
<form action="" method="post"> <form action="" method="post">
<div class="scrollable"> <div class="scrollable">
<table cellspacing="0" class="nowrap checkable"> <table class="nowrap checkable odds">
<?php <?php
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});"); echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
// HTML valid because there is always at least one process // HTML valid because there is always at least one process
$i = -1; $i = -1;
foreach (process_list() as $i => $row) { foreach (process_list() as $i => $row) {
if (!$i) { if (!$i) {
echo "<thead><tr lang='en'>" . (support("kill") ? "<th>" : ""); echo "<thead><tr lang='en'>" . (support("kill") ? "<th>" : "");
foreach ($row as $key => $val) { foreach ($row as $key => $val) {
@@ -32,13 +35,13 @@ foreach (process_list() as $i => $row) {
} }
echo "</thead>\n"; echo "</thead>\n";
} }
echo "<tr" . odd() . ">" . (support("kill") ? "<td>" . checkbox("kill[]", $row[$jush == "sql" ? "Id" : "pid"], 0) : ""); echo "<tr>" . (support("kill") ? "<td>" . checkbox("kill[]", $row[JUSH == "sql" ? "Id" : "pid"], 0) : "");
foreach ($row as $key => $val) { foreach ($row as $key => $val) {
echo "<td>" . ( echo "<td>" . (
($jush == "sql" && $key == "Info" && preg_match("~Query|Killed~", $row["Command"]) && $val != "") || (JUSH == "sql" && $key == "Info" && preg_match("~Query|Killed~", $row["Command"]) && $val != "") ||
($jush == "pgsql" && $key == "current_query" && $val != "<IDLE>") || (JUSH == "pgsql" && $key == "current_query" && $val != "<IDLE>") ||
($jush == "oracle" && $key == "sql_text" && $val != "") (JUSH == "oracle" && $key == "sql_text" && $val != "")
? "<code class='jush-$jush'>" . shorten_utf8($val, 100, "</code>") . ' <a href="' . h(ME . ($row["db"] != "" ? "db=" . urlencode($row["db"]) . "&" : "") . "sql=" . urlencode($val)) . '">' . lang('Clone') . '</a>' ? "<code class='jush-" . JUSH . "'>" . shorten_utf8($val, 100, "</code>") . ' <a href="' . h(ME . ($row["db"] != "" ? "db=" . urlencode($row["db"]) . "&" : "") . "sql=" . urlencode($val)) . '">' . lang('Clone') . '</a>'
: h($val) : h($val)
); );
} }

View File

@@ -1,9 +1,11 @@
<?php <?php
namespace Adminer;
page_header(lang('Database schema'), "", array(), h(DB . ($_GET["ns"] ? ".$_GET[ns]" : ""))); page_header(lang('Database schema'), "", array(), h(DB . ($_GET["ns"] ? ".$_GET[ns]" : "")));
$table_pos = array(); $table_pos = array();
$table_pos_js = array(); $table_pos_js = array();
$SCHEMA = ($_GET["schema"] ? $_GET["schema"] : $_COOKIE["adminer_schema-" . str_replace(".", "_", DB)]); // $_COOKIE["adminer_schema"] was used before 3.2.0 //! ':' in table name $SCHEMA = ($_GET["schema"] ?: $_COOKIE["adminer_schema-" . str_replace(".", "_", DB)]); // $_COOKIE["adminer_schema"] was used before 3.2.0 //! ':' in table name
preg_match_all('~([^:]+):([-0-9.]+)x([-0-9.]+)(_|$)~', $SCHEMA, $matches, PREG_SET_ORDER); preg_match_all('~([^:]+):([-0-9.]+)x([-0-9.]+)(_|$)~', $SCHEMA, $matches, PREG_SET_ORDER);
foreach ($matches as $i => $match) { foreach ($matches as $i => $match) {
$table_pos[$match[1]] = array($match[2], $match[3]); $table_pos[$match[1]] = array($match[2], $match[3]);
@@ -26,7 +28,7 @@ foreach (table_status('', true) as $table => $table_status) {
$field["pos"] = $pos; $field["pos"] = $pos;
$schema[$table]["fields"][$name] = $field; $schema[$table]["fields"][$name] = $field;
} }
$schema[$table]["pos"] = ($table_pos[$table] ? $table_pos[$table] : array($top, 0)); $schema[$table]["pos"] = ($table_pos[$table] ?: array($top, 0));
foreach ($adminer->foreignKeys($table) as $val) { foreach ($adminer->foreignKeys($table) as $val) {
if (!$val["db"]) { if (!$val["db"]) {
$left = $base_left; $left = $base_left;
@@ -82,7 +84,10 @@ foreach ($schema as $name => $table) {
$left1 = $left - $table_pos[$name][1]; $left1 = $left - $table_pos[$name][1];
$i = 0; $i = 0;
foreach ($columns as $target) { foreach ($columns as $target) {
echo "\n<div class='references' title='" . h($target_name) . "' id='refd$left-" . ($i++) . "' style='left: $left1" . "em; top: " . $table["fields"][$target]["pos"] . "em; height: 1.25em; background: url(../adminer/static/arrow.gif) no-repeat right center;'><div style='height: .5em; border-bottom: 1px solid Gray; width: " . (-$left1) . "em;'></div></div>"; echo "\n<div class='references' title='" . h($target_name) . "' id='refd$left-" . ($i++) . "' style='left: $left1" . "em; top: " . $table["fields"][$target]["pos"] . "em; height: 1.25em; background: url(../adminer/static/arrow.gif) no-repeat right center;'>"
. "<div style='height: .5em; border-bottom: 1px solid Gray; width: " . (-$left1) . "em;'></div>"
. "</div>"
;
} }
} }
} }

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$row = $_POST; $row = $_POST;
if ($_POST && !$error) { if ($_POST && !$error) {
@@ -26,8 +28,7 @@ if (!$row) {
?> ?>
<form action="" method="post"> <form action="" method="post">
<p><input name="name" id="name" value="<?php echo h($row["name"]); ?>" autocapitalize="off"> <p><input name="name" autofocus value="<?php echo h($row["name"]); ?>" autocapitalize="off">
<?php echo script("focus(qs('#name'));"); ?>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php <?php
if ($_GET["ns"] != "") { if ($_GET["ns"] != "") {

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
header("Content-Type: text/javascript; charset=utf-8"); header("Content-Type: text/javascript; charset=utf-8");
if ($_GET["script"] == "db") { if ($_GET["script"] == "db") {
@@ -12,10 +14,12 @@ if ($_GET["script"] == "db") {
foreach ($sums + array("Auto_increment" => 0, "Rows" => 0) as $key => $val) { foreach ($sums + array("Auto_increment" => 0, "Rows" => 0) as $key => $val) {
if ($table_status[$key] != "") { if ($table_status[$key] != "") {
$val = format_number($table_status[$key]); $val = format_number($table_status[$key]);
json_row("$key-$name", ($key == "Rows" && $val && $table_status["Engine"] == ($sql == "pgsql" ? "table" : "InnoDB") if ($val >= 0) {
json_row("$key-$name", ($key == "Rows" && $val && $table_status["Engine"] == (JUSH == "pgsql" ? "table" : "InnoDB")
? "~ $val" ? "~ $val"
: $val : $val
)); ));
}
if (isset($sums[$key])) { if (isset($sums[$key])) {
// ignore innodb_file_per_table because it is not active for tables created before it was enabled // ignore innodb_file_per_table because it is not active for tables created before it was enabled
$sums[$key] += ($table_status["Engine"] != "InnoDB" || $key != "Data_free" ? $table_status[$key] : 0); $sums[$key] += ($table_status["Engine"] != "InnoDB" || $key != "Data_free" ? $table_status[$key] : 0);

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$TABLE = $_GET["select"]; $TABLE = $_GET["select"];
$table_status = table_status1($TABLE); $table_status = table_status1($TABLE);
$indexes = indexes($TABLE); $indexes = indexes($TABLE);
@@ -22,6 +24,8 @@ foreach ($fields as $key => $field) {
} }
list($select, $group) = $adminer->selectColumnsProcess($columns, $indexes); list($select, $group) = $adminer->selectColumnsProcess($columns, $indexes);
$select = array_unique($select);
$group = array_unique($group);
$is_group = count($group) < count($select); $is_group = count($group) < count($select);
$where = $adminer->selectSearchProcess($fields, $indexes); $where = $adminer->selectSearchProcess($fields, $indexes);
$order = $adminer->selectOrderProcess($fields, $indexes); $order = $adminer->selectOrderProcess($fields, $indexes);
@@ -31,7 +35,7 @@ if ($_GET["val"] && is_ajax()) {
header("Content-Type: text/plain; charset=utf-8"); header("Content-Type: text/plain; charset=utf-8");
foreach ($_GET["val"] as $unique_idf => $row) { foreach ($_GET["val"] as $unique_idf => $row) {
$as = convert_field($fields[key($row)]); $as = convert_field($fields[key($row)]);
$select = array($as ? $as : idf_escape(key($row))); $select = array($as ?: idf_escape(key($row)));
$where[] = where_check($unique_idf, $fields); $where[] = where_check($unique_idf, $fields);
$return = $driver->select($TABLE, $select, $where, $select); $return = $driver->select($TABLE, $select, $where, $select);
if ($return) { if ($return) {
@@ -97,7 +101,7 @@ if ($_POST && !$error) {
$affected = 0; $affected = 0;
$set = array(); $set = array();
if (!$_POST["delete"]) { if (!$_POST["delete"]) {
foreach ($columns as $name => $val) { //! should check also for edit or insert privileges foreach ($_POST["fields"] as $name => $val) {
$val = process_input($fields[$name]); $val = process_input($fields[$name]);
if ($val !== null && ($_POST["clone"] || $val !== false)) { if ($val !== null && ($_POST["clone"] || $val !== false)) {
$set[idf_escape($name)] = ($val !== false ? $val : idf_escape($name)); $set[idf_escape($name)] = ($val !== false ? $val : idf_escape($name));
@@ -144,7 +148,8 @@ if ($_POST && !$error) {
} }
queries_redirect(remove_from_uri($_POST["all"] && $_POST["delete"] ? "page" : ""), $message, $result); queries_redirect(remove_from_uri($_POST["all"] && $_POST["delete"] ? "page" : ""), $message, $result);
if (!$_POST["delete"]) { if (!$_POST["delete"]) {
edit_form($TABLE, $fields, (array) $_POST["fields"], !$_POST["clone"]); $post_fields = (array) $_POST["fields"];
edit_form($TABLE, array_intersect_key($fields, $post_fields), $post_fields, !$_POST["clone"]);
page_footer(); page_footer();
exit; exit;
} }
@@ -198,14 +203,14 @@ if ($_POST && !$error) {
} else { } else {
$set = array(); $set = array();
foreach ($matches2[1] as $i => $col) { foreach ($matches2[1] as $i => $col) {
$set[idf_escape($cols[$i])] = ($col == "" && $fields[$cols[$i]]["null"] ? "NULL" : q(str_replace('""', '"', preg_replace('~^"|"$~', '', $col)))); $set[idf_escape($cols[$i])] = ($col == "" && $fields[$cols[$i]]["null"] ? "NULL" : q(preg_match('~^".*"$~s', $col) ? str_replace('""', '"', substr($col, 1, -1)) : $col));
} }
$rows[] = $set; $rows[] = $set;
} }
} }
$result = (!$rows || $driver->insertUpdate($TABLE, $rows, $primary)); $result = (!$rows || $driver->insertUpdate($TABLE, $rows, $primary));
if ($result) { if ($result) {
$result = $driver->commit(); $driver->commit();
} }
queries_redirect(remove_from_uri("page"), lang('%d row(s) have been imported.', $affected), $result); queries_redirect(remove_from_uri("page"), lang('%d row(s) have been imported.', $affected), $result);
$driver->rollback(); // after queries_redirect() to not overwrite error $driver->rollback(); // after queries_redirect() to not overwrite error
@@ -224,14 +229,17 @@ if (is_ajax()) {
$set = null; $set = null;
if (isset($rights["insert"]) || !support("table")) { if (isset($rights["insert"]) || !support("table")) {
$set = ""; $params = array();
foreach ((array) $_GET["where"] as $val) { foreach ((array) $_GET["where"] as $val) {
if ($foreign_keys[$val["col"]] && count($foreign_keys[$val["col"]]) == 1 && ($val["op"] == "=" if (
|| (!$val["op"] && !preg_match('~[_%]~', $val["val"])) // LIKE in Editor isset($foreign_keys[$val["col"]]) && count($foreign_keys[$val["col"]]) == 1
)) { && ($val["op"] == "=" || (!$val["op"] && (is_array($val["val"]) || !preg_match('~[_%]~', $val["val"])))) // LIKE in Editor
$set .= "&set" . urlencode("[" . bracket_escape($val["col"]) . "]") . "=" . urlencode($val["val"]); ) {
$params["set" . "[" . bracket_escape($val["col"]) . "]"] = $val["val"];
} }
} }
$set = $params ? "&" . http_build_query($params) : "";
} }
$adminer->selectLinks($table_status, $set); $adminer->selectLinks($table_status, $set);
@@ -286,21 +294,21 @@ if (!$columns && support("table")) {
if (!$result) { if (!$result) {
echo "<p class='error'>" . error() . "\n"; echo "<p class='error'>" . error() . "\n";
} else { } else {
if ($jush == "mssql" && $page) { if (JUSH == "mssql" && $page) {
$result->seek($limit * $page); $result->seek($limit * $page);
} }
$email_fields = array(); $email_fields = array();
echo "<form action='' method='post' enctype='multipart/form-data'>\n"; echo "<form action='' method='post' enctype='multipart/form-data'>\n";
$rows = array(); $rows = array();
while ($row = $result->fetch_assoc()) { while ($row = $result->fetch_assoc()) {
if ($page && $jush == "oracle") { if ($page && JUSH == "oracle") {
unset($row["RNUM"]); unset($row["RNUM"]);
} }
$rows[] = $row; $rows[] = $row;
} }
// use count($rows) without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest) // use count($rows) without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest)
if ($_GET["page"] != "last" && $limit != "" && $group && $is_group && $jush == "sql") { if ($_GET["page"] != "last" && $limit != "" && $group && $is_group && JUSH == "sql") {
$found_rows = $connection->result(" SELECT FOUND_ROWS()"); // space to allow mysql.trace_mode $found_rows = $connection->result(" SELECT FOUND_ROWS()"); // space to allow mysql.trace_mode
} }
@@ -310,7 +318,7 @@ if (!$columns && support("table")) {
$backward_keys = $adminer->backwardKeys($TABLE, $table_name); $backward_keys = $adminer->backwardKeys($TABLE, $table_name);
echo "<div class='scrollable'>"; echo "<div class='scrollable'>";
echo "<table id='table' cellspacing='0' class='nowrap checkable'>"; echo "<table id='table' class='nowrap checkable odds'>";
echo script("mixin(qs('#table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true), onkeydown: editingKeydown});"); echo script("mixin(qs('#table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true), onkeydown: editingKeydown});");
echo "<thead><tr>" . (!$group && $select echo "<thead><tr>" . (!$group && $select
? "" ? ""
@@ -324,14 +332,14 @@ if (!$columns && support("table")) {
if (!isset($unselected[$key])) { if (!isset($unselected[$key])) {
$val = $_GET["columns"][key($select)]; $val = $_GET["columns"][key($select)];
$field = $fields[$select ? ($val ? $val["col"] : current($select)) : $key]; $field = $fields[$select ? ($val ? $val["col"] : current($select)) : $key];
$name = ($field ? $adminer->fieldName($field, $rank) : ($val["fun"] ? "*" : $key)); $name = ($field ? $adminer->fieldName($field, $rank) : ($val["fun"] ? "*" : h($key)));
if ($name != "") { if ($name != "") {
$rank++; $rank++;
$names[$key] = $name; $names[$key] = $name;
$column = idf_escape($key); $column = idf_escape($key);
$href = remove_from_uri('(order|desc)[^=]*|page') . '&order%5B0%5D=' . urlencode($key); $href = remove_from_uri('(order|desc)[^=]*|page') . '&order%5B0%5D=' . urlencode($key);
$desc = "&desc%5B0%5D=1"; $desc = "&desc%5B0%5D=1";
echo "<th>" . script("mixin(qsl('th'), {onmouseover: partial(columnMouse), onmouseout: partial(columnMouse, ' hidden')});", ""); echo "<th id='th[" . h(bracket_escape($key)) . "]'>" . script("mixin(qsl('th'), {onmouseover: partial(columnMouse), onmouseout: partial(columnMouse, ' hidden')});", "");
echo '<a href="' . h($href . ($order[0] == $column || $order[0] == $key || (!$order && $is_group && $group[0] == $column) ? $desc : '')) . '">'; // $order[0] == $key - COUNT(*) echo '<a href="' . h($href . ($order[0] == $column || $order[0] == $key || (!$order && $is_group && $group[0] == $column) ? $desc : '')) . '">'; // $order[0] == $key - COUNT(*)
echo apply_sql_function($val["fun"], $name) . "</a>"; //! columns looking like functions echo apply_sql_function($val["fun"], $name) . "</a>"; //! columns looking like functions
echo "<span class='column hidden'>"; echo "<span class='column hidden'>";
@@ -359,9 +367,6 @@ if (!$columns && support("table")) {
echo ($backward_keys ? "<th>" . lang('Relations') : "") . "</thead>\n"; echo ($backward_keys ? "<th>" . lang('Relations') : "") . "</thead>\n";
if (is_ajax()) { if (is_ajax()) {
if ($limit % 2 == 1 && $page % 2 == 1) {
odd();
}
ob_end_clean(); ob_end_clean();
} }
@@ -377,14 +382,14 @@ if (!$columns && support("table")) {
} }
$unique_idf = ""; $unique_idf = "";
foreach ($unique_array as $key => $val) { foreach ($unique_array as $key => $val) {
if (($jush == "sql" || $jush == "pgsql") && preg_match('~char|text|enum|set~', $fields[$key]["type"]) && strlen($val) > 64) { if ((JUSH == "sql" || JUSH == "pgsql") && preg_match('~char|text|enum|set~', $fields[$key]["type"]) && strlen($val) > 64) {
$key = (strpos($key, '(') ? $key : idf_escape($key)); //! columns looking like functions $key = (strpos($key, '(') ? $key : idf_escape($key)); //! columns looking like functions
$key = "MD5(" . ($jush != 'sql' || preg_match("~^utf8~", $fields[$key]["collation"]) ? $key : "CONVERT($key USING " . charset($connection) . ")") . ")"; $key = "MD5(" . (JUSH != 'sql' || preg_match("~^utf8~", $fields[$key]["collation"]) ? $key : "CONVERT($key USING " . charset($connection) . ")") . ")";
$val = md5($val); $val = md5($val);
} }
$unique_idf .= "&" . ($val !== null ? urlencode("where[" . bracket_escape($key) . "]") . "=" . urlencode($val) : "null%5B%5D=" . urlencode($key)); $unique_idf .= "&" . ($val !== null ? urlencode("where[" . bracket_escape($key) . "]") . "=" . urlencode($val === false ? "f" : $val) : "null%5B%5D=" . urlencode($key));
} }
echo "<tr" . odd() . ">" . (!$group && $select ? "" : "<td>" echo "<tr>" . (!$group && $select ? "" : "<td>"
. checkbox("check[]", substr($unique_idf, 1), in_array(substr($unique_idf, 1), (array) $_POST["check"])) . checkbox("check[]", substr($unique_idf, 1), in_array(substr($unique_idf, 1), (array) $_POST["check"]))
. ($is_group || information_schema(DB) ? "" : " <a href='" . h(ME . "edit=" . urlencode($TABLE) . $unique_idf) . "' class='edit'>" . lang('edit') . "</a>") . ($is_group || information_schema(DB) ? "" : " <a href='" . h(ME . "edit=" . urlencode($TABLE) . $unique_idf) . "' class='edit'>" . lang('edit') . "</a>")
); );
@@ -434,16 +439,17 @@ if (!$columns && support("table")) {
$val = select_value($val, $link, $field, $text_length); $val = select_value($val, $link, $field, $text_length);
$id = h("val[$unique_idf][" . bracket_escape($key) . "]"); $id = h("val[$unique_idf][" . bracket_escape($key) . "]");
$value = $_POST["val"][$unique_idf][bracket_escape($key)]; $value = $_POST["val"][$unique_idf][bracket_escape($key)];
$editable = !is_array($row[$key]) && is_utf8($val) && $rows[$n][$key] == $row[$key] && !$functions[$key]; $editable = !is_array($row[$key]) && is_utf8($val) && $rows[$n][$key] == $row[$key] && !$functions[$key] && !$field["generated"];
$text = preg_match('~text|lob~', $field["type"]); $text = preg_match('~text|lob~', $field["type"]);
echo "<td id='$id'";
if (($_GET["modify"] && $editable) || $value !== null) { if (($_GET["modify"] && $editable) || $value !== null) {
$h_value = h($value !== null ? $value : $row[$key]); $h_value = h($value !== null ? $value : $row[$key]);
echo "<td>" . ($text ? "<textarea name='$id' cols='30' rows='" . (substr_count($row[$key], "\n") + 1) . "'>$h_value</textarea>" : "<input name='$id' value='$h_value' size='$lengths[$key]'>"); echo ">" . ($text ? "<textarea name='$id' cols='30' rows='" . (substr_count($row[$key], "\n") + 1) . "'>$h_value</textarea>" : "<input name='$id' value='$h_value' size='$lengths[$key]'>");
} else { } else {
$long = strpos($val, "<i>…</i>"); $long = strpos($val, "<i>…</i>");
echo "<td id='$id' data-text='" . ($long ? 2 : ($text ? 1 : 0)) . "'" echo " data-text='" . ($long ? 2 : ($text ? 1 : 0)) . "'"
. ($editable ? "" : " data-warning='" . h(lang('Use edit link to modify this value.')) . "'") . ($editable ? "" : " data-warning='" . h(lang('Use edit link to modify this value.')) . "'")
. ">$val</td>" . ">$val"
; ;
} }
} }
@@ -469,7 +475,7 @@ if (!$columns && support("table")) {
if ($_GET["page"] != "last") { if ($_GET["page"] != "last") {
if ($limit == "" || (count($rows) < $limit && ($rows || !$page))) { if ($limit == "" || (count($rows) < $limit && ($rows || !$page))) {
$found_rows = ($page ? $page * $limit : 0) + count($rows); $found_rows = ($page ? $page * $limit : 0) + count($rows);
} elseif ($jush != "sql" || !$is_group) { } elseif (JUSH != "sql" || !$is_group) {
$found_rows = ($is_group ? false : found_rows($table_status, $where)); $found_rows = ($is_group ? false : found_rows($table_status, $where));
if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) { if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) {
// slow with big tables // slow with big tables
@@ -500,7 +506,7 @@ if (!$columns && support("table")) {
: floor(($found_rows - 1) / $limit) : floor(($found_rows - 1) / $limit)
); );
echo "<fieldset>"; echo "<fieldset>";
if ($jush != "simpledb") { if (JUSH != "simpledb") {
echo "<legend><a href='" . h(remove_from_uri("page")) . "'>" . lang('Page') . "</a></legend>"; echo "<legend><a href='" . h(remove_from_uri("page")) . "'>" . lang('Page') . "</a></legend>";
echo script("qsl('a').onclick = function () { pageClick(this.href, +prompt('" . lang('Page') . "', '" . ($page + 1) . "')); return false; };"); echo script("qsl('a').onclick = function () { pageClick(this.href, +prompt('" . lang('Page') . "', '" . ($page + 1) . "')); return false; };");
echo pagination(0, $page) . ($page > 5 ? "" : ""); echo pagination(0, $page) . ($page > 5 ? "" : "");
@@ -526,7 +532,8 @@ if (!$columns && support("table")) {
echo "<fieldset>"; echo "<fieldset>";
echo "<legend>" . lang('Whole result') . "</legend>"; echo "<legend>" . lang('Whole result') . "</legend>";
$display_rows = ($exact_count ? "" : "~ ") . $found_rows; $display_rows = ($exact_count ? "" : "~ ") . $found_rows;
echo checkbox("all", 1, 0, ($found_rows !== false ? ($exact_count ? "" : "~ ") . lang('%d row(s)', $found_rows) : ""), "var checked = formChecked(this, /check/); selectCount('selected', this.checked ? '$display_rows' : checked); selectCount('selected2', this.checked || !checked ? '$display_rows' : checked);") . "\n"; $onclick = "var checked = formChecked(this, /check/); selectCount('selected', this.checked ? '$display_rows' : checked); selectCount('selected2', this.checked || !checked ? '$display_rows' : checked);";
echo checkbox("all", 1, 0, ($found_rows !== false ? ($exact_count ? "" : "~ ") . lang('%d row(s)', $found_rows) : ""), $onclick) . "\n";
echo "</fieldset>\n"; echo "</fieldset>\n";
if ($adminer->selectCommandPrint()) { if ($adminer->selectCommandPrint()) {
@@ -567,7 +574,7 @@ if (!$columns && support("table")) {
echo "<div>"; echo "<div>";
echo "<a href='#import'>" . lang('Import') . "</a>"; echo "<a href='#import'>" . lang('Import') . "</a>";
echo script("qsl('a').onclick = partial(toggle, 'import');", ""); echo script("qsl('a').onclick = partial(toggle, 'import');", "");
echo "<span id='import' class='hidden'>: "; echo "<span id='import'" . ($_POST["import"] ? "" : " class='hidden'") . ">: ";
echo "<input type='file' name='csv_file'> "; echo "<input type='file' name='csv_file'> ";
echo html_select("separator", array("csv" => "CSV,", "csv;" => "CSV;", "tsv" => "TSV"), $adminer_import["format"], 1); // 1 - select echo html_select("separator", array("csv" => "CSV,", "csv;" => "CSV;", "tsv" => "TSV"), $adminer_import["format"], 1); // 1 - select
echo " <input type='submit' name='import' value='" . lang('Import') . "'>"; echo " <input type='submit' name='import' value='" . lang('Import') . "'>";

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
$SEQUENCE = $_GET["sequence"]; $SEQUENCE = $_GET["sequence"];
$row = $_POST; $row = $_POST;

View File

@@ -1,4 +1,6 @@
<?php <?php
namespace Adminer;
if (!$error && $_POST["export"]) { if (!$error && $_POST["export"]) {
dump_headers("sql"); dump_headers("sql");
$adminer->dumpTable("", ""); $adminer->dumpTable("", "");
@@ -32,8 +34,8 @@ if (!$error && $_POST) {
} }
if (is_string($query)) { // get_file() returns error as number, fread() as false if (is_string($query)) { // get_file() returns error as number, fread() as false
if (function_exists('memory_get_usage')) { if (function_exists('memory_get_usage') && ($memory_limit = ini_bytes("memory_limit")) != "-1") {
@ini_set("memory_limit", max(ini_bytes("memory_limit"), 2 * strlen($query) + memory_get_usage() + 8e6)); // @ - may be disabled, 2 - substr and trim, 8e6 - other variables @ini_set("memory_limit", max($memory_limit, 2 * strlen($query) + memory_get_usage() + 8e6)); // @ - may be disabled, 2 - substr and trim, 8e6 - other variables
} }
if ($query != "" && strlen($query) < 1e6) { // don't add big queries if ($query != "" && strlen($query) < 1e6) { // don't add big queries
@@ -50,13 +52,16 @@ if (!$error && $_POST) {
$delimiter = ";"; $delimiter = ";";
$offset = 0; $offset = 0;
$empty = true; $empty = true;
$connection2 = connect(); // connection for exploring indexes and EXPLAIN (to not replace FOUND_ROWS()) //! PDO - silent error $connection2 = connect($adminer->credentials()); // connection for exploring indexes and EXPLAIN (to not replace FOUND_ROWS()) //! PDO - silent error
if (is_object($connection2) && DB != "") { if (is_object($connection2) && DB != "") {
$connection2->select_db(DB); $connection2->select_db(DB);
if ($_GET["ns"] != "") {
set_schema($_GET["ns"], $connection2);
}
} }
$commands = 0; $commands = 0;
$errors = array(); $errors = array();
$parse = '[\'"' . ($jush == "sql" ? '`#' : ($jush == "sqlite" ? '`[' : ($jush == "mssql" ? '[' : ''))) . ']|/\*|-- |$' . ($jush == "pgsql" ? '|\$[^$]*\$' : ''); $parse = '[\'"' . (JUSH == "sql" ? '`#' : (JUSH == "sqlite" ? '`[' : (JUSH == "mssql" ? '[' : ''))) . ']|/\*|-- |$' . (JUSH == "pgsql" ? '|\$[^$]*\$' : '');
$total_start = microtime(true); $total_start = microtime(true);
parse_str($_COOKIE["adminer_export"], $adminer_export); parse_str($_COOKIE["adminer_export"], $adminer_export);
$dump_format = $adminer->dumpFormat(); $dump_format = $adminer->dumpFormat();
@@ -78,13 +83,21 @@ if (!$error && $_POST) {
$offset = $pos + strlen($found); $offset = $pos + strlen($found);
if ($found && rtrim($found) != $delimiter) { // find matching quote or comment end if ($found && rtrim($found) != $delimiter) { // find matching quote or comment end
while (preg_match('(' . ($found == '/*' ? '\*/' : ($found == '[' ? ']' : (preg_match('~^-- |^#~', $found) ? "\n" : preg_quote($found) . "|\\\\."))) . '|$)s', $query, $match, PREG_OFFSET_CAPTURE, $offset)) { //! respect sql_mode NO_BACKSLASH_ESCAPES $c_style_escapes = $driver->hasCStyleEscapes() || (JUSH == "pgsql" && ($pos > 0 && strtolower($query[$pos - 1]) == "e"));
$pattern = ($found == '/*' ? '\*/'
: ($found == '[' ? ']'
: (preg_match('~^-- |^#~', $found) ? "\n"
: preg_quote($found) . ($c_style_escapes ? "|\\\\." : "")
)));
while (preg_match("($pattern|\$)s", $query, $match, PREG_OFFSET_CAPTURE, $offset)) {
$s = $match[0][0]; $s = $match[0][0];
if (!$s && $fp && !feof($fp)) { if (!$s && $fp && !feof($fp)) {
$query .= fread($fp, 1e5); $query .= fread($fp, 1e5);
} else { } else {
$offset = $match[0][1] + strlen($s); $offset = $match[0][1] + strlen($s);
if ($s[0] != "\\") { if (!$s || $s[0] != "\\") {
break; break;
} }
} }
@@ -94,8 +107,8 @@ if (!$error && $_POST) {
$empty = false; $empty = false;
$q = substr($query, 0, $pos); $q = substr($query, 0, $pos);
$commands++; $commands++;
$print = "<pre id='sql-$commands'><code class='jush-$jush'>" . $adminer->sqlCommandQuery($q) . "</code></pre>\n"; $print = "<pre id='sql-$commands'><code class='jush-" . JUSH . "'>" . $adminer->sqlCommandQuery($q) . "</code></pre>\n";
if ($jush == "sqlite" && preg_match("~^$space*+ATTACH\\b~i", $q, $match)) { if (JUSH == "sqlite" && preg_match("~^$space*+ATTACH\\b~i", $q, $match)) {
// PHP doesn't support setting SQLITE_LIMIT_ATTACHED // PHP doesn't support setting SQLITE_LIMIT_ATTACHED
echo $print; echo $print;
echo "<p class='error'>" . lang('ATTACH queries are not supported.') . "\n"; echo "<p class='error'>" . lang('ATTACH queries are not supported.') . "\n";
@@ -130,7 +143,7 @@ if (!$error && $_POST) {
$time = " <span class='time'>(" . format_time($start) . ")</span>" $time = " <span class='time'>(" . format_time($start) . ")</span>"
. (strlen($q) < 1000 ? " <a href='" . h(ME) . "sql=" . urlencode(trim($q)) . "'>" . lang('Edit') . "</a>" : "") // 1000 - maximum length of encoded URL in IE is 2083 characters . (strlen($q) < 1000 ? " <a href='" . h(ME) . "sql=" . urlencode(trim($q)) . "'>" . lang('Edit') . "</a>" : "") // 1000 - maximum length of encoded URL in IE is 2083 characters
; ;
$affected = $connection->affected_rows; // getting warnigns overwrites this $affected = $connection->affected_rows; // getting warnings overwrites this
$warnings = ($_POST["only_errors"] ? "" : $driver->warnings()); $warnings = ($_POST["only_errors"] ? "" : $driver->warnings());
$warnings_id = "warnings-$commands"; $warnings_id = "warnings-$commands";
if ($warnings) { if ($warnings) {
@@ -171,7 +184,7 @@ if (!$error && $_POST) {
} }
echo ($warnings ? "<div id='$warnings_id' class='hidden'>\n$warnings</div>\n" : ""); echo ($warnings ? "<div id='$warnings_id' class='hidden'>\n$warnings</div>\n" : "");
if ($explain) { if ($explain) {
echo "<div id='$explain_id' class='hidden'>\n"; echo "<div id='$explain_id' class='hidden explain'>\n";
select($explain, $connection2, $orgtables); select($explain, $connection2, $orgtables);
echo "</div>\n"; echo "</div>\n";
} }
@@ -219,7 +232,7 @@ if (!isset($_GET["import"])) {
} }
echo "<p>"; echo "<p>";
textarea("query", $q, 20); textarea("query", $q, 20);
echo script(($_POST ? "" : "qs('textarea').focus();\n") . "qs('#form').onsubmit = partial(sqlSubmit, qs('#form'), '" . remove_from_uri("sql|limit|error_stops|only_errors") . "');"); echo script(($_POST ? "" : "qs('textarea').focus();\n") . "qs('#form').onsubmit = partial(sqlSubmit, qs('#form'), '" . js_escape(remove_from_uri("sql|limit|error_stops|only_errors|history")) . "');");
echo "<p>$execute\n"; echo "<p>$execute\n";
echo lang('Limit rows') . ": <input type='number' name='limit' class='size' value='" . h($_POST ? $_POST["limit"] : $_GET["limit"]) . "'>\n"; echo lang('Limit rows') . ": <input type='number' name='limit' class='size' value='" . h($_POST ? $_POST["limit"] : $_GET["limit"]) . "'>\n";
@@ -241,8 +254,8 @@ if (!isset($_GET["import"])) {
echo "<p>"; echo "<p>";
} }
echo checkbox("error_stops", 1, ($_POST ? $_POST["error_stops"] : isset($_GET["import"])), lang('Stop on error')) . "\n"; echo checkbox("error_stops", 1, ($_POST ? $_POST["error_stops"] : isset($_GET["import"]) || $_GET["error_stops"]), lang('Stop on error')) . "\n";
echo checkbox("only_errors", 1, ($_POST ? $_POST["only_errors"] : isset($_GET["import"])), lang('Show only errors')) . "\n"; echo checkbox("only_errors", 1, ($_POST ? $_POST["only_errors"] : isset($_GET["import"]) || $_GET["only_errors"]), lang('Show only errors')) . "\n";
echo "<input type='hidden' name='token' value='$token'>\n"; echo "<input type='hidden' name='token' value='$token'>\n";
if (!isset($_GET["import"]) && $history) { if (!isset($_GET["import"]) && $history) {
@@ -252,7 +265,7 @@ if (!isset($_GET["import"]) && $history) {
list($q, $time, $elapsed) = $val; list($q, $time, $elapsed) = $val;
echo '<a href="' . h(ME . "sql=&history=$key") . '">' . lang('Edit') . "</a>" echo '<a href="' . h(ME . "sql=&history=$key") . '">' . lang('Edit') . "</a>"
. " <span class='time' title='" . @date('Y-m-d', $time) . "'>" . @date("H:i:s", $time) . "</span>" // @ - time zone may be not set . " <span class='time' title='" . @date('Y-m-d', $time) . "'>" . @date("H:i:s", $time) . "</span>" // @ - time zone may be not set
. " <code class='jush-$jush'>" . shorten_utf8(ltrim(str_replace("\n", " ", str_replace("\r", "", preg_replace('~^(#|-- ).*~m', '', $q)))), 80, "</code>") . " <code class='jush-" . JUSH . "'>" . shorten_utf8(ltrim(str_replace("\n", " ", str_replace("\r", "", preg_replace('~^(#|-- ).*~m', '', $q)))), 80, "</code>")
. ($elapsed ? " <span class='time'>($elapsed)</span>" : "") . ($elapsed ? " <span class='time'>($elapsed)</span>" : "")
. "<br>\n" . "<br>\n"
; ;

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