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

Compare commits

...

149 Commits
v4.7.8 ... icyz

Author SHA1 Message Date
Jakub Vrana
a9f768fe0d Add Adminer namespace
Adminer 5 wrapped itself into a namespace and plugins now need to call Adminer's functions via this namespace.
2025-03-16 06:18:19 +01:00
Andrea
e40e3434ef Merge branch 'vrana:master' into master 2024-06-26 12:35:01 +02:00
Andrea
4da8628305 Create zerocloud.css 2024-06-26 11:09:00 +02: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
Andrea
2319ec7692 added drag + bugfix
drag and drop + bugfix click on list
2020-02-27 09:19:54 +01:00
Andrea
d7c37f6bb5 Suggests fields and tablenames 2020-02-24 00:38:35 +01:00
Andrea
80747e0da8 lang() function instead of h() 2020-02-24 00:37:55 +01:00
Andrea
679c602b6b added filter_input()
added `filter_input()` accessing superglobals var
2020-02-20 21:10:48 +01:00
Andrea
cd2fb4acee Allow Disable foreign keys
Allow Disable foreign keys  in SQL command
2020-02-19 15:08:52 +01:00
Andrea
59b6efac9f Translation
Added translation for "access denied"
2020-02-19 10:21:21 +01:00
Andrea
eea1bce828 Disable Tables
Disable access to specified tables
2020-01-13 00:56:26 +01:00
66 changed files with 2709 additions and 836 deletions

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

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

6
.gitmodules vendored
View File

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

View File

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

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

@@ -54,7 +54,7 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
}
$process_field = process_field($field, $type_field);
$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);
if ($field["orig"] != "" || $after) {
$use_all_fields = true;
@@ -185,11 +185,17 @@ edit_fields($row["fields"], $collations, "TABLE", $foreign_keys);
<p>
<?php echo lang('Auto Increment'); ?>: <input type="number" name="Auto_increment" size="6" value="<?php echo h($row["Auto_increment"]); ?>">
<?php echo checkbox("defaults", 1, ($_POST ? $_POST["defaults"] : adminer_setting("defaults")), lang('Default values'), "columnShow(this.checked, 5)", "jsonly"); ?>
<?php echo (support("comment")
? checkbox("comments", 1, ($_POST ? $_POST["comments"] : adminer_setting("comments")), lang('Comment'), "editingCommentsClick(this, true);", "jsonly")
. ' <input name="Comment" value="' . h($row["Comment"]) . '" data-maxlength="' . (min_version(5.5) ? 2048 : 60) . '">'
<?php
$comments = ($_POST ? $_POST["comments"] : adminer_setting("comments"));
echo (support("comment")
? checkbox("comments", 1, $comments, lang('Comment'), "editingCommentsClick(this, true);", "jsonly")
. ' ' . (preg_match('~\n~', $row["Comment"])
? "<textarea name='Comment' rows='2' cols='20'" . ($comments ? "" : " class='hidden'") . ">" . h($row["Comment"]) . "</textarea>"
: '<input name="Comment" value="' . h($row["Comment"]) . '" data-maxlength="' . (min_version(5.5) ? 2048 : 60) . '"' . ($comments ? "" : " class='hidden'") . '>'
)
: '')
; ?>
;
?>
<p>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php } ?>

View File

@@ -83,7 +83,7 @@ if ($adminer->homepage()) {
$tables = 0;
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);
echo '<tr' . odd() . '><td>' . checkbox(($view ? "views[]" : "tables[]"), $name, in_array($name, $tables_views, true), "", "", "", $id);
echo '<th>' . (support("table") || support("indexes") ? "<a href='" . h(ME) . "table=" . urlencode($name) . "' title='" . lang('Show structure') . "' id='$id'>" . h($name) . '</a>' : h($name));

View File

@@ -2,12 +2,11 @@
$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;
var $extension = "JSON", $server_info, $errno, $error, $_url, $_db;
/** Performs query
* @param string
@@ -28,7 +27,7 @@ if (isset($_GET["elastic"])) {
return $file;
}
if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) {
$this->error = $file;
$this->error = lang('Invalid credentials.') . " $http_response_header[0]";
return false;
}
$return = json_decode($file, true);
@@ -284,6 +283,11 @@ if (isset($_GET["elastic"])) {
function tables_list() {
global $connection;
if (min_version(6)) {
return array('_doc' => 'table');
}
$return = $connection->query('_mapping');
if ($return) {
$return = array_fill_keys(array_keys($return[$connection->_db]["mappings"]), 'table');
@@ -339,25 +343,35 @@ if (isset($_GET["elastic"])) {
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'];
$mappings = array();
if (min_version(6)) {
$result = $connection->query("_mapping");
if ($result) {
$mappings = $result[$connection->_db]['mappings']['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"]);
}
} else {
$result = $connection->query("$table/_mapping");
if ($result) {
$mappings = $result[$table]['properties'];
if (!$mappings) {
$mappings = $result[$connection->_db]['mappings'][$table]['properties'];
}
}
}
$return = array();
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"]);
}
}
}
@@ -446,20 +460,27 @@ if (isset($_GET["elastic"])) {
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);
function driver_config() {
$types = array();
$structured_types = array();
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);
}
return array(
'possible_drivers' => array("json + allow_url_fopen"),
'jush' => "elastic",
'operators' => array("=", "query"),
'functions' => array(),
'grouping' => array(),
'edit_functions' => array(array("json")),
'types' => $types,
'structured_types' => $structured_types,
);
}
}

View File

@@ -1,8 +1,7 @@
<?php
$drivers["mongo"] = "MongoDB";
$drivers["mongo"] = "MongoDB (alpha)";
if (isset($_GET["mongo"])) {
$possible_drivers = array("mongo", "mongodb");
define("DRIVER", "mongo");
if (class_exists('MongoDB')) {
@@ -10,7 +9,20 @@ if (isset($_GET["mongo"])) {
var $extension = "Mongo", $server_info = MongoClient::VERSION, $error, $last_id, $_link, $_db;
function connect($uri, $options) {
return @new MongoClient($uri, $options);
try {
$this->_link = new MongoClient($uri, $options);
if ($options["password"] != "") {
$options["password"] = "";
try {
new MongoClient($uri, $options);
$this->error = lang('Database does not support password.');
} catch (Exception $e) {
// this is what we want
}
}
} catch (Exception $e) {
$this->error = $e->getMessage();
}
}
function query($query) {
@@ -30,7 +42,6 @@ if (isset($_GET["mongo"])) {
function quote($string) {
return $string;
}
}
class Min_Result {
@@ -44,10 +55,10 @@ if (isset($_GET["mongo"])) {
$this->_charset[$key] = 63;
}
$row[$key] =
(is_a($val, 'MongoId') ? 'ObjectId("' . strval($val) . '")' :
(is_a($val, 'MongoId') ? "ObjectId(\"$val\")" :
(is_a($val, 'MongoDate') ? gmdate("Y-m-d H:i:s", $val->sec) . " GMT" :
(is_a($val, 'MongoBinData') ? $val->bin : //! allow downloading
(is_a($val, 'MongoRegex') ? strval($val) :
(is_a($val, 'MongoRegex') ? "$val" :
(is_object($val) ? get_class($val) : // MongoMinKey, MongoMaxKey
$val
)))));
@@ -198,14 +209,36 @@ if (isset($_GET["mongo"])) {
} elseif (class_exists('MongoDB\Driver\Manager')) {
class Min_DB {
var $extension = "MongoDB", $server_info = MONGODB_VERSION, $error, $last_id;
var $extension = "MongoDB", $server_info = MONGODB_VERSION, $affected_rows, $error, $last_id;
/** @var MongoDB\Driver\Manager */
var $_link;
var $_db, $_db_name;
function connect($uri, $options) {
$class = 'MongoDB\Driver\Manager';
return new $class($uri, $options);
$this->_link = new $class($uri, $options);
$this->executeCommand('admin', array('ping' => 1));
}
function executeCommand($db, $command) {
$class = 'MongoDB\Driver\Command';
try {
return $this->_link->executeCommand($db, new $class($command));
} catch (Exception $e) {
$this->error = $e->getMessage();
return array();
}
}
function executeBulkWrite($namespace, $bulk, $counter) {
try {
$results = $this->_link->executeBulkWrite($namespace, $bulk);
$this->affected_rows = $results->$counter();
return true;
} catch (Exception $e) {
$this->error = $e->getMessage();
return false;
}
}
function query($query) {
@@ -220,7 +253,6 @@ if (isset($_GET["mongo"])) {
function quote($string) {
return $string;
}
}
class Min_Result {
@@ -234,13 +266,13 @@ if (isset($_GET["mongo"])) {
$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
)))));
(is_a($val, 'MongoDB\BSON\ObjectID') ? 'MongoDB\BSON\ObjectID("' . "$val\")" :
(is_a($val, 'MongoDB\BSON\UTCDatetime') ? $val->toDateTime()->format('Y-m-d H:i:s') :
(is_a($val, 'MongoDB\BSON\Binary') ? $val->getData() : //! allow downloading
(is_a($val, 'MongoDB\BSON\Regex') ? "$val" :
(is_object($val) || is_array($val) ? json_encode($val, 256) : // 256 = JSON_UNESCAPED_UNICODE
$val // MongoMinKey, MongoMaxKey
)))));
}
$this->_rows[] = $row;
foreach ($row as $key => $val) {
@@ -249,7 +281,7 @@ if (isset($_GET["mongo"])) {
}
}
}
$this->num_rows = $result->count;
$this->num_rows = count($this->_rows);
}
function fetch_assoc() {
@@ -309,9 +341,12 @@ if (isset($_GET["mongo"])) {
$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);
try {
return new Min_Result($connection->_link->executeQuery("$connection->_db_name.$table", new $class($where, array('projection' => $select, 'limit' => $limit, 'skip' => $skip, 'sort' => $sort))));
} catch (Exception $e) {
$connection->error = $e->getMessage();
return false;
}
}
function update($table, $set, $queryWhere, $limit = 0, $separator = "\n") {
@@ -335,9 +370,7 @@ if (isset($_GET["mongo"])) {
$update['$unset'] = $removeFields;
}
$bulk->update($where, $update, array('upsert' => false));
$results = $connection->_link->executeBulkWrite("$db.$table", $bulk);
$connection->affected_rows = $results->getModifiedCount();
return true;
return $connection->executeBulkWrite("$db.$table", $bulk, 'getModifiedCount');
}
function delete($table, $queryWhere, $limit = 0) {
@@ -347,9 +380,7 @@ if (isset($_GET["mongo"])) {
$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;
return $connection->executeBulkWrite("$db.$table", $bulk, 'getDeletedCount');
}
function insert($table, $set) {
@@ -357,24 +388,18 @@ if (isset($_GET["mongo"])) {
$db = $connection->_db_name;
$class = 'MongoDB\Driver\BulkWrite';
$bulk = new $class(array());
if (isset($set['_id']) && empty($set['_id'])) {
if ($set['_id'] == '') {
unset($set['_id']);
}
$bulk->insert($set);
$results = $connection->_link->executeBulkWrite("$db.$table", $bulk);
$connection->affected_rows = $results->getInsertedCount();
return true;
return $connection->executeBulkWrite("$db.$table", $bulk, 'getInsertedCount');
}
}
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 ($connection->executeCommand('admin', array('listDatabases' => 1)) as $dbs) {
foreach ($dbs->databases as $db) {
$return[] = $db->name;
}
@@ -389,11 +414,8 @@ if (isset($_GET["mongo"])) {
function tables_list() {
global $connection;
$class = 'MongoDB\Driver\Command';
$command = new $class(array('listCollections' => 1));
$results = $connection->_link->executeCommand($connection->_db_name, $command);
$collections = array();
foreach ($results as $result) {
foreach ($connection->executeCommand($connection->_db_name, array('listCollections' => 1)) as $result) {
$collections[$result->name] = 'table';
}
return $collections;
@@ -406,10 +428,7 @@ if (isset($_GET["mongo"])) {
function indexes($table, $connection2 = null) {
global $connection;
$return = array();
$class = 'MongoDB\Driver\Command';
$command = new $class(array('listIndexes' => $table));
$results = $connection->_link->executeCommand($connection->_db_name, $command);
foreach ($results as $index) {
foreach ($connection->executeCommand($connection->_db_name, array('listIndexes' => $table)) as $index) {
$descs = array();
$columns = array();
foreach (get_object_vars($index->key) as $column => $type) {
@@ -427,24 +446,26 @@ if (isset($_GET["mongo"])) {
}
function fields($table) {
global $driver;
$fields = fields_from_edit();
if (!count($fields)) {
global $driver;
if (!$fields) {
$result = $driver->select($table, array("*"), null, null, array(), 10);
while ($row = $result->fetch_assoc()) {
foreach ($row as $key => $val) {
$row[$key] = null;
$fields[$key] = array(
"field" => $key,
"type" => "string",
"null" => ($key != $driver->primary),
"auto_increment" => ($key == $driver->primary),
"privileges" => array(
"insert" => 1,
"select" => 1,
"update" => 1,
),
);
if ($result) {
while ($row = $result->fetch_assoc()) {
foreach ($row as $key => $val) {
$row[$key] = null;
$fields[$key] = array(
"field" => $key,
"type" => "string",
"null" => ($key != $driver->primary),
"auto_increment" => ($key == $driver->primary),
"privileges" => array(
"insert" => 1,
"select" => 1,
"update" => 1,
),
);
}
}
}
}
@@ -454,16 +475,12 @@ if (isset($_GET["mongo"])) {
function found_rows($table_status, $where) {
global $connection;
$where = where_to_query($where);
$class = 'MongoDB\Driver\Command';
$command = new $class(array('count' => $table_status['Name'], 'query' => $where));
$results = $connection->_link->executeCommand($connection->_db_name, $command);
$toArray = $results->toArray();
$toArray = $connection->executeCommand($connection->_db_name, array('count' => $table_status['Name'], 'query' => $where))->toArray();
return $toArray[0]->n;
}
function sql_query_where_parser($queryWhere) {
$queryWhere = trim(preg_replace('/WHERE[\s]?[(]?\(?/', '', $queryWhere));
$queryWhere = preg_replace('/\)\)\)$/', ')', $queryWhere);
$queryWhere = preg_replace('~^\sWHERE \(?\(?(.+?)\)?\)?$~', '\1', $queryWhere);
$wheres = explode(' AND ', $queryWhere);
$wheresOr = explode(') OR (', $queryWhere);
$where = array();
@@ -485,10 +502,8 @@ if (isset($_GET["mongo"])) {
if (is_array($where)) {
foreach ($where as $expression) {
list($col, $op, $val) = explode(" ", $expression, 3);
if ($col == "_id") {
$val = str_replace('MongoDB\BSON\ObjectID("', "", $val);
$val = str_replace('")', "", $val);
$class = 'MongoDB\BSON\ObjectID';
if ($col == "_id" && preg_match('~^(MongoDB\\\\BSON\\\\ObjectID)\("(.+)"\)$~', $val, $match)) {
list(, $class, $val) = $match;
$val = new $class($val);
}
if (!in_array($op, $adminer->operators)) {
@@ -560,6 +575,7 @@ if (isset($_GET["mongo"])) {
"(date)>=",
"(date)<=",
);
}
function table($idf) {
@@ -621,21 +637,11 @@ if (isset($_GET["mongo"])) {
if (($auth_source = getenv("MONGO_AUTH_SOURCE"))) {
$options["authSource"] = $auth_source;
}
try {
$connection->_link = $connection->connect("mongodb://$server", $options);
if ($password != "") {
$options["password"] = "";
try {
$connection->connect("mongodb://$server", $options);
return lang('Database does not support password.');
} catch (Exception $ex) {
// this is what we want
}
}
return $connection;
} catch (Exception $ex) {
return $ex->getMessage();
$connection->connect("mongodb://$server", $options);
if ($connection->error) {
return $connection->error;
}
return $connection;
}
function alter_indexes($table, $alter) {
@@ -725,8 +731,15 @@ if (isset($_GET["mongo"])) {
return true;
}
$jush = "mongo";
$functions = array();
$grouping = array();
$edit_functions = array(array("json"));
function driver_config() {
global $operators;
return array(
'possible_drivers' => array("mongo", "mongodb"),
'jush' => "mongo",
'operators' => $operators,
'functions' => array(),
'grouping' => array(),
'edit_functions' => array(array("json")),
);
}
}

View File

@@ -8,7 +8,6 @@
$drivers["mssql"] = "MS SQL (beta)";
if (isset($_GET["mssql"])) {
$possible_drivers = array("SQLSRV", "MSSQL", "PDO_DBLIB");
define("DRIVER", "mssql");
if (extension_loaded("sqlsrv")) {
class Min_DB {
@@ -368,7 +367,7 @@ if (isset($_GET["mssql"])) {
}
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)");
$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();
foreach (get_rows("SELECT c.max_length, c.precision, c.scale, c.name, c.is_nullable, c.is_identity, c.collation_name, t.name type, CAST(d.definition as text) [default]
FROM sys.all_columns c
@@ -495,8 +494,8 @@ WHERE OBJECT_NAME(i.object_id) = " . q($table)
}
foreach ($comments as $key => $val) {
$comment = substr($val, 9); // 9 - strlen(" COMMENT ")
queries("EXEC sp_dropextendedproperty @name = N'MS_Description', @level0type = N'Schema', @level0name = " . q(get_schema()) . ", @level1type = N'Table', @level1name = " . q($name) . ", @level2type = N'Column', @level2name = " . q($key));
queries("EXEC sp_addextendedproperty @name = N'MS_Description', @value = " . $comment . ", @level0type = N'Schema', @level0name = " . q(get_schema()) . ", @level1type = N'Table', @level1name = " . q($name) . ", @level2type = N'Column', @level2name = " . q($key));
queries("EXEC sp_dropextendedproperty @name = N'MS_Description', @level0type = N'Schema', @level0name = " . q(get_schema()) . ", @level1type = N'Table', @level1name = " . q($name) . ", @level2type = N'Column', @level2name = " . q($key));
queries("EXEC sp_addextendedproperty @name = N'MS_Description', @value = " . $comment . ", @level0type = N'Schema', @level0name = " . q(get_schema()) . ", @level1type = N'Table', @level1name = " . q($name) . ", @level2type = N'Column', @level2name = " . q($key));
}
return true;
}
@@ -646,28 +645,35 @@ WHERE sys1.xtype = 'TR' AND sys2.name = " . q($table)
return preg_match('~^(comment|columns|database|drop_col|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);
function driver_config() {
$types = array();
$structured_types = array();
foreach (array( //! use sys.types
lang('Numbers') => array("tinyint" => 3, "smallint" => 5, "int" => 10, "bigint" => 20, "bit" => 1, "decimal" => 0, "real" => 12, "float" => 53, "smallmoney" => 10, "money" => 20),
lang('Date and time') => array("date" => 10, "smalldatetime" => 19, "datetime" => 19, "datetime2" => 19, "time" => 8, "datetimeoffset" => 10),
lang('Strings') => array("char" => 8000, "varchar" => 8000, "text" => 2147483647, "nchar" => 4000, "nvarchar" => 4000, "ntext" => 1073741823),
lang('Binary') => array("binary" => 8000, "varbinary" => 8000, "image" => 2147483647),
) as $key => $val) {
$types += $val;
$structured_types[$key] = array_keys($val);
}
return array(
'possible_drivers' => array("SQLSRV", "MSSQL", "PDO_DBLIB"),
'jush' => "mssql",
'types' => $types,
'structured_types' => $structured_types,
'unsigned' => array(),
'operators' => array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL"),
'functions' => array("len", "lower", "round", "upper"),
'grouping' => array("avg", "count", "count distinct", "max", "min", "sum"),
'edit_functions' => array(
array(
"date|time" => "getdate",
), array(
"int|decimal|real|float|money|datetime" => "+/-",
"char|text" => "+",
)
),
);
}
$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

@@ -2,7 +2,6 @@
$drivers = array("server" => "MySQL") + $drivers;
if (!defined("DRIVER")) {
$possible_drivers = array("MySQLi", "MySQL", "PDO_MySQL");
define("DRIVER", "server"); // server - backwards compatibility
// MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable
if (extension_loaded("mysqli")) {
@@ -267,7 +266,7 @@ if (!defined("DRIVER")) {
}
function query($query, $unbuffered = false) {
$this->pdo->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);
}
}
@@ -547,7 +546,7 @@ if (!defined("DRIVER")) {
"type" => $match[1],
"length" => $match[2],
"unsigned" => ltrim($match[3] . $match[4]),
"default" => ($row["Default"] != "" || preg_match("~char|set~", $match[1]) ? $row["Default"] : null),
"default" => ($row["Default"] != "" || preg_match("~char|set~", $match[1]) ? (preg_match('~text~', $match[1]) ? stripslashes(preg_replace("~^'(.*)'\$~", '\1', $row["Default"])) : $row["Default"]) : null),
"null" => ($row["Null"] == "YES"),
"auto_increment" => ($row["Extra"] == "auto_increment"),
"on_update" => (preg_match('~^on update (.+)~i', $row["Extra"], $match) ? $match[1] : ""), //! available since MySQL 5.1.23
@@ -679,17 +678,17 @@ if (!defined("DRIVER")) {
function rename_database($name, $collation) {
$return = false;
if (create_database($name, $collation)) {
//! move triggers
$rename = array();
$tables = array();
$views = array();
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();
set_session("dbs", null);
$return = (!$tables && !$views) || move_tables($tables, $views, $name);
drop_databases($return ? array(DB) : array());
}
return $return;
}
@@ -798,12 +797,27 @@ if (!defined("DRIVER")) {
* @return bool
*/
function move_tables($tables, $views, $target) {
global $connection;
$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);
}
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
return false;
}
/** Copy tables to other schema
@@ -950,7 +964,7 @@ if (!defined("DRIVER")) {
* @return Min_Result
*/
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
@@ -1085,7 +1099,8 @@ if (!defined("DRIVER")) {
$return = "CONV($return, 2, 10) + 0";
}
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;
}
@@ -1098,47 +1113,67 @@ if (!defined("DRIVER")) {
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);
}
/** Kill a process
* @param int
* @return bool
*/
function kill_process($val) {
return queries("KILL " . number($val));
}
/** Return query to get connection ID
* @return string
*/
function connection_id(){
return "SELECT CONNECTION_ID()";
}
/** Get maximum number of connections
* @return int
*/
function max_connections() {
global $connection;
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);
/** Get driver config
* @return array array('possible_drivers' => , 'jush' => , 'types' => , 'structured_types' => , 'unsigned' => , 'operators' => , 'functions' => , 'grouping' => , 'edit_functions' => )
*/
function driver_config() {
$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);
}
return array(
'possible_drivers' => array("MySQLi", "MySQL", "PDO_MySQL"),
'jush' => "sql", ///< @var string JUSH identifier
'types' => $types,
'structured_types' => $structured_types,
'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",
)
),
);
}
$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

@@ -2,11 +2,11 @@
$drivers["oracle"] = "Oracle (beta)";
if (isset($_GET["oracle"])) {
$possible_drivers = array("OCI8", "PDO_OCI");
define("DRIVER", "oracle");
if (extension_loaded("oci8")) {
class Min_DB {
var $extension = "oci8", $_link, $_result, $server_info, $affected_rows, $errno, $error;
var $_current_db;
function _error($errno, $error) {
if (ini_bool("html_errors")) {
@@ -32,6 +32,7 @@ if (isset($_GET["oracle"])) {
}
function select_db($database) {
$this->_current_db = $database;
return true;
}
@@ -52,6 +53,7 @@ if (isset($_GET["oracle"])) {
return new Min_Result($result);
}
$this->affected_rows = oci_num_rows($result);
oci_free_statement($result);
}
return $return;
}
@@ -119,6 +121,7 @@ if (isset($_GET["oracle"])) {
} elseif (extension_loaded("pdo_oci")) {
class Min_DB extends Min_PDO {
var $extension = "PDO_OCI";
var $_current_db;
function connect($server, $username, $password) {
$this->dsn("oci:dbname=//$server;charset=AL32UTF8", $username, $password);
@@ -126,6 +129,7 @@ if (isset($_GET["oracle"])) {
}
function select_db($database) {
$this->_current_db = $database;
return true;
}
}
@@ -142,6 +146,25 @@ if (isset($_GET["oracle"])) {
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;
}
}
@@ -165,7 +188,7 @@ if (isset($_GET["oracle"])) {
}
function get_databases() {
return get_vals("SELECT tablespace_name FROM user_tablespaces");
return get_vals("SELECT tablespace_name FROM user_tablespaces ORDER BY 1");
}
function limit($query, $where, $limit, $offset = 0, $separator = " ") {
@@ -193,22 +216,51 @@ if (isset($_GET["oracle"])) {
return $connection->result("SELECT USER FROM DUAL");
}
function get_current_db() {
global $connection;
$db = $connection->_current_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 ? $owner : "rownum < 0") . ")";
}
function tables_list() {
return get_key_vals("SELECT table_name, 'table' FROM all_tables WHERE tablespace_name = " . q(DB) . "
UNION SELECT view_name, 'view' FROM user_views
$view = views_table("view_name");
$owner = where_owner(" AND ");
return get_key_vals("SELECT table_name, 'table' FROM all_tables WHERE tablespace_name = " . q(DB) . "$owner
UNION SELECT view_name, 'view' FROM $view
ORDER BY 1"
); //! views don't have schema
}
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 = "") {
$return = array();
$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" : "") . "
UNION SELECT view_name, 'view', 0, 0 FROM user_views" . ($name != "" ? " WHERE view_name = $search" : "") . "
$db = get_current_db();
$view = views_table("view_name");
$owner = where_owner(" AND ");
foreach (get_rows('SELECT table_name "Name", \'table\' "Engine", avg_row_len * num_rows "Data_length", num_rows "Rows" FROM all_tables WHERE tablespace_name = ' . q($db) . $owner . ($name != "" ? " AND table_name = $search" : "") . "
UNION SELECT view_name, 'view', 0, 0 FROM $view" . ($name != "" ? " WHERE view_name = $search" : "") . "
ORDER BY 1"
) as $row) {
if ($name != "") {
@@ -229,11 +281,12 @@ ORDER BY 1"
function fields($table) {
$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"];
$length = "$row[DATA_PRECISION],$row[DATA_SCALE]";
if ($length == ",") {
$length = $row["DATA_LENGTH"];
$length = $row["CHAR_COL_DECL_LENGTH"];
} //! int
$return[$row["COLUMN_NAME"]] = array(
"field" => $row["COLUMN_NAME"],
@@ -254,22 +307,27 @@ ORDER BY 1"
function indexes($table, $connection2 = null) {
$return = array();
foreach (get_rows("SELECT uic.*, uc.constraint_type
FROM user_ind_columns uic
LEFT JOIN user_constraints uc ON uic.index_name = uc.constraint_name AND uic.table_name = uc.table_name
WHERE uic.table_name = " . q($table) . "
ORDER BY uc.constraint_type, uic.column_position", $connection2) as $row) {
$owner = where_owner(" AND ", "aic.table_owner");
foreach (get_rows("SELECT aic.*, ac.constraint_type, atc.data_default
FROM all_ind_columns aic
LEFT JOIN all_constraints ac ON aic.index_name = ac.constraint_name AND aic.table_name = ac.table_name AND aic.index_owner = ac.owner
LEFT JOIN all_tab_cols atc ON aic.column_name = atc.column_name AND aic.table_name = atc.table_name AND aic.index_owner = atc.owner
WHERE aic.table_name = " . q($table) . "$owner
ORDER BY ac.constraint_type, aic.column_position", $connection2) as $row) {
$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]["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]["descs"][] = ($row["DESCEND"] ? '1' : null);
$return[$index_name]["descs"][] = ($row["DESCEND"] && $row["DESCEND"] == "DESC" ? '1' : null);
}
return $return;
}
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);
}
@@ -294,13 +352,25 @@ ORDER BY uc.constraint_type, uic.column_position", $connection2) as $row) {
function found_rows($table_status, $where) {
}
function auto_increment() {
return "";
}
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
$alter = $drop = array();
$orig_fields = ($table ? fields($table) : array());
foreach ($fields as $field) {
$val = $field[1];
if ($val && $field[0] != "" && idf_escape($field[0]) != $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) {
$alter[] = ($table != "" ? ($field[0] != "" ? "MODIFY (" : "ADD (") : " ") . implode($val) . ($table != "" ? ")" : ""); //! error with name change only
} else {
@@ -316,6 +386,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) {
$return = array();
$query = "SELECT c_list.CONSTRAINT_NAME as NAME,
@@ -359,7 +458,8 @@ AND c_src.TABLE_NAME = " . q($table);
}
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 ? $return : get_vals("SELECT DISTINCT owner FROM all_tables WHERE tablespace_name = " . q(DB) . " ORDER BY 1"));
}
function get_schema() {
@@ -401,33 +501,40 @@ ORDER BY PROCESS
}
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);
function driver_config() {
$types = array();
$structured_types = array();
foreach (array(
lang('Numbers') => array("number" => 38, "binary_float" => 12, "binary_double" => 21),
lang('Date and time') => array("date" => 10, "timestamp" => 29, "interval year" => 12, "interval day" => 28), //! year(), day() to second()
lang('Strings') => array("char" => 2000, "varchar2" => 4000, "nchar" => 2000, "nvarchar2" => 4000, "clob" => 4294967295, "nclob" => 4294967295),
lang('Binary') => array("raw" => 2000, "long raw" => 2147483648, "blob" => 4294967295, "bfile" => 4294967296),
) as $key => $val) {
$types += $val;
$structured_types[$key] = array_keys($val);
}
return array(
'possible_drivers' => array("OCI8", "PDO_OCI"),
'jush' => "oracle",
'types' => $types,
'structured_types' => $structured_types,
'unsigned' => array(),
'operators' => array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL"),
'functions' => array("length", "lower", "round", "upper"),
'grouping' => array("avg", "count", "count distinct", "max", "min", "sum"),
'edit_functions' => array(
array( //! no parentheses
"date" => "current_date",
"timestamp" => "current_timestamp",
), array(
"number|float|double" => "+/-",
"date|timestamp" => "+ interval/- interval",
"char|clob" => "||",
)
),
);
}
$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

@@ -2,7 +2,6 @@
$drivers["pgsql"] = "PostgreSQL";
if (isset($_GET["pgsql"])) {
$possible_drivers = array("PgSQL", "PDO_PgSQL");
define("DRIVER", "pgsql");
if (extension_loaded("pgsql")) {
class Min_DB {
@@ -41,7 +40,7 @@ if (isset($_GET["pgsql"])) {
}
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) {
@@ -150,8 +149,7 @@ if (isset($_GET["pgsql"])) {
function connect($server, $username, $password) {
global $adminer;
$db = $adminer->database();
$string = "pgsql:host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' options='-c client_encoding=utf8'";
$this->dsn("$string dbname='" . ($db != "" ? addcslashes($db, "'\\") : "postgres") . "'", $username, $password);
$this->dsn("pgsql:host='" . str_replace(":", "' port='", addcslashes($server, "'\\")) . "' client_encoding=utf8 dbname='" . ($db != "" ? addcslashes($db, "'\\") : "postgres") . "'", $username, $password); //! client_encoding is supported since 9.1 but we can't yet use min_version here
//! connect without DB in case of an error
return true;
}
@@ -286,13 +284,13 @@ if (isset($_GET["pgsql"])) {
function limit1($table, $query, $where, $separator = "\n") {
return (preg_match('~^INTO~', $query)
? 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) {
global $connection;
return $connection->result("SHOW LC_COLLATE"); //! respect $db
return $connection->result("SELECT datcollate FROM pg_database WHERE datname = " . q($db));
}
function engines() {
@@ -306,7 +304,7 @@ if (isset($_GET["pgsql"])) {
function tables_list() {
$query = "SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = current_schema()";
if (support('materializedview')) {
if (support('materializedview')) { // ' - support("materializedview") could be removed by compile.php
$query .= "
UNION ALL
SELECT matviewname, 'MATERIALIZED VIEW'
@@ -327,7 +325,7 @@ ORDER BY 1";
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
FROM pg_class c
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")
) as $row) { //! Index_length, Auto_increment
$return[$row["Name"]] = $row;
@@ -350,9 +348,7 @@ WHERE relkind IN ('r', 'm', 'v', 'f')
'timestamp with time zone' => 'timestamptz',
);
$identity_column = min_version(10) ? "(a.attidentity = 'd')::int" : '0';
foreach (get_rows("SELECT a.attname AS field, format_type(a.atttypid, a.atttypmod) AS full_type, pg_get_expr(d.adbin, d.adrelid) AS default, a.attnotnull::int, col_description(c.oid, a.attnum) AS comment, $identity_column AS identity
foreach (get_rows("SELECT a.attname AS field, format_type(a.atttypid, a.atttypmod) AS full_type, pg_get_expr(d.adbin, d.adrelid) AS default, a.attnotnull::int, col_description(c.oid, a.attnum) AS comment" . (min_version(10) ? ", a.attidentity" : "") . "
FROM pg_class c
JOIN pg_namespace n ON c.relnamespace = n.oid
JOIN pg_attribute a ON c.oid = a.attrelid
@@ -375,14 +371,14 @@ ORDER BY a.attnum"
$row["type"] = $type;
$row["full_type"] = $row["type"] . $length . $addon . $array;
}
if ($row['identity']) {
$row['default'] = 'GENERATED BY DEFAULT AS IDENTITY';
if (in_array($row['attidentity'], array('a', 'd'))) {
$row['default'] = 'GENERATED ' . ($row['attidentity'] == 'd' ? 'BY DEFAULT' : 'ALWAYS') . ' AS IDENTITY';
}
$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);
if (preg_match('~(.+)::[^)]+(.*)~', $row["default"], $match)) {
$row["default"] = ($match[1] == "NULL" ? null : (($match[1][0] == "'" ? idf_unescape($match[1]) : $match[1]) . $match[2]));
if (preg_match('~(.+)::[^,)]+(.*)~', $row["default"], $match)) {
$row["default"] = ($match[1] == "NULL" ? null : idf_unescape($match[1]) . $match[2]);
}
$return[$row["field"]] = $row;
}
@@ -397,7 +393,7 @@ ORDER BY a.attnum"
$return = array();
$table_oid = $connection2->result("SELECT oid FROM pg_class WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = current_schema()) AND relname = " . q($table));
$columns = get_key_vals("SELECT attnum, attname FROM pg_attribute WHERE attrelid = $table_oid AND attnum > 0", $connection2);
foreach (get_rows("SELECT relname, indisunique::int, indisprimary::int, indkey, indoption , (indpred IS NOT NULL)::int as indispartial FROM pg_index i, pg_class ci WHERE i.indrelid = $table_oid AND ci.oid = i.indexrelid", $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", $connection2) as $row) {
$relname = $row["relname"];
$return[$relname]["type"] = ($row["indispartial"] ? "INDEX" : ($row["indisprimary"] ? "PRIMARY" : ($row["indisunique"] ? "UNIQUE" : "INDEX")));
$return[$relname]["columns"] = array();
@@ -422,12 +418,12 @@ WHERE conrelid = (SELECT pc.oid FROM pg_class AS pc INNER JOIN pg_namespace AS p
AND contype = 'f'::char
ORDER BY conkey, conname") as $row) {
if (preg_match('~FOREIGN KEY\s*\((.+)\)\s*REFERENCES (.+)\((.+)\)(.*)$~iA', $row['definition'], $match)) {
$row['source'] = array_map('trim', explode(',', $match[1]));
$row['source'] = array_map('idf_unescape', array_map('trim', explode(',', $match[1])));
if (preg_match('~^(("([^"]|"")+"|[^"]+)\.)?"?("([^"]|"")+"|[^"]+)$~', $match[2], $match2)) {
$row['ns'] = str_replace('""', '"', preg_replace('~^"(.+)"$~', '\1', $match2[2]));
$row['table'] = str_replace('""', '"', preg_replace('~^"(.+)"$~', '\1', $match2[4]));
$row['ns'] = idf_unescape($match2[2]);
$row['table'] = idf_unescape($match2[4]);
}
$row['target'] = array_map('trim', explode(',', $match[3]));
$row['target'] = array_map('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_update'] = (preg_match("~ON UPDATE ($on_actions)~", $match[4], $match2) ? $match2[1] : 'NO ACTION');
$return[$row['conname']] = $row;
@@ -436,9 +432,26 @@ ORDER BY conkey, conname") as $row) {
return $return;
}
function constraints($table) {
global $on_actions;
$return = array();
foreach (get_rows("SELECT conname, consrc
FROM pg_catalog.pg_constraint
INNER JOIN pg_catalog.pg_namespace ON pg_constraint.connamespace = pg_namespace.oid
INNER JOIN pg_catalog.pg_class ON pg_constraint.conrelid = pg_class.oid AND pg_constraint.connamespace = pg_class.relnamespace
WHERE pg_constraint.contype = 'c'
AND conrelid != 0 -- handle only CONSTRAINTs here, not TYPES
AND nspname = current_schema()
AND relname = " . q($table) . "
ORDER BY connamespace, conname") as $row) {
$return[$row['conname']] = $row['consrc'];
}
return $return;
}
function view($name) {
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() {
@@ -492,11 +505,14 @@ ORDER BY conkey, conname") as $row) {
} else {
$val5 = $val[5];
unset($val[5]);
if (isset($val[6]) && $field[0] == "") { // auto_increment
$val[1] = ($val[1] == "bigint" ? " big" : " ") . "serial";
}
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);
if (isset($val[6])) {
$alter[] = ($table != "" ? "ADD" : " ") . " PRIMARY KEY ($val[0])";
}
} else {
if ($column != $val[0]) {
$queries[] = "ALTER TABLE " . table($name) . " RENAME $column TO $val[0]";
@@ -518,7 +534,7 @@ ORDER BY conkey, conname") as $row) {
} elseif ($alter) {
array_unshift($queries, "ALTER TABLE " . table($table) . "\n" . implode(",\n", $alter));
}
if ($table != "" || $comment != "") {
if ($comment !== null) {
$queries[] = "COMMENT ON TABLE " . table($name) . " IS " . q($comment);
}
if ($auto_increment != "") {
@@ -592,21 +608,34 @@ ORDER BY conkey, conname") as $row) {
return true;
}
function trigger($name, $table = null) {
function trigger($name, $table) {
if ($name == "") {
return array("Statement" => "EXECUTE PROCEDURE ()");
}
if ($table === null) {
$table = $_GET['trigger'];
$columns = array();
$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 reset($rows);
$return = array();
foreach (get_rows('SELECT trigger_name AS "Trigger", action_timing AS "Timing", event_manipulation AS "Event", \'FOR EACH \' || action_orientation AS "Type", action_statement AS "Statement" FROM information_schema.triggers ' . "$where ORDER BY event_manipulation DESC") as $row) {
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) {
$return = array();
foreach (get_rows("SELECT * FROM information_schema.triggers WHERE event_object_table = " . q($table)) as $row) {
$return[$row["trigger_name"]] = array($row["action_timing"], $row["event_manipulation"]);
foreach (get_rows("SELECT * FROM information_schema.triggers WHERE trigger_schema = current_schema() AND event_object_table = " . q($table)) as $row) {
$trigger = trigger($row["trigger_name"], $table);
$return[$trigger["Trigger"]] = array($trigger["Timing"], $trigger["Event"]);
}
return $return;
}
@@ -614,7 +643,7 @@ ORDER BY conkey, conname") as $row) {
function trigger_options() {
return array(
"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"),
);
}
@@ -704,6 +733,23 @@ AND typelem = 0"
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) {
global $connection;
$return = '';
@@ -718,8 +764,7 @@ AND typelem = 0"
$fields = fields($table);
$indexes = indexes($table);
ksort($indexes);
$fkeys = foreign_keys($table);
ksort($fkeys);
$constraints = constraints($table);
if (!$status || empty($fields)) {
return false;
@@ -742,7 +787,7 @@ AND typelem = 0"
: "SELECT * FROM $sequence_name"
));
$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]" : "") . " CACHE $sq[cache_value];";
}
}
@@ -759,9 +804,8 @@ AND typelem = 0"
}
}
// foreign keys
foreach ($fkeys as $fkey_name => $fkey) {
$return_parts[] = "CONSTRAINT " . idf_escape($fkey_name) . " $fkey[definition] " . ($fkey['deferrable'] ? 'DEFERRABLE' : 'NOT DEFERRABLE');
foreach ($constraints as $conname => $consrc) {
$return_parts[] = "CONSTRAINT " . idf_escape($conname) . " CHECK $consrc";
}
$return .= implode(",\n ", $return_parts) . "\n) WITH (oids = " . ($status['Oid'] ? 'true' : 'false') . ");";
@@ -800,7 +844,7 @@ AND typelem = 0"
$return = "";
foreach (triggers($table) as $trg_id => $trg) {
$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;
}
@@ -845,32 +889,39 @@ AND typelem = 0"
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);
function driver_config() {
$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);
}
return array(
'possible_drivers' => array("PgSQL", "PDO_PgSQL"),
'jush' => "pgsql",
'types' => $types,
'structured_types' => $structured_types,
'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" => "||",
)
),
);
}
$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

@@ -3,7 +3,6 @@ $drivers["sqlite"] = "SQLite 3";
$drivers["sqlite2"] = "SQLite 2";
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"])) {
@@ -141,7 +140,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
}
$return = array();
foreach ($row as $key => $val) {
$return[($key[0] == '"' ? idf_unescape($key) : $key)] = $val;
$return[idf_unescape($key)] = $val;
}
return $return;
}
@@ -191,6 +190,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
parent::__construct($filename);
$this->query("PRAGMA foreign_keys = 1");
$this->query("PRAGMA busy_timeout = 500");
return true;
}
return false;
@@ -676,7 +676,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return array(
"Timing" => strtoupper($match[1]),
"Event" => strtoupper($match[2]) . ($of ? " OF" : ""),
"Of" => ($of[0] == '`' || $of[0] == '"' ? idf_unescape($of) : $of),
"Of" => idf_unescape($of),
"Trigger" => $name,
"Statement" => $match[4],
);
@@ -784,20 +784,26 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return preg_match('~^(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" => "||",
)
);
function driver_config() {
$types = array("integer" => 0, "real" => 0, "numeric" => 0, "text" => 0, "blob" => 0);
return array(
'possible_drivers' => array((isset($_GET["sqlite"]) ? "SQLite3" : "SQLite"), "PDO_SQLite"),
'jush' => "sqlite",
'types' => $types,
'structured_types' => array_keys($types),
'unsigned' => array(),
'operators' => array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "NOT IN", "IS NOT NULL", "SQL"), // REGEXP can be user defined function
'functions' => array("hex", "length", "lower", "round", "unixepoch", "upper"),
'grouping' => array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"),
'edit_functions' => array(
array(
// "text" => "date('now')/time('now')/datetime('now')",
), array(
"integer|real|numeric" => "+/-",
// "text" => "date/time/datetime",
"text" => "||",
)
),
);
}
}

View File

@@ -14,7 +14,7 @@ if ($_POST && !$error) {
$is_sql = preg_match('~sql~', $_POST["format"]);
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") {
echo "SET NAMES utf8;
SET time_zone = '+00:00';
@@ -22,7 +22,8 @@ SET foreign_key_checks = 0;
" . ($_POST["data_style"] ? "SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
" : "") . "
";
$connection->query("SET time_zone = '+00:00';");
$connection->query("SET time_zone = '+00:00'");
$connection->query("SET sql_mode = ''");
}
}
@@ -105,6 +106,16 @@ SET foreign_key_checks = 0;
}
}
// add FKs after creating tables (except in MySQL which uses SET FOREIGN_KEY_CHECKS=0)
if (function_exists('foreign_keys_sql')) {
foreach (table_status('', true) as $name => $table_status) {
$table = (DB == "" || in_array($name, (array) $_POST["tables"]));
if ($table && !is_view($table_status)) {
echo foreign_keys_sql($name);
}
}
}
foreach ($views as $view) {
$adminer->dumpTable($view, $_POST["table_style"], 1);
}

View File

@@ -60,7 +60,7 @@ if ($row["ns"] != "") {
set_schema($row["ns"]);
}
$referencable = array_keys(array_filter(table_status('', true), '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();";
echo "<p>" . lang('Target table') . ": " . html_select("table", $referencable, $row["table"], $onchange) . "\n";
if ($jush == "pgsql") {

View File

@@ -480,7 +480,7 @@ class Adminer {
echo "</script>\n";
echo "</div></fieldset>\n";
}
/** Print command box in select
* @return bool whether to print default commands
*/
@@ -563,6 +563,7 @@ class Adminer {
foreach ($fields as $name => $field) {
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('~date|timestamp~', $field["type"]) || preg_match('~^\d+-\d+-\d+~', $val["val"]))
) {
$cols[] = $prefix . $driver->convertSearch(idf_escape($name), $val, $field) . $cond;
}
@@ -658,6 +659,16 @@ class Adminer {
;
}
/** 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
* @param array single field from fields()
* @return array
@@ -665,19 +676,20 @@ class Adminer {
function editFunctions($field) {
global $edit_functions;
$return = ($field["null"] ? "NULL/" : "");
$update = isset($_GET["select"]) || where($_GET);
foreach ($edit_functions as $key => $functions) {
if (!$key || (!isset($_GET["call"]) && (isset($_GET["select"]) || where($_GET)))) { // relative functions
if (!$key || (!isset($_GET["call"]) && $update)) { // relative functions
foreach ($functions as $pattern => $val) {
if (!$pattern || preg_match("~$pattern~", $field["type"])) {
$return .= "/$val";
}
}
if ($key && !preg_match('~set|blob|bytea|raw|file~', $field["type"])) {
$return .= "/SQL";
}
}
if ($key && !preg_match('~set|blob|bytea|raw|file|bool~', $field["type"])) {
$return .= "/SQL";
}
}
if ($field["auto_increment"] && !isset($_GET["select"]) && !where($_GET)) {
if ($field["auto_increment"] && !$update) {
$return = lang('Auto Increment');
}
return explode("/", $return);
@@ -944,6 +956,7 @@ class Adminer {
echo "<ul id='logins'>\n$output</ul>\n" . script("mixin(qs('#logins'), {onmouseover: menuOver, onmouseout: menuOut});");
}
} else {
$tables = array();
if ($_GET["ns"] !== "" && !$missing && DB != "") {
$connection->select_db(DB);
$tables = table_status('', true);
@@ -998,7 +1011,7 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
function databasesPrint($missing) {
global $adminer, $connection;
$databases = $this->databases();
if ($databases && !in_array(DB, $databases)) {
if (DB && $databases && !in_array(DB, $databases)) {
array_unshift($databases, DB);
}
?>
@@ -1012,8 +1025,8 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
: "<input name='db' value='" . h(DB) . "' autocapitalize='off'>\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";
if ($_GET["ns"] != "") {
set_schema($_GET["ns"]);
@@ -1038,7 +1051,10 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
foreach ($tables as $table => $status) {
$name = $this->tableName($status);
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")
? '<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"))
@@ -1051,8 +1067,3 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
}
}
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
if ($adminer->operators === null) {
$adminer->operators = $operators;
}

View File

@@ -41,7 +41,7 @@ function add_invalid_login() {
function check_invalid_login() {
global $adminer;
$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
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)));
@@ -73,18 +73,12 @@ if ($auth) {
redirect(auth_url($vendor, $server, $username, $db));
}
} elseif ($_POST["logout"]) {
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) {
set_session($key, null);
}
unset_permanent();
redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.') . ' ' . lang('Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.'));
} elseif ($_POST["logout"] && (!$has_token || verify_token())) {
foreach (array("pwds", "db", "dbs", "queries") as $key) {
set_session($key, null);
}
unset_permanent();
redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.') . ' ' . lang('Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.'));
} elseif ($permanent && !$_SESSION["pwds"]) {
session_regenerate_id();
@@ -125,7 +119,7 @@ function auth_error($error) {
$password = get_password();
if ($password !== null) {
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);
}
@@ -162,7 +156,7 @@ stop_session(true);
if (isset($_GET["username"]) && is_string(get_password())) {
list($host, $port) = explode(":", SERVER, 2);
if (+$port && ($port < 1024 || $port > 65535)) {
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.'));
}
check_invalid_login();
@@ -176,6 +170,12 @@ if (!is_object($connection) || ($login = $adminer->login($_GET["username"], get_
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"]) {
$_POST["token"] = $token; // reset token after explicit login
}

View File

@@ -1,5 +1,10 @@
<?php
error_reporting(6133); // errors
function adminer_errors($errno, $errstr) {
return !!preg_match('~^(Trying to access array offset on value of type null|Undefined array key)~', $errstr);
}
error_reporting(6135); // errors and warnings
set_error_handler('adminer_errors', E_WARNING);
include "../adminer/include/coverage.inc.php";
@@ -75,13 +80,26 @@ include "../adminer/drivers/sqlite.inc.php";
include "../adminer/drivers/pgsql.inc.php";
include "../adminer/drivers/oracle.inc.php";
include "../adminer/drivers/mssql.inc.php";
include "../adminer/drivers/firebird.inc.php";
include "../adminer/drivers/simpledb.inc.php";
include "../adminer/drivers/mongo.inc.php";
include "../adminer/drivers/elastic.inc.php";
include "../adminer/drivers/clickhouse.inc.php";
include "./include/adminer.inc.php";
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver
$config = driver_config();
$possible_drivers = $config['possible_drivers'];
$jush = $config['jush'];
$types = $config['types'];
$structured_types = $config['structured_types'];
$unsigned = $config['unsigned'];
$operators = $config['operators'];
$functions = $config['functions'];
$grouping = $config['grouping'];
$edit_functions = $config['edit_functions'];
if ($adminer->operators === null) {
$adminer->operators = $operators;
}
define("SERVER", $_GET[DRIVER]); // read from pgsql=localhost
define("DB", $_GET["db"]); // for the sake of speed and size
define("ME", preg_replace('~\?.*~', '', relative_uri()) . '?'
@@ -92,7 +110,6 @@ define("ME", preg_replace('~\?.*~', '', relative_uri()) . '?'
);
include "../adminer/include/version.inc.php";
include "./include/adminer.inc.php";
include "../adminer/include/design.inc.php";
include "../adminer/include/xxtea.inc.php";
include "../adminer/include/auth.inc.php";

View File

@@ -89,14 +89,16 @@ if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET
exit;
}
if (support("scheme") && DB != "" && $_GET["ns"] !== "") {
if (!isset($_GET["ns"])) {
redirect(preg_replace('~ns=[^&]*&~', '', ME) . "ns=" . get_schema());
}
if (!set_schema($_GET["ns"])) {
header("HTTP/1.1 404 Not Found");
page_header(lang('Schema') . ": " . h($_GET["ns"]), lang('Invalid schema.'), true);
page_footer("ns");
exit;
if (support("scheme")) {
if (DB != "" && $_GET["ns"] !== "") {
if (!isset($_GET["ns"])) {
redirect(preg_replace('~ns=[^&]*&~', '', ME) . "ns=" . get_schema());
}
if (!set_schema($_GET["ns"])) {
header("HTTP/1.1 404 Not Found");
page_header(lang('Schema') . ": " . h($_GET["ns"]), lang('Invalid schema.'), true);
page_footer("ns");
exit;
}
}
}

View File

@@ -75,7 +75,7 @@ var thousandsSeparator = '<?php echo js_escape(lang(',')); ?>';
if ($breadcrumb === false) {
echo "$server\n";
} 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> &raquo; ";
if ($_GET["ns"] != "" || (DB != "" && is_array($breadcrumb))) {
echo '<a href="' . h($link . "&db=" . urlencode(DB) . (support("scheme") ? "&ns=" : "")) . '">' . h(DB) . '</a> &raquo; ';
}

View File

@@ -1,4 +1,15 @@
<?php
$drivers = array();
/** Add a driver
* @param string
* @param string
* @return null
*/
function add_driver($id, $name) {
global $drivers;
$drivers[$id] = $name;
}
/*abstract*/ class Min_SQL {
var $_conn;

View File

@@ -61,6 +61,20 @@ function select($result, $connection2 = null, $orgtables = array(), $limit = 0)
}
echo "<tr" . odd() . ">";
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) {
$val = "<i>NULL</i>";
} elseif ($blobs[$key] && !is_utf8($val)) {
@@ -71,17 +85,8 @@ function select($result, $connection2 = null, $orgtables = array(), $limit = 0)
$val = "<code>$val</code>";
}
}
if (isset($links[$key]) && !$columns[$links[$key]]) {
if ($orgtables && $jush == "sql") { // MySQL EXPLAIN
$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>";
if ($link) {
$val = "<a href='" . h($link) . "'" . (is_url($link) ? target_blank() : '') . ">$val</a>";
}
echo "<td>$val";
}
@@ -146,7 +151,7 @@ function set_adminer_settings($settings) {
*/
function textarea($name, $value, $rows = 10, $cols = 80) {
global $jush;
echo "<textarea name='$name' rows='$rows' cols='$cols' class='sqlarea jush-$jush' spellcheck='false' wrap='off'>";
echo "<textarea name='" . h($name) . "' rows='$rows' cols='$cols' class='sqlarea jush-$jush' spellcheck='false' wrap='off'>";
if (is_array($value)) {
foreach ($value as $val) { // not implode() to save memory
echo h($val[0]) . "\n\n\n"; // $val == array($query, $time, $elapsed)
@@ -425,7 +430,7 @@ function drop_create($drop, $create, $drop_created, $test, $drop_test, $location
*/
function create_trigger($on, $row) {
global $jush;
$timing_event = " $row[Timing] $row[Event]" . ($row["Event"] == "UPDATE OF" ? " " . idf_escape($row["Of"]) : "");
$timing_event = " $row[Timing] $row[Event]" . (preg_match('~ OF~', $row["Event"]) ? " $row[Of]" : ""); // SQL injection
return "CREATE TRIGGER "
. idf_escape($row["Trigger"])
. ($jush == "mssql" ? $on . $timing_event : $timing_event . $on)
@@ -537,7 +542,7 @@ function doc_link($paths, $text = "<sup>?</sup>") {
$urls['sql'] = "https://mariadb.com/kb/en/library/";
$paths['sql'] = (isset($paths['mariadb']) ? $paths['mariadb'] : str_replace(".html", "/", $paths['sql']));
}
return ($paths[$jush] ? "<a href='$urls[$jush]$paths[$jush]'" . target_blank() . ">$text</a>" : "");
return ($paths[$jush] ? "<a href='" . h($urls[$jush] . $paths[$jush]) . "'" . target_blank() . ">$text</a>" : "");
}
/** Wrap gzencode() for usage in ob_start()

View File

@@ -29,6 +29,9 @@ function version() {
* @return string
*/
function idf_unescape($idf) {
if (!preg_match('~^[`\'"[]~', $idf)) {
return $idf;
}
$last = substr($idf, -1);
return str_replace($last . $last, $last, substr($idf, 1, -1));
}
@@ -1115,7 +1118,7 @@ function dump_headers($identifier, $multi_table = false) {
$return = $adminer->dumpHeaders($identifier, $multi_table);
$output = $_POST["output"];
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();
ob_flush();
@@ -1129,7 +1132,7 @@ function dump_headers($identifier, $multi_table = false) {
*/
function dump_csv($row) {
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) . '"';
}
}
@@ -1411,15 +1414,16 @@ function on_help($command, $side = 0) {
* @param bool
* @return null
*/
function edit_form($TABLE, $fields, $row, $update) {
function edit_form($table, $fields, $row, $update) {
global $adminer, $jush, $token, $error;
$table_name = $adminer->tableName(table_status1($TABLE, true));
$table_name = $adminer->tableName(table_status1($table, true));
page_header(
($update ? lang('Edit') : lang('Insert')),
$error,
array("select" => array($TABLE, $table_name)),
array("select" => array($table, $table_name)),
$table_name
);
$adminer->editRowPrint($table, $fields, $row, $update);
if ($row === false) {
echo "<p class='error'>" . lang('No rows.') . "\n";
}
@@ -1443,7 +1447,7 @@ function edit_form($TABLE, $fields, $row, $update) {
$value = ($row !== null
? ($row[$name] != "" && $jush == "sql" && preg_match("~enum|set~", $field["type"])
? (is_array($row[$name]) ? array_sum($row[$name]) : +$row[$name])
: $row[$name]
: (is_bool($row[$name]) ? +$row[$name] : $row[$name])
)
: (!$update && $field["auto_increment"]
? ""
@@ -1460,6 +1464,9 @@ function edit_form($TABLE, $fields, $row, $update) {
: ($value === false ? null : ($value !== null ? '' : 'NULL'))
)
);
if (!$_POST && !$update && $value == $field["default"] && preg_match('~^[\w.]+\(~', $value)) {
$function = "SQL";
}
if (preg_match("~time~", $field["type"]) && preg_match('~^CURRENT_TIMESTAMP~i', $value)) {
$value = "";
$function = "now";

View File

@@ -13,14 +13,14 @@ if (extension_loaded('pdo')) {
}
function dsn($dsn, $username, $password, $options = array()) {
$options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT;
$options[PDO::ATTR_STATEMENT_CLASS] = array('Min_PDOStatement');
try {
$this->pdo = new PDO($dsn, $username, $password, $options);
} catch (Exception $ex) {
auth_error(h($ex->getMessage()));
}
$this->pdo->setAttribute(3, 1); // 3 - PDO::ATTR_ERRMODE, 1 - PDO::ERRMODE_WARNING
$this->pdo->setAttribute(13, array('Min_PDOStatement')); // 13 - PDO::ATTR_STATEMENT_CLASS
$this->server_info = @$this->pdo->getAttribute(4); // 4 - PDO::ATTR_SERVER_VERSION
$this->server_info = @$this->pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
}
/*abstract function select_db($database);*/
@@ -84,11 +84,11 @@ if (extension_loaded('pdo')) {
var $_offset = 0, $num_rows;
function fetch_assoc() {
return $this->fetch(2); // PDO::FETCH_ASSOC
return $this->fetch(PDO::FETCH_ASSOC);
}
function fetch_row() {
return $this->fetch(3); // PDO::FETCH_NUM
return $this->fetch(PDO::FETCH_NUM);
}
function fetch_field() {
@@ -100,5 +100,3 @@ if (extension_loaded('pdo')) {
}
}
}
$drivers = array();

View File

@@ -1,2 +1,2 @@
<?php
$VERSION = "4.7.8";
$VERSION = "4.8.2-dev";

View File

@@ -2,7 +2,7 @@
$translations = array(
'Login' => 'Inicia la sessió',
'Logout successful.' => 'Desconnexió correcta.',
'Invalid credentials.' => 'Credencials invàlids.',
'Invalid credentials.' => 'Credencials invàlides.',
'Server' => 'Servidor',
'Username' => 'Nom d\'usuari',
'Password' => 'Contrasenya',
@@ -35,7 +35,7 @@ $translations = array(
'Use' => 'Utilitza',
'No tables.' => 'No hi ha cap taula.',
'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%s has been inserted.' => 'S\'ha insertat l\'element%s.',
'Edit' => 'Edita',
@@ -44,9 +44,9 @@ $translations = array(
'Delete' => 'Suprimeix',
'Database' => 'Base de dades',
'Routines' => 'Rutines',
'Indexes have been altered.' => 'S\'han modificat els índexs.',
'Indexes have been altered.' => 'S\'han modificat els índex.',
'Indexes' => 'Índexs',
'Alter indexes' => 'Modifica els índexs',
'Alter indexes' => 'Modifica els índex',
'Add next' => 'Afegeix el següent',
'Language' => 'Idioma',
'Select' => 'Selecciona',
@@ -74,11 +74,11 @@ $translations = array(
'No commands to execute.' => 'Cap comanda per executar.',
'Unable to upload a file.' => 'Impossible adjuntar el 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.'),
'Call' => 'Crida',
'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 expired, please login again.' => 'La sessió ha expirat, torna a iniciar-ne una.',
'Text length' => 'Longitud del text',
@@ -86,7 +86,7 @@ $translations = array(
'Foreign key has been altered.' => 'S\'ha modificat la clau forana.',
'Foreign key has been created.' => 'S\'ha creat la clau forana.',
'Foreign key' => 'Clau forana',
'Target table' => 'Taula de destí',
'Target table' => 'Taula de destinació',
'Change' => 'Canvi',
'Source' => 'Font',
'Target' => 'Destí',
@@ -139,7 +139,7 @@ $translations = array(
'Grant' => 'Grant',
'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.',
'Logged as: %s' => 'Connectat com: %s',
'Logged as: %s' => 'Connectat com a: %s',
'Move up' => 'Mou a dalt',
'Move down' => 'Mou a baix',
'Functions' => 'Funcions',
@@ -204,7 +204,7 @@ $translations = array(
'[yyyy]-mm-dd' => 'dd/mm/[aaaa]',
'History' => 'Història',
'Variables' => 'Variables',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'Les columnes 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',
'From' => 'De',
'Subject' => 'Assumpte',

View File

@@ -280,7 +280,7 @@ $translations = array(
'If you did not send this request from Adminer then close this page.' => 'Wenn Sie diese Anfrage nicht von Adminer gesendet haben, schließen Sie diese Seite.',
'You can upload a big SQL file via FTP and import it from server.' => 'Sie können eine große SQL-Datei per FTP hochladen und dann vom Server importieren.',
'You are offline.' => 'Sie sind offline.',
'You have no privileges to update this table.' => 'Sie haben keine Rechte, um diese Tabelle zu aktualisieren.' ,
'You have no privileges to update this table.' => 'Sie haben keine Rechte, um diese Tabelle zu aktualisieren.',
'Saving' => 'Speichere',
'yes' => 'ja',
'no' => 'nein',

View File

@@ -11,12 +11,12 @@ $translations = array(
'Logged as: %s' => 'Συνδεθήκατε ως %s',
'Logout successful.' => 'Αποσυνδεθήκατε με επιτυχία.',
'Invalid credentials.' => 'Εσφαλμένα Διαπιστευτήρια.',
'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 για να τον κάνετε μόνιμο.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτό.', 'Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτά.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Έληξε ο Κύριος Κωδικός. <a href="https://www.adminer.org/en/extension/"%s>Ενεργοποιήστε</a> τη μέθοδο %s για να τον κάνετε μόνιμο.',
'Language' => 'Γλώσσα',
'Invalid CSRF token. Send the form again.' => 'Άκυρο κουπόνι CSRF. Στείλτε τη φόρμα ξανά.',
'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) δεν είναι διαθέσιμη.',
'Session support must be enabled.' => 'Πρέπει να είναι ενεργοποιημένη η υποστήριξη συνεδριών.',
'Session expired, please login again.' => 'Η συνεδρία έληξε, παρακαλώ συνδεθείτε ξανά.',
@@ -26,7 +26,7 @@ $translations = array(
// text direction - 'ltr' or 'rtl'
'ltr' => 'ltr',
'Privileges' => 'Προνόμια',
'Privileges' => 'Δικαιώματα',
'Create user' => 'Δημιουργία Χρήστη',
'User has been dropped.' => 'Ο Χρήστης διαγράφηκε.',
'User has been altered.' => 'Ο Χρήστης τροποποιήθηκε.',
@@ -38,7 +38,7 @@ $translations = array(
'Revoke' => 'Ανάκληση',
'Process list' => 'Λίστα διεργασιών',
'%d process(es) have been killed.' => array('Τερματίστηκαν %d διεργασία.', 'Τερματίστηκαν %d διεργασίες.'),
'%d process(es) have been killed.' => array('Τερματίστηκε %d διεργασία.', 'Τερματίστηκαν %d διεργασίες.'),
'Kill' => 'Τερματισμός',
'Variables' => 'Μεταβλητές',
@@ -46,8 +46,8 @@ $translations = array(
'SQL command' => 'Εντολή SQL',
'%d query(s) executed OK.' => array('Το ερώτημα %d εκτελέστηκε ΟΚ.', 'Τα ερώτηματα %d εκτελέστηκαν ΟΚ.'),
'Query executed OK, %d row(s) affected.' => array('Το ερώτημα εκτελέστηκε ΟΚ, επιρρεάστηκε %d σειρά.', 'Το ερώτημα εκτελέστηκε ΟΚ, επιρρεάστηκαν %d σειρές.'),
'No commands to execute.' => 'Δεν υπάρχει εντολή να εκτελεστεί.',
'Query executed OK, %d row(s) affected.' => array('Το ερώτημα εκτελέστηκε ΟΚ, επηρεάστηκε %d σειρά.', 'Το ερώτημα εκτελέστηκε ΟΚ, επηρεάστηκαν %d σειρές.'),
'No commands to execute.' => 'Δεν υπάρχουν εντολές να εκτελεστούν.',
'Error in query' => 'Σφάλμα στο ερώτημα',
'Execute' => 'Εκτέλεση',
'Stop on error' => 'Διακοπή όταν υπάρχει σφάλμα',
@@ -58,16 +58,16 @@ $translations = array(
'Clear' => 'Καθαρισμός',
'Edit all' => 'Επεξεργασία όλων',
'File upload' => 'Ανέβασμα αρχείου',
'File upload' => 'Μεταφόρτωση αρχείου',
'From server' => 'Από διακομιστή',
'Webserver file %s' => 'Αρχείο %s από διακομιστή web',
'Run file' => 'Εκτέλεση αρχείου',
'File does not exist.' => 'Το αρχείο δεν υπάρχει.',
'File uploads are disabled.' => 'Έχει απενεργοποιηθεί το ανέβασμα αρχείων.',
'Unable to upload a file.' => 'Δεν είναι δυνατόν να ανεβεί το αρχείο.',
'Maximum allowed file size is %sB.' => 'Το μέγιστο επιτρεπόμενο μέγεθος αρχείο για ανέβασμα είναι %sB.',
'File uploads are disabled.' => 'Έχει απενεργοποιηθεί η μεταφόρτωση αρχείων.',
'Unable to upload a file.' => 'Αδυναμία μεταφόρτωσης αρχείου.',
'Maximum allowed file size is %sB.' => 'Το μέγιστο επιτρεπόμενο μέγεθος αρχείου είναι %sB.',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Πολλά δεδομένα POST. Μείωστε τα περιεχόμενα ή αυξήστε την σχετική ρύθμιση %s.',
'You can upload a big SQL file via FTP and import it from server.' => 'Μπορείτε να ανεβάσετε ένα μεγάλο αρχείο SQL μέσω FTP και να το εισάγετε από το διακομιστή.',
'You can upload a big SQL file via FTP and import it from server.' => 'Μπορείτε να μεταφορτώσετε ένα μεγάλο αρχείο SQL μέσω FTP και να το εισάγετε από το διακομιστή.',
'You are offline.' => 'Βρίσκεστε εκτός σύνδεσης.',
'Export' => 'Εξαγωγή',
@@ -82,7 +82,7 @@ $translations = array(
'database' => 'β. δεδομένων',
'Use' => 'χρήση',
'Select database' => 'Επιλέξτε Β.Δ.',
'Invalid database.' => 'Άκυρη Β.Δ.',
'Invalid database.' => 'Λανθασμένη Β.Δ.',
'Database has been dropped.' => 'Η Β.Δ. διαγράφηκε.',
'Databases have been dropped.' => 'Οι Β.Δ. διαγράφηκαν.',
'Database has been created.' => 'Η Β.Δ. δημιουργήθηκε.',
@@ -111,7 +111,7 @@ $translations = array(
'Check' => 'Έλεγχος',
'Repair' => 'Επιδιόρθωση',
'Truncate' => 'Περικοπή',
'Tables have been truncated.' => 'Οι πίνακες περικόπτηκαν.',
'Tables have been truncated.' => 'Οι πίνακες περικόπηκαν.',
'Move to other database' => 'Μεταφορά σε άλλη Β.Δ.',
'Move' => 'Μεταφορά',
'Tables have been moved.' => 'Οι πίνακες μεταφέρθηκαν.',
@@ -119,11 +119,11 @@ $translations = array(
'Tables have been copied.' => 'Οι πίνακες αντιγράφηκαν.',
'Routines' => 'Ρουτίνες',
'Routine has been called, %d row(s) affected.' => array('Η ρουτίνα εκτελέστηκε, επιρρεάστηκε %d σειρά.', 'Η ρουτίνα εκτελέστηκε, επιρρεάστηκαν %d σειρές.'),
'Routine has been called, %d row(s) affected.' => array('Η ρουτίνα εκτελέστηκε, επηρεάστηκε %d σειρά.', 'Η ρουτίνα εκτελέστηκε, επηρεάστηκαν %d σειρές.'),
'Call' => 'Εκτέλεση',
'Parameter name' => 'Όνομα παραμέτρου',
'Create procedure' => 'Δημιουργία διαδικασίας',
'Create function' => 'Δημιουργία Λειτουργίας',
'Create function' => 'Δημιουργία Συνάρτησης',
'Routine has been dropped.' => 'Η ρουτίνα διαγράφηκε.',
'Routine has been altered.' => 'Η ρουτίνα τροποποιήθηκε.',
'Routine has been created.' => 'Η ρουτίνα δημιουργήθηκε.',
@@ -151,7 +151,7 @@ $translations = array(
'Alter table' => 'Τροποποίηση πίνακα',
'Create table' => 'Δημιουργία πίνακα',
'Table has been dropped.' => 'Ο πίνακας διαγράφηκε.',
'Tables have been dropped.' => 'Οι πινακες διαγράφηκαν.',
'Tables have been dropped.' => 'Οι πίνακες διαγράφηκαν.',
'Tables have been optimized.' => 'Οι πίνακες βελτιστοποιήθηκαν.',
'Table has been altered.' => 'Ο πίνακας τροποποιήθηκε.',
'Table has been created.' => 'Ο πίνακας δημιουργήθηκε.',
@@ -210,7 +210,7 @@ $translations = array(
'Add foreign key' => 'Προσθήκη εξαρτημένου κλειδιού',
'ON DELETE' => 'ΚΑΤΑ ΤΗ ΔΙΑΓΡΑΦΗ',
'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' => 'Εναύσματα',
'Add trigger' => 'Προσθήκη εναύσματος',
@@ -262,7 +262,7 @@ $translations = array(
'Item%s has been inserted.' => 'Η εγγραφή%s εισήχθη.',
'Item has been deleted.' => 'Η εγγραφή διαγράφηκε.',
'Item has been updated.' => 'Η εγγραφή ενημερώθηκε.',
'%d item(s) have been affected.' => array('Επιρρεάστηκε %d εγγραφή.', 'Επιρρεάστηκαν %d εγγραφές.'),
'%d item(s) have been affected.' => array('Επηρεάστηκε %d εγγραφή.', 'Επηρεάστηκαν %d εγγραφές.'),
'New item' => 'Νέα εγγραφή',
'original' => 'πρωτότυπο',
// label for value '' in enum data type
@@ -274,7 +274,7 @@ $translations = array(
'Save and continue edit' => 'Αποθήκευση και συνέχεια επεξεργασίας',
'Save and insert next' => 'Αποθήκευση και εισαγωγή επόμενου',
'Selected' => 'Επιλεγμένα',
'Clone' => 'Κλονοποίηση',
'Clone' => 'Κλωνοποίηση',
'Delete' => 'Διαγραφή',
'You have no privileges to update this table.' => 'Δεν έχετε δικαίωμα να τροποποιήσετε αυτό τον πίνακα.',
@@ -283,7 +283,7 @@ $translations = array(
'Subject' => 'Θέμα',
'Attachments' => 'Συνημμένα',
'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
'Numbers' => 'Αριθμοί',

View File

@@ -175,7 +175,7 @@ $translations = array(
'Repair' => 'Javít',
'Truncate' => 'Felszabadít',
'Tables have been truncated.' => 'A tábla felszabadítva.',
'Rows' => 'Oszlop',
'Rows' => 'Sorok',
',' => ' ',
'0123456789' => '0123456789',
'Tables have been moved.' => 'Táblák áthelyezve.',

View File

@@ -1,267 +1,280 @@
<?php
$translations = array(
'Login' => '로그인',
'Logout successful.' => '로그아웃',
'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' => '기본값',
'$1-$3-$5' => '$1-$3-$5',
'%.3f s' => '%.3f 초',
'%d byte(s)' => '%d 바이트',
'No commands to execute.' => '실행할 수 있는 명령이 없습니다.',
'Unable to upload a file.' => '파일을 업로드 할 수 없습니다.',
'File upload' => '파일 올리기',
'File uploads are disabled.' => '파일 업로드가 잘못되었습니다.',
'Routine has been called, %d row(s) affected.' => '루틴을 호출했습니다. %d 행을 변경했습니다.',
'Call' => '외침',
'No extension' => '확장 기능이 없습니다.',
'None of the supported PHP extensions (%s) are available.' => 'PHP 확장 (%s)가 설치되어 있지 않습니다.',
'Session support must be enabled.' => '세션을 사용하십시오.',
'Session expired, please login again.' => '세션 만료. 다시 로그인하십시오.',
'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' => '이벤트',
'%d e-mail(s) have been sent.' => '%d개 메일을 보냈습니다.',
'%d in total' => '총 %d개',
'%d item(s) have been affected.' => '%d개 항목을 갱신했습니다.',
'%d process(es) have been killed.' => '%d개 프로세스를 강제 종료하였습니다.',
'%d query(s) executed OK.' => '%d개 쿼리를 잘 실행했습니다.',
'%d row(s) have been imported.' => '%d개 행을 가져 왔습니다.',
'%d row(s)' => '%d개 행',
'%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',
'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',
'History' => '역사',
'Variables' => '변수',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => '원본 및 대상 열은 동일한 데이터 형식이어야합니다. 목표 컬럼에 인덱스와 데이터가 존재해야합니다.',
'Relations' => '관계',
'Run file' => '파일을 실행',
'Clear' => '삭제',
'Maximum allowed file size is %sB.' => '파일의 최대 크기 %sB',
'Numbers' => '숫자',
'Date and time' => '시간',
'Strings' => '문자열',
'Binary' => '이진',
'Lists' => '목록',
'Editor' => '에디터',
'E-mail' => '메일',
'From' => '보낸 사람',
'Subject' => '제목',
'Send' => '보내기',
'%d e-mail(s) have been sent.' => '%d 메일을 보냈습니다.',
'Webserver file %s' => 'Web 서버 파일 %s',
'File does not exist.' => '파일이 존재하지 않습니다.',
'%d in total' => '총 %d',
'Permanent login' => '영구적으로 로그인',
'Databases have been dropped.' => '데이터베이스를 삭제했습니다.',
'Search data in tables' => '데이터 검색',
'Schema' => '스키마',
'Action' => '실행',
'Add column' => '열 추가',
'Add foreign key' => '외부 키를 추가',
'Add next' => '다음 추가',
'Add trigger' => '트리거 추가',
'Aggregation' => '집합',
'Alter database' => '데이터베이스 변경',
'Alter event' => '이벤트 변경',
'Alter function' => '함수 변경',
'Alter indexes' => '색인 변경',
'Alter procedure' => '시저 변경',
'Alter schema' => '스키마 변경',
'Create schema' => '스키마 추가',
'Schema has been dropped.' => '스키마를 삭제했습니다.',
'Schema has been created.' => '스키마를 추가했습니다.',
'Schema has been altered.' => '스키마를 변경했습니다.',
'Sequences' => '시퀀스',
'Create sequence' => '시퀀스 만들기',
'Alter sequence' => '순서 변경',
'Sequence has been dropped.' => '시퀀스를 제거했습니다.',
'Sequence has been created.' => '시퀀스를 추가했습니다.',
'Sequence has been altered.' => '순서를 변경했습니다.',
'User types' => '사용자 정의 형',
'Create type' => '사용자 정의 형식 만들기',
'Alter type' => '사용자 정의 형식 변경',
'Type has been dropped.' => '사용자 정의 형식을 삭제했습니다.',
'Type has been created.' => '사용자 정의 형식을 추가했습니다.',
'Use edit link to modify this value.' => '링크 편집',
'last' => '마지막',
'From server' => '서버에서 실행',
'System' => '데이터베이스 형식',
'empty' => '하늘',
'Network' => '네트워크 형',
'Geometry' => '기하 형',
'File exists.' => '파일이 이미 있습니다.',
'Alter table' => '테이블 변경',
'Alter trigger' => '트리거 변경',
'Alter type' => '형 변경',
'Alter view' => '보기 변경',
'Alter' => '변경',
'Analyze' => '분석',
'anywhere' => '모든',
'Are you sure?' => '실행 하시겠습니까?',
'At given time' => '지정 시간',
'Attachments' => '첨부 파일',
'Item%s has been inserted.' => '%s 항목을 삽입했습니다.',
'now' => '현재 시간',
'%d query(s) executed OK.' => '%d 쿼리를 실행했습니다.',
'Show only errors' => '오류 만 표시',
'Refresh' => '새로 고침',
'Invalid schema.' => '잘못된 스키마',
'Please use one of the extensions %s.' => '하나의 확장 기능을 사용하십시오 %s',
'ltr' => 'ltr',
'Tables have been copied.' => '테이블을 복사했습니다',
'Auto Increment' => '자동 증가',
'Binary' => '이진',
'Call' => '호출',
'Change' => '변경',
'Check' => '확인',
'Clear' => '삭제',
'Clone' => '복제',
'collation' => '정렬',
'Collation' => '정렬',
'Column (length)' => '열 (길이)',
'Column name' => '열 이름',
'Column' => '열',
'Comment' => '주석',
'Compute' => '계산하기',
'Copy' => '복사',
'Permanent link' => '영구 링크',
'Edit all' => '모든 편집',
'Create database' => '데이터베이스 만들기',
'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' => '데이터베이스',
'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' => '시:분:초',
'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

@@ -289,4 +289,15 @@ $translations = array(
'Saving' => 'Сохранение',
'yes' => 'Да',
'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.' => 'База данных не поддерживает пароль.',
);

View File

@@ -14,7 +14,7 @@ $translations = array(
'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öder inte lösenord.',
'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',
@@ -25,7 +25,7 @@ $translations = array(
'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 ur, vänligen logga in igen.',
'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',

View File

@@ -313,4 +313,34 @@ $translations = array(
'Type has been dropped.' => 'Тип було видалено.',
'Type has been created.' => 'Тип було створено.',
'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

@@ -8,6 +8,9 @@ function adminer_object() {
include_once $filename;
}
// enable extra drivers just by including them
//~ include "../plugins/drivers/simpledb.php";
$plugins = array(
// specify enabled plugins here
new AdminerDatabaseHide(array('information_schema')),

View File

@@ -1,12 +1,14 @@
<?php
if (support("kill") && $_POST && !$error) {
$killed = 0;
foreach ((array) $_POST["kill"] as $val) {
if (kill_process($val)) {
$killed++;
if (support("kill")) {
if ($_POST && !$error) {
$killed = 0;
foreach ((array) $_POST["kill"] as $val) {
if (kill_process($val)) {
$killed++;
}
}
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);

View File

@@ -331,7 +331,7 @@ if (!$columns && support("table")) {
$column = idf_escape($key);
$href = remove_from_uri('(order|desc)[^=]*|page') . '&order%5B0%5D=' . urlencode($key);
$desc = "&desc%5B0%5D=1";
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 apply_sql_function($val["fun"], $name) . "</a>"; //! columns looking like functions
echo "<span class='column hidden'>";
@@ -382,7 +382,7 @@ if (!$columns && support("table")) {
$key = "MD5(" . ($jush != 'sql' || preg_match("~^utf8~", $fields[$key]["collation"]) ? $key : "CONVERT($key USING " . charset($connection) . ")") . ")";
$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>"
. checkbox("check[]", substr($unique_idf, 1), in_array(substr($unique_idf, 1), (array) $_POST["check"]))

View File

@@ -222,7 +222,7 @@ if (!isset($_GET["import"])) {
}
echo "<p>";
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 lang('Limit rows') . ": <input type='number' name='limit' class='size' value='" . h($_POST ? $_POST["limit"] : $_GET["limit"]) . "'>\n";
@@ -244,8 +244,8 @@ if (!isset($_GET["import"])) {
echo "<p>";
}
echo checkbox("error_stops", 1, ($_POST ? $_POST["error_stops"] : isset($_GET["import"])), lang('Stop on error')) . "\n";
echo checkbox("only_errors", 1, ($_POST ? $_POST["only_errors"] : isset($_GET["import"])), lang('Show only errors')) . "\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"]) || $_GET["only_errors"]), lang('Show only errors')) . "\n";
echo "<input type='hidden' name='token' value='$token'>\n";
if (!isset($_GET["import"]) && $history) {

View File

@@ -17,14 +17,14 @@ function bodyLoad(version, maria) {
for (var i = 1; i < obj.length; i++) {
obj[i] = obj[i]
.replace(/\.html/, '/')
.replace(/(numeric)(-type-overview)/, '$1-data$2')
.replace(/-type-syntax/, '-data-types')
.replace(/numeric-(data-types)/, '$1-$&')
.replace(/#statvar_.*/, '#$$1')
;
}
}
}
obj[key] = obj[key]
.replace(/dev\.mysql\.com\/doc\/mysql\/en\//, (maria ? 'mariadb.com/kb/en/library/' : '$&')) // MariaDB
obj[key] = (maria ? obj[key].replace(/dev\.mysql\.com\/doc\/mysql\/en\//, 'mariadb.com/kb/en/library/') : obj[key]) // MariaDB
.replace(/\/doc\/mysql/, '/doc/refman/' + version) // MySQL
.replace(/\/docs\/current/, '/docs/' + version) // PostgreSQL
;
@@ -658,7 +658,7 @@ function triggerChange(tableRe, table, form) {
if (tableRe.test(form['Trigger'].value)) {
form['Trigger'].value = table + '_' + (selectValue(form['Timing']).charAt(0) + formEvent.charAt(0)).toLowerCase();
}
alterClass(form['Of'], 'hidden', formEvent != 'UPDATE OF');
alterClass(form['Of'], 'hidden', !/ OF/.test(formEvent));
}

View File

@@ -2,7 +2,7 @@
$TABLE = $_GET["trigger"];
$name = $_GET["name"];
$trigger_options = trigger_options();
$row = (array) trigger($name) + array("Trigger" => $TABLE . "_bi");
$row = (array) trigger($name, $TABLE) + array("Trigger" => $TABLE . "_bi");
if ($_POST) {
if (!$error && in_array($_POST["Timing"], $trigger_options["Timing"]) && in_array($_POST["Event"], $trigger_options["Event"]) && in_array($_POST["Type"], $trigger_options["Type"])) {

View File

@@ -1,3 +1,67 @@
Adminer 4.8.2-dev:
Support multi-line table comments
MySQL: Use ST_SRID() instead of SRID() for MySQL 8 (PR #418)
PostgreSQL: Don't reset table comments (regression from 4.2.0)
PostgreSQL PDO: Allow editing rows identified by boolean column (PR #380)
Adminer 4.8.1 (released 2021-05-14):
Internet Explorer or PDO in Adminer 4.7.8-4.8.0: Fix XSS in doc_link (bug #797)
Fix more PHP 8 warnings (bug #781)
Avoid PHP warnings with PDO drivers (bug #786, regression from 4.7.8)
MySQL: Allow moving views to other DB and renaming DB with views (bug #783)
MariaDB: Do not treat sequences as views (PR #416)
PostgreSQL: Support UPDATE OF triggers (bug #789)
PostgreSQL: Support triggers with more events (OR)
PostgreSQL: Fix parsing of foreign keys with non-ASCII column names
PostgreSQL < 10 PDO: Avoid displaying GENERATED ALWAYS BY IDENTITY everywhere (bug #785, regression from 4.7.9)
SQLite: Fix displayed types (bug #784, regression from 4.8.0)
Adminer 4.8.0 (released 2021-02-10):
Support function default values in insert (bug #713)
Allow SQL pseudo-function in insert
Skip date columns for non-date values in search anywhere
Add DB version to comment in export
Support PHP 8 in create table (regression from 4.7.9)
MySQL 8: Fix EXPLAIN in SQL command
PostgreSQL: Create PRIMARY KEY for auto increment columns
PostgreSQL: Avoid exporting empty sequence last value (bug #768)
PostgreSQL: Do not show triggers from other schemas (PR #412)
PostgreSQL: Fix multi-parameter functions in default values (bug #736)
PostgreSQL: Fix displaying NULL bytea fields
PostgreSQL PDO: Do not select NULL function for false values in edit
Oracle: Alter indexes
Oracle: Count tables
Oracle: Import from CSV
Oracle: Fix column size with string type
MongoDB: Handle errors
SimpleDB, Firebird, ClickHouse: Move to plugin
Adminer 4.7.9 (released 2021-02-07):
Fix XSS in browsers which don't encode URL parameters (bug #775, regression from 4.7.0)
Elasticsearch, ClickHouse: Do not print response if HTTP code is not 200
Don't syntax highlight during IME composition (bug #747)
Quote values with leading and trailing zeroes in CSV export (bug #777)
Link URLs in SQL command (PR #411)
Fix displayed foreign key columns from other DB (bug #766)
Re-enable PHP warnings (regression from 4.7.8)
MySQL: Do not export names in quotes with sql_mode='ANSI_QUOTES' (bug #749)
MySQL: Avoid error in PHP 8 when connecting to socket (PR #409)
MySQL: Don't quote default value of text fields (bug #779)
PostgreSQL: Export all FKs after all CREATE TABLE (PR #351)
PostgreSQL: Fix dollar-quoted syntax highlighting (bug #738)
PostgreSQL: Do not show view definition from other schema (PR #392)
PostgreSQL: Use bigserial for bigint auto increment (bug #765, regression from 3.0.0)
PostgreSQL PDO: Support PgBouncer, unsupport PostgreSQL < 9.1 (bug #771)
PostgreSQL 10: Support GENERATED ALWAYS BY IDENTITY (PR #386)
PostgreSQL 10: Support partitioned tables (PR #396)
PostgreSQL 11: Create PRIMARY KEY for auto increment columns
SQLite: Set busy_timeout to 500
MS SQL: Don't truncate comments to 30 chars (PR #376)
Elasticsearch 6: Fix displaying type mapping (PR #402)
MongoDB: Fix password-less check in the mongo extension (PR #405)
Editor: Cast to string when searching (bug #325)
Editor: Avoid trailing dot in export filename
Adminer 4.7.8 (released 2020-12-06):
Support PHP 8
Disallow connecting to privileged ports (bug #769)
@@ -335,7 +399,7 @@ Adminer 3.7.1 (released 2013-06-29):
Increase click target for checkboxes
Use shadow for highlighting default button
Don't use LIMIT 1 if inline updating unique row
Don't check previous checkbox on added column in create table (bug #3614245)
Don't check previous checkbox on added column in create table (bug #326)
Order table list by name
Verify UTF-8 encoding of CSV import
Notify user about expired master password for permanent login
@@ -346,7 +410,7 @@ Display error on invalid alter table and view pages
MySQL: Speed up updating rows without numeric or UTF-8 primary key
Non-MySQL: Descending indexes
PostgreSQL: Fix detecting oid column in PDO
PostgreSQL: Handle timestamp types (bug #3614086)
PostgreSQL: Handle timestamp types (bug #324)
Add Korean translation
Adminer 3.7.0 (released 2013-05-19):
@@ -359,9 +423,9 @@ Disable SQL export when applying functions in select
Allow using lang() in plugins (customization)
Remove bzip2 compression support
Constraint memory used in TAR export
Allow exporting views dependent on each other (bug #3459151)
Fix resetting search (bug #3612507)
Don't use LIMIT 1 if updating unique row (bug #3613109)
Allow exporting views dependent on each other (bug #214)
Fix resetting search (bug #318)
Don't use LIMIT 1 if updating unique row (bug #320)
Restrict editing rows without unique identifier to search results
Display navigation bellow main content on mobile browsers
Get number of rows on export page asynchronously
@@ -369,7 +433,7 @@ Respect 'whole result' even if some rows are checked (bug #339 since Adminer 3.7
MySQL: Optimize create table page and Editor navigation
MySQL: Display bit type as binary number
MySQL: Improve export of binary data types
MySQL: Fix handling of POINT data type (bug #3582578)
MySQL: Fix handling of POINT data type (bug #282)
MySQL: Don't export binary and geometry columns twice in select
MySQL: Fix EXPLAIN in MySQL < 5.1, bug since Adminer 3.6.4
SQLite: Export views
@@ -384,11 +448,11 @@ Recover original view, trigger, routine if creating fails
Do not store plain text password to history in creating user
Selectable ON UPDATE CURRENT_TIMESTAMP field in create table
Open database to a new window after selecting it with Ctrl
Clear column name after resetting search (bug #3601200)
Explain partitions in SQL query (bug #3600150)
Allow loading more data with inline edit (bug #3605531)
Stay on the same page after deleting rows (bug #3605845)
Respect checked tables in export filename (bug #3245464)
Clear column name after resetting search (bug #296)
Explain partitions in SQL query (bug #294)
Allow loading more data with inline edit (bug #299)
Stay on the same page after deleting rows (bug #301)
Respect checked tables in export filename (bug #133)
Respect PHP configuration max_input_vars
Fix unsetting permanent login after logout
Disable autocapitalize in identifiers on mobile browsers
@@ -473,11 +537,11 @@ Ukrainian translation
Bengali translation
Adminer 3.3.4 (released 2012-03-07):
Foreign keys default actions (bug #3397606)
Foreign keys default actions (bug #188)
SET DEFAULT foreign key action
Fix minor parser bug in SQL command with webserver file
Ctrl+click on button opens form to a blank window
Trim table and column names (bug #3405309)
Trim table and column names (bug #195)
Error message with no response from server in AJAX
Esc to cancel AJAX request
Move AJAX loading indicator to the right
@@ -489,9 +553,9 @@ Ability to disable export (customization)
Extensible list of databases (customization)
MySQL: set autocommit after connect
SQLite, PostgreSQL: vacuum
SQLite, PostgreSQL: don't use LIKE for numbers (bug #3420408)
SQLite, PostgreSQL: don't use LIKE for numbers (bug #202)
PostgreSQL: fix alter foreign key
PostgreSQL over PDO: connect if the eponymous database does not exist (bug #3391619)
PostgreSQL over PDO: connect if the eponymous database does not exist (bug #185)
Boolean search (Editor)
Persian translation
@@ -519,8 +583,8 @@ Adminer 3.3.0 (released 2011-07-19):
Use Esc to disable in-place edit
Shortcut for database privileges
Editable index names
Append new index with auto index selection (bug #3282127)
Preserve original timestamp value in multiple update (bug #3312614)
Append new index with auto index selection (bug #138)
Preserve original timestamp value in multiple update (bug #158)
Bit type default value
Display foreign key name in tooltip
Display default column value in table overview
@@ -534,7 +598,7 @@ Display foreign keys from other schemas (PostgreSQL)
Pagination support (Oracle)
Autocomplete for big foreign keys (Editor)
Display name of the referenced record in PostgreSQL (Editor)
Prefer NULL to empty string (Editor, bug #3323800)
Prefer NULL to empty string (Editor, bug #162)
Display searched columns (Editor)
Customizable favicon (customization)
Method name can return a link (customization)
@@ -546,8 +610,8 @@ Fix AJAX history after reload
Adminer 3.2.1 (released 2011-03-23):
Ability to save expression in edit
Respect default database collation (bug #3191489)
Don't export triggers without table (bug #3193489)
Respect default database collation (bug #119)
Don't export triggers without table (bug #123)
Esc to focus next field in Tab textarea
Send forms by Ctrl+Enter on <select>
Enum editor and textarea Ctrl+Enter working in IE
@@ -570,8 +634,8 @@ Get long texts and slow information by AJAX
Most links and forms by AJAX in browsers with support for history.pushState
Copy tables
Ability to search by expression in select
Export SQL command result (bug #3116854)
Focus first field with insert (bug #3126501)
Export SQL command result (bug #99)
Focus first field with insert (bug #106)
Permanent link in schema
Display total time in show only errors mode in SQL command
History: edit all
@@ -584,7 +648,7 @@ Utilize oids in PostgreSQL
Homepage customization
Use IN for search in numeric fields (Editor)
Use password input for _md5 and _sha1 fields (Editor)
Work without session.use_cookies (bug #3138640)
Work without session.use_cookies (bug #107)
Fix saving schema to cookie in Opera
Portuguese, Slovenian and Turkish translation
@@ -597,10 +661,10 @@ Recognize $$ strings in SQL command (PostgreSQL)
Highlight and edit SQL command in processlist
Always display all drivers
Timestamp at the end of export
Link to refresh database cache (bug #3102451)
Link to refresh database cache (bug #96)
Support for virtual foreign keys
Disable XSS "protection" of IE8
Immunity against zend.ze1_compatibility_mode (bug #3089645)
Immunity against zend.ze1_compatibility_mode (bug #86)
Fix last page with empty result set
Arabic translation and RTL support
Dual licensing: Apache or GPL
@@ -648,7 +712,7 @@ Add Drop button to Alter pages (regression from 2.0.0)
Link COUNT(*) result to listing
Newlines in select query edit
Return to referrer after edit
Respect session.auto_start (bug #2967284)
Respect session.auto_start (bug #42)
Adminer 2.3.0 (released 2010-02-26):
Support for permanent login (customization required)
@@ -677,7 +741,7 @@ Link URLs in select
Display number of manipulated rows in JS confirm
Set required memory in SQL command
Fix removed default in ALTER
Display whitespace in texts (bug #2858042)
Display whitespace in texts (bug #11)
ClickJacking protection in modern browsers
E-mail attachments (Editor)
Optional year in date (Editor)
@@ -696,7 +760,7 @@ Use ON DUPLICATE KEY UPDATE for CSV import
Print ALTER export instead of executing it
Click on row selects it
Fix Editor date format
Fix long SQL query crash (bug #2839231)
Fix long SQL query crash (bug #3)
Speed up simple alter table
Traditional Chinese translation
@@ -752,7 +816,7 @@ Use \n in SQL commands
phpMinAdmin 1.10.1 (released 2009-05-07):
Highlight odd and hover rows
Partition editing comfort (bug #2783446)
Partition editing comfort (bug #12)
Allow full length in limited int
phpMinAdmin 1.10.0 (released 2009-04-28):
@@ -839,7 +903,7 @@ phpMinAdmin 1.4.0 (released 2007-08-15):
Privileges
New design
Dutch translation
Use NULL for auto_increment (bug #1768966)
Use NULL for auto_increment (bug #1)
Fix dropping procedure parameters
phpMinAdmin 1.3.2 (released 2007-08-06):

View File

@@ -1,6 +1,11 @@
#!/usr/bin/env php
<?php
error_reporting(6133); // errors
function adminer_errors($errno, $errstr) {
return !!preg_match('~^(Trying to access array offset on value of type null|Undefined array key)~', $errstr);
}
error_reporting(6135); // errors and warnings
set_error_handler('adminer_errors', E_WARNING);
include dirname(__FILE__) . "/adminer/include/version.inc.php";
include dirname(__FILE__) . "/externals/JsShrink/jsShrink.php";
@@ -36,7 +41,7 @@ function lang_ids($match) {
}
function put_file($match) {
global $project, $VERSION;
global $project, $VERSION, $driver;
if (basename($match[2]) == '$LANG.inc.php') {
return $match[0]; // processed later
}
@@ -56,6 +61,9 @@ header("Cache-Control: immutable");
echo "adminer/file.inc.php: Caching headers placeholder not found\n";
}
}
if ($driver && dirname($match[2]) == "../adminer/drivers") {
$return = preg_replace('~^if \(isset\(\$_GET\["' . $driver . '"]\)\) \{(.*)^}~ms', '\1', $return);
}
if (basename($match[2]) != "lang.inc.php" || !$_SESSION["lang"]) {
if (basename($match[2]) == "lang.inc.php") {
$return = str_replace('function lang($idf, $number = null) {', 'function lang($idf, $number = null) {
@@ -100,7 +108,7 @@ function lzw_compress($string) {
$word = "";
$codes = array();
for ($i=0; $i <= strlen($string); $i++) {
$x = $string[$i];
$x = @$string[$i];
if (strlen($x) && isset($dictionary[$word . $x])) {
$word .= $x;
} elseif ($i) {

729
designs/dracula/adminer.css Normal file
View File

@@ -0,0 +1,729 @@
/*
* Theme by Douglas Damasio [http://github.com/douglasdamasio]
* Based on Pepa Linha
* Color syntax inspired by Dracula Theme [https://draculatheme.com/]
* @version 1.0 (June 2020)
*/
@import url('https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@300;400;600&family=Ubuntu:wght@500;700&display=swap');
:root {
--color-darkBackground: #282a36;
--color-darkCurrentLine: #44475a;
--color-darkForeground: #f8f8f2;
--color-darkComment: #6272a4;
--color-darkCyan: #8be9fd;
--color-darkGreen: #50fa7b;
--color-darkOrange: #ffb86c;
--color-darkPink: #ff79c6;
--color-darkPurple: #bd93f9;
--color-darkRed: #ff5555;
--color-darkYellow: #f1fa8c;
--color-darkTitleSite: #bcc2cd;
--color-darkDraculaSite: #383a59;
--color-darkDraculaVSCode: #22222c;
}
html,
body {
height: 100%;
background: var(--color-darkBackground);
}
body {
font-family: 'Source Sans Pro', sans-serif;
}
div {
color: var(--color-darkForeground);
}
h1 {
margin: 0;
padding: 0;
background: none;
border: 0;
}
h2 {
margin: 0;
padding: 0;
background: none;
border: 0;
font-family: 'Ubuntu', sans-serif;
font-size: 32px;
font-weight: 700;
color: var(--color-darkPink);
border-bottom: 1px solid var(--color-darkComment);
padding-bottom: 6px;
margin-bottom: 40px;
}
.rtl h2 {
margin: 0;
margin-bottom: 40px;
}
h3 {
font-size: 22px;
margin: 0 0 10px;
border-bottom: 1px solid var(--color-darkComment);
padding: 0;
padding-bottom: 6px;
color: var(--color-darkGreen);
}
p {
margin: 0;
margin-bottom: 15px;
align-items: center;
color: var(--color-darkForeground);
}
a {
color:var(--color-darkPink);
text-decoration:none;
}
a:visited {
color: var(--color-darkPurple);
}
a:link:hover,
a:visited:hover {
color: var(--color-darkPink);
text-decoration:underline;
}
a[href*=charsets] {
display: none;
}
table {
border: 0;
margin: 0;
margin-top: 15px;
}
th, td {
border: 0;
padding: 6px;
color: var(--color-darkOrange);
}
th {
background: none;
color: var(--color-darkCyan);
font-weight: normal;
}
tbody tr:hover td,
tbody tr:hover th {
background: var(--color-darkCurrentLine);
}
table:not(.checkable) th {
min-width: 120px;
}
thead td,
thead th {
background: var(--color-darkComment);
}
thead td,
thead td a,
thead td a:link:hover,
thead td a:visited,
thead td a:visited:hover,
thead th,
thead th a,
thead th a:link:hover,
thead th a:visited,
thead th a:visited:hover {
color: var(--color-darkForeground);
}
table.checkable,
p.links + table,
pre + table,
#edit-fields,
p + table,
h3 + table {
border: 1px solid var(--color-darkCurrentLine);
margin-bottom: 15px;
}
table.checkable tbody tr:hover td,
table.checkable tbody tr:hover th {
background: var(--color-darkCurrentLine);
}
.js .checkable .checked td,
.js .checkable .checked th {
background: var(--color-darkDraculaSite);
}
.js .checkable thead .checked td,
.js .checkable thead .checked th {
background: var(--color-darkPurple);
}
.odd th,
.odd td {
background: var(--color-darkDraculaVSCode);
}
fieldset {
display: inline-block;
padding: 15px;
padding-top: 5px;
margin: 0 0 15px;
border: 0;
background: var(--color-darkBackground);
}
fieldset select {
margin-right: 5px;
}
fieldset input[type=button],
fieldset input[type=submit],
fieldset p {
margin-bottom: 0;
}
fieldset div p {
margin-top: 10px;
}
legend {
display: inline-block;
padding: 6px 15px;
margin: 0 0 0 -15px;
background: var(--color-darkDraculaSite);
font-family: 'Source Sans Pro', sans-serif;
color: var(--color-darkOrange);
}
legend a,
legend a:link:hover {
color: var(--color-darkOrange);
text-decoration: underline;
}
code {
background: none;
}
p code,
pre code,
pre[contenteditable=true] {
padding: 10px 15px;
display: block;
font-size: 17px;
margin-bottom: 15px;
}
p code + a,
p code + a:link:hover,
p code + a:visited:hover {
margin-left: 15px;
position: relative;
top: -20px;
color: var(--color-darkOrange);
font-size: 12px;
text-decoration: underline;
text-transform: lowercase;
}
#content {
margin: 0;
margin-left: 400px;
margin-right: 54px;
padding: 0;
padding-top: 50px;
}
#content > p {
margin-bottom: 15px;
color: var(--color-darkForeground);
}
.rtl #content {
margin: 0;
margin-left: 54px;
margin-right: 400px;
padding: 0;
padding-top: 50px;
}
#menu {
width: 347px;
border-right: 1px solid var(--color-darkBackground);
box-shadow: inset -1px 0 0 #000000b4;
margin: 0;
padding: 0;
top: 0;
background: var(--color-darkDraculaVSCode);
bottom: 0;
position: fixed;
padding: 0 15px;
box-sizing: border-box;
}
#menu h1 {
background: none left top no-repeat;
/* background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD0AAAAyCAIAAABgVkRrAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTA0RDI5NkM5QkRGMTFFMzg4ODNEQjEzNjY5NzJEMEEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTA0RDI5NkQ5QkRGMTFFMzg4ODNEQjEzNjY5NzJEMEEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1MDREMjk2QTlCREYxMUUzODg4M0RCMTM2Njk3MkQwQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1MDREMjk2QjlCREYxMUUzODg4M0RCMTM2Njk3MkQwQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PnG4emkAAASXSURBVHja7Fk9aNtAFL6EDKKUoqGDySRKB1FC8dDBdCgeOmQoIUMG0yGE0EFT8dDBUwidPJQQQgcNpYROGjKI0sFDB9GhaMhgSgcPpWgqHjqYYsINJfQ7PfV0tmX9JI4Sgx+HI8f26bt3733fe6elIf/LbqwdHbJWS1wYBrMstrXJVg36ZJnNhQWBWMB9k+215gq3tDeHBH3pRseJtC8ee2ezEzd62+ncDH/DhS+ttC88qbMPDntaj952uyvXD3q7ETvyyE77pq5HFz9614r7V8C2GnBezBgp9tGNl3ffzIjvwZ9B//dA7Mz3YPLTyl29UhE+MI0KW9YKh2yjwQZichEAjsNu6WlUqNqkvwHUO+0BJeD2gn4hJFXTwAIw6jUzYxlwHkCTvWqy1+0Ct7FtsPh/3Ofc9brOJ5+8ezHr9gKMcGpWf2SK8bhKk48sA1kIOiODmzc2c8U0DLrzwhI5ypjA3fsZtNrOgPP4y5pmGJXamqHd1kQMTIkENYpwEfQHEW7GsGkYZse393ewb+Y9IwE0PJcOejQ2pFgK3Li3BI14hZM269XKaiXPVPodHUOs6l48o/+t5wO038OcQGztHzd31uPfUEgQdCQi3JkfumLLHa9LoK2tunPQtJ6v5wQ9zWoPzebupms34QKxmZNJAugIDzJE+V4rbTrDSMYtr3AD+H5WFIfZ0lIFPu50otiF7zfW2dlgquKccTFWRxYQ8wlFJOVTdc2gAChq/V99vxdgD7O5CIBO/Yi/P3vsUY2dOOxBdSrzIBm2dxJwq+hlaiId9dua5OlEv/IhH0vKvAYXfvUjvUTFB2STeinJu91Oxo3Eh58onwRXcB7zWkGj/Maa9203+9soPIyWEKBEkQdc8veo+sS4wQkYzV1Bi+A1Ee5DnhO33BxsSw1/wszGPHkXmqI7yIQzPvnvhPqEFjAWtSq7j7n2YplwSctVV8F/FXazbN76nQXu68btfe3Odmqwahl5Ca6tel0UVdnVc6pRBX/JkrgYn0RCY0cdAMhYvGYxHbEklbJ++FoqD8LTUiwTlZLEha55WKOmSybWTCXD1eJG8dnc4XAYqmdgmoRFyp/ZqqHbgMiD8qGXZeAOs1RD9YyhBgBVTgL3cMTHwKd2xyUL50qmTI5p/oK/F7jnEjeycLZTFz02SrKlaSPGbe0fOx+9mbTGcMHhe/fwuFMGn4Dy7BMPA3oBGkZrbIDgcp9JgK37YYtZjmSuqApH9yPRcTp+TM939THOpkaYroMguRuSE14tbuegif11vS58poYm7i1vn6fdxF6hMoNk4leIvTJ0B1FhPQ/PxM45eZ2HGjkY8jHXqptghGJJqqmKVHn1oCr4k93xgr8XuOcZ9zmf7dQym68Et6QFcFaBk7EsQ5fdfuteHW7xPM3asyVh05EkxFJITMHuGDUCukxwvOz3YI31mtWoX7TRXkrDjQhBLeFOHBtQQ6n/f8TDlAd/6mNBP7xO7Ecbz2qNjfrl6qoU3Mr5Qa4j9yyLHqZd7jwjL241QQFdPiJTdT7RsBuapslzi5mqVSHcKXYetcZlSelU3P8EGADW25uhkIE0mQAAAABJRU5ErkJggg==); */
background-image: url();
line-height: 50px;
padding-left: 50px;
padding-top: 9px;
/* text-transform: lowercase; */
margin: 25px 0 10px 16px;
}
#menu h1 a {
font-style: normal;
}
#menu h1 .version {
color: var(--color-darkPurple);
}
#menu a {
color: var(--color-darkForeground);
}
#menu p, #tables {
border: 0;
padding: 0;
}
#menu #dbs {
background: var(--color-darkDraculaVSCode);
padding: 0 15px 15px;
border: 1px solid var(--color-darkForeground);
border-bottom: 0;
box-sizing: border-box;
color: var(--color-darkCyan);
}
#menu #dbs select {
outline: 0;
border-color: var(--color-darkComment);
width: 100%;
}
#menu p.links {
margin: 0 0 15px;
border: 1px solid var(--color-darkForeground);
border-top: 0;
text-align: center;
display: table;
width: 100%;
box-sizing: border-box;
}
#menu p.links a {
padding: 8px;
margin: 0;
display: table-cell;
font-size: 12px;
}
#menu p.links a:hover {
color: var(--color-darkPink);
}
#menu p.links a.active {
font-weight: normal;
background: var(--color-darkCurrentLine);
color: var(--color-darkYellow);
}
#content p.links {
margin: -10px 0 15px;
}
#content p.links a {
padding: 8px;
margin: 0;
display: table-cell;
border: 1px solid var(--color-darkBackground);
}
#content p.links a,
#content p.links a:visited,
#content p.links a:hover {
color: var(--color-darkCyan);
}
#content p.links a.active {
font-weight: normal;
border: 1px solid var(--color-darkTitleSite);
background: var(--color-darkCurrentLine);
}
#tables {
max-height: 100%;
margin: 32px -15px !important;
position: absolute;
left: 15px;
right: 15px;
bottom: 0;
top: 220px;
overflow: hidden !important;
overflow-y: auto !important;
}
.rtl #tables {
overflow: hidden !important;
overflow-y: auto !important;
}
#tables a {
float: right;
padding: 6px 15px;
}
.rtl #tables a {
float: none;
}
#tables .structure, #tables .view {
float: none;
display: block;
}
.rtl #tables a:first-child,
.rtl #tables br + a {
float: left;
display: block;
margin-left: 15px;
}
#tables a:hover,
#tables a:hover + a,
#tables a.active,
#tables a.active + a {
background: var(--color-darkBackground);
color: var(--color-darkPink);
}
#tables br {
display: none;
}
.js .column {
background: var(--color-darkDraculaVSCode);
}
.js .checked .column {
background: var(--color-darkDraculaVSCode);
}
.pages {
left: 400px;
background: var(--color-darkCyan);
color: var(--color-darkBackground);
font-weight: bold;
border: 0;
display: inline-block;
position: static;
}
.pages a,
.pages a:link,
.pages a:link:hover,
.pages a:visited,
.pages a:visited:hover {
color: var(--color-darkBackground);
font-weight: normal;
}
#breadcrumb {
margin: 0;
left: 400px;
background: none;
padding: 0;
padding-top: 25px;
font-size: 12px;
}
#breadcrumb a {
color: var(--color-darkForeground);
text-decoration: underline;
}
#breadcrumb,
#breadcrumb a:hover {
color: var(--color-darkTitleSite);
}
.rtl #breadcrumb {
margin: 0;
padding: 0;
padding-top: 25px;
right: 400px;
}
.logout,
.rtl .logout {
top: 30px;
right: 54px;
margin: 0;
}
.rtl .logout {
right: auto;
left: 54px;
}
input:not([type]),
input[type="color"],
input[type="email"],
input[type="number"],
input[type="password"],
input[type="tel"],
input[type="url"],
input[type="text"],
input[type="search"] {
border: 1px solid var(--color-darkCurrentLine);
background-color: var(--color-darkBackground);
padding: 6px;
margin: 0;
box-sizing: border-box;
color: var(--color-darkForeground);
}
table:not(#table) input:not([type]),
table:not(#table) input[type="color"],
table:not(#table) input[type="email"],
table:not(#table) input[type="number"],
table:not(#table) input[type="password"],
table:not(#table) input[type="tel"],
table:not(#table) input[type="url"],
table:not(#table) input[type="text"],
table:not(#table) input[type="search"] {
min-width: 280px;
}
input[type=submit],
input[type=button] {
border: 0;
padding: 7px 12px;
cursor: pointer;
outline: 0;
box-shadow: none;
background: var(--color-darkGreen);
color: var(--color-darkBackground);
font-weight: bold;
margin-bottom: 5px;
transition: background .4s ease;
border-radius: 5px;
margin-top: 20px;
}
input[type=submit][disabled],
input[type=button][disabled] {
background: var(--color-darkTitleSite) !important;
color: var(--color-darkBackground);
cursor: not-allowed;
}
input[type=submit]:hover,
input[type=button]:hover,
input[type=submit]:focus,
input[type=button]:focus {
background: var(--color-darkGreen);
opacity: 0.8;
}
.logout input[type=submit] {
background: var(--color-darkRed);
color: var(--color-darkForeground);
}
.logout input[type=submit]:hover {
background: var(--color-darkRed);
opacity: 0.8;
}
input.default,
input.default {
box-shadow: none;
background: var(--color-darkGreen);
color: var(--color-darkDraculaVSCode);
font-weight: bold;
}
select {
box-sizing: border-box;
margin: 0;
padding: 6px 0;
border: 1px solid var(--color-darkCurrentLine);
background-color: var(--color-darkBackground);
color: var(--color-darkForeground);
}
label {
cursor: pointer;
margin: 18px;
color: var(--color-darkOrange);
}
.error,
.message {
margin: 0;
margin-bottom: 15px;
background: var(--color-darkCurrentLine);
color: var(--color-darkRed);
}
#logins a,
#tables a,
#tables span {
background: none;
}
#form > p {
margin-bottom: 15px;
color: var(--color-darkForeground);
}
#schema .table {
padding: 6px;
}
#schema .table a {
display: block;
margin: -6px;
margin-bottom: 6px;
padding: 6px;
color: var(--color-darkBackground);
background: var(--color-darkPurple);
}
#schema .table br {
display: none;
}
#schema .table span {
display: block;
margin-bottom: 1px solid var(--color-darkDraculaVSCode);
}
#lang {
position: fixed;
top: 55px;
right: 100%;
z-index: 10;
margin-right: -340px;
line-height: normal;
padding: 0;
left: auto;
font-size: 0;
}
#lang select {
font-size: 12px;
padding: 0;
text-align: right;
border: 0;
background: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
cursor: pointer;
outline: 0;
}
#lang select option {
text-align: right;
}
.rtl #lang {
margin-right: 0;
left: 100%;
margin-left: -261px;
right: auto;
}
.jush {
color: var(--color-darkForeground);
}
.jush a {
color: var(--color-darkPurple);
}
.jush-sql a,
.jush-sql_code a,
.jush-sqlite a,
.jush-pgsql a,
.jush-mssql a,
.jush-oracle a,
.jush-simpledb a {
font-weight: normal;
}
.jush-bac,
.jush-php_bac,
.jush-bra,
.jush-mssql_bra,
.jush-sqlite_quo {
color: var(--color-darkYellow);
}
.jush-php_quo,
.jush-quo,
.jush-quo_one,
.jush-php_eot,
.jush-apo,
.jush-sql_apo,
.jush-sqlite_apo,
.jush-sql_quo,
.jush-sql_eot {
color: var(--color-darkOrange);
}
.jush-num,
.jush-clr {
color: var(--color-darkPurple);
}
@media print {
.logout {
display: none;
}
#breadcrumb {
position: static;
}
#content {
margin: 0;
}
}
.footer {
position: sticky;
bottom: 0;
margin-right: -20px;
border-top: 20px solid var(--color-darkBackground);
border-image: var(--color-darkBackground) 100% 0;
border-image-source: var(--color-darkBackground);
border-image-slice: 100% 0;
border-image-width: 1;
border-image-outset: 0;
border-image-repeat: stretch;
}
.footer > div {
background: var(--color-darkBackground);
padding: 0 0 .5em;
}

View File

@@ -752,7 +752,7 @@ legend{
font-size: 13px;
}
#tables a[title] {
#tables .structure, #tables .view {
float: none;
display: block;
color: inherit;

1
designs/hydra Submodule

Submodule designs/hydra added at afcef61f66

View File

@@ -19,9 +19,9 @@ html/*\*/>/*/*/body a[href$="dump="] {background:url("data:image/png;base64,iVBO
html/*\*/>/*/*/body select[name="db"] {background:white url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEYSURBVBgZBcHPio5hGAfg6/2+R980k6wmJgsJ5U/ZOAqbSc2GnXOwUg7BESgLUeIQ1GSjLFnMwsKGGg1qxJRmPM97/1zXFAAAAEADdlfZzr26miup2svnelq7d2aYgt3rebl585wN6+K3I1/9fJe7O/uIePP2SypJkiRJ0vMhr55FLCA3zgIAOK9uQ4MS361ZOSX+OrTvkgINSjS/HIvhjxNNFGgQsbSmabohKDNoUGLohsls6BaiQIMSs2FYmnXdUsygQYmumy3Nhi6igwalDEOJEjPKP7CA2aFNK8Bkyy3fdNCg7r9/fW3jgpVJbDmy5+PB2IYp4MXFelQ7izPrhkPHB+P5/PjhD5gCgCenx+VR/dODEwD+A3T7nqbxwf1HAAAAAElFTkSuQmCC") no-repeat scroll left bottom; padding-left:16px;}
html/*\*/>/*/*/body select[name="db"] option {padding-left:18px;}
html/*\*/>/*/*/body #menu p a[href*="&select="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHkm9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1zztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wGhGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUHYJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWluUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhNTWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7nHADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGFrwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=") no-repeat scroll left bottom; clear:left; display:block; float:left; height:16px; margin-right:8px; padding-top:1px; overflow:hidden; padding-left:16px; width:0; text-decoration:none;}
html/*\*/>/*/*/body #menu li a[href*="&select="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHkm9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1zztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wGhGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUHYJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWluUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhNTWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7nHADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGFrwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=") no-repeat scroll left bottom; clear:left; display:block; float:left; height:16px; margin-right:8px; padding-top:1px; overflow:hidden; padding-left:16px; width:0; text-decoration:none;}
html/*\*/>/*/*/body #menu p a[href*="&table="], html/*\*/>/*/*/body #menu p a[href*="&view="] {clear:right; margin-left:24px; display:block; height:17px; padding-bottom:1px; text-decoration:none;}
html/*\*/>/*/*/body #menu li a[href*="&table="], html/*\*/>/*/*/body #menu li a[href*="&view="] {clear:right; margin-left:24px; display:block; height:17px; padding-bottom:1px; text-decoration:none;}
html/*\*/>/*/*/body #menu p#tables br {display:none;}

View File

@@ -1,6 +1,6 @@
/*
A colourful RTL-friendly theme.
Update from https://github.com/vrana/adminer/raw/master/designs/lucas-sandery/adminer.css
A colourful, RTL-friendly theme.
Update from https://github.com/lucas-sandery/adminer/raw/master/designs/lucas-sandery/adminer.css
Icons from http://FlatIcon.com:
"Translation" by Freepik
@@ -13,7 +13,7 @@ Icons from http://FlatIcon.com:
"Forbidden Mark" by Pavel Kozlov
"Search" by Freepik
Background from "All Work and No Play", http://thenewcode.com/1008/SVG-Movie-Backgrounds-Andys-Room-and-Overlook-Hotel
Background adapted from "All Work and No Play", http://thenewcode.com/1008/SVG-Movie-Backgrounds-Andys-Room-and-Overlook-Hotel
*/
html {
height: 100%;
@@ -23,6 +23,7 @@ body {
min-height: 100%;
display: flex;
background: #41658a;
box-sizing: border-box;
}
p {
margin-right: 0;
@@ -133,6 +134,9 @@ thead a:visited:focus,
.message p > a:visited:focus {
color: #f39561;
}
pre {
overflow-x: auto;
}
code.jush-sql {
display: inline-block;
padding: 0.3em 0.5em 0.2em;
@@ -164,6 +168,11 @@ th > code {
.footer {
background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 340.6 491.8' width='56px' height='81px'%3E%3Cpolygon fill='%2370a37f' fill-opacity='0.05' points='229.9,208.7 170.5,243 111,208.7 111,140 170.5,105.7 229.9,140'/%3E%3Cpolygon fill='%2370a37f' fill-opacity='0.05' points='0,305.3 59.5,339.6 59.5,408.3 0,442.6'/%3E%3Cpolygon fill='%2370a37f' fill-opacity='0.05' points='342.8,442.6 283.3,408.3 283.3,339.6 342.8,305.3'/%3E%3Cpolygon fill='%2379b473' fill-opacity='0.05' points='91.6,0 0,52.9 0,0'/%3E%3Cpolygon fill='%2379b473' fill-opacity='0.05' points='340.6,0 340.6,52.9 248.8,0'/%3E%3Cpolygon fill='%2379b473' fill-opacity='0.05' points='21.4,264.6 102.8,311.6 102.8,431.7 -1.2,491.8 0,544.5 149.7,458.1 149.1,285.1 68.2,236.7 68.2,116.6 172.2,56.5 276.2,116.6 276.2,236.7 192.5,285 192.5,337.1 192.5,337.1 192.5,458.1 342.2,544.5 341,491.8 237,431.7 237,311.6 320.8,263.3 320.8,90.2 171.1,3.8 21.4,90.2'/%3E%3C/svg%3E") fixed;
}
@supports (-ms-ime-align: auto) {
.footer {
background: #fff;
}
}
.scrollable {
overflow: auto;
}
@@ -202,6 +211,7 @@ h2 {
padding: 2em 20px 0.5em;
border-bottom-style: none;
color: #fff;
overflow-wrap: break-word;
}
h1,
h2,
@@ -247,7 +257,7 @@ input.required {
}
table {
border-style: none;
background: rgba(255, 255, 255, 0.8);
background: rgba(255, 255, 255, 0.6);
}
td,
th {
@@ -275,20 +285,27 @@ thead th,
thead td {
border-color: #fff;
padding: 0.5em 0.8em 0.6em;
background: #414073;
color: #fff;
}
thead th {
text-align: left;
font-weight: normal;
}
.js .checkable thead .checked th,
thead th {
background: #414073;
position: relative;
background-clip: padding-box;
}
.rtl thead th {
text-align: right;
}
.js .checkable thead .checked td,
thead td {
background: #41658a;
}
.js .column {
z-index: 1;
background: transparent;
padding: 0;
margin-top: 0;
@@ -325,20 +342,20 @@ tbody tr:nth-child(n):hover td {
tbody tr:nth-child(n):hover th {
background: rgba(236, 72, 18, 0.2);
}
.js .checkable .checked td {
.js .checkable tbody .checked td {
background: rgba(236, 72, 18, 0.25);
}
.js .checkable .checked:nth-child(even) td,
.js .checkable .checked th {
.js .checkable tbody .checked:nth-child(even) td,
.js .checkable tbody .checked th {
background: rgba(236, 72, 18, 0.3);
}
.js .checkable .checked:nth-child(even) th {
.js .checkable tbody .checked:nth-child(even) th {
background: rgba(236, 72, 18, 0.35);
}
.js .checkable .checked:hover td {
.js .checkable tbody .checked:hover td {
background: rgba(236, 72, 18, 0.4);
}
.js .checkable .checked:hover th {
.js .checkable tbody .checked:hover th {
background: rgba(236, 72, 18, 0.45);
}
.icon {
@@ -368,12 +385,9 @@ tbody tr:nth-child(n):hover th {
.column a[href="#fieldset-search"] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' viewBox='0 0 310.088 310.088' enable-background='new 0 0 310.088 310.088' width='512px' height='512px'%3E%3Cg%3E%3Cpath d='m299.85,250.413l-62.808-62.808c-3.982-3.982-10.437-3.982-14.418,0l-3.539,3.539-18.586-18.586c29.709-42.872 25.472-102.152-12.716-140.34-42.958-42.958-112.606-42.958-155.563,0s-42.958,112.606 0,155.563c38.189,38.188 97.468,42.425 140.34,12.716l18.586,18.586-3.539,3.539c-3.982,3.981-3.982,10.437 0,14.418l62.808,62.808c13.651,13.651 35.785,13.651 49.436,0s13.65-35.784-0.001-49.435zm-251.368-78.895c-33.921-33.921-33.921-89.115-0.001-123.036 33.922-33.921 89.117-33.922 123.037-0.001v0.001c33.922,33.921 33.922,89.115 0,123.036-16.96,16.961-39.239,25.441-61.518,25.441-22.279,0-44.558-8.48-61.518-25.441z' fill='%23FFFFFF'/%3E%3C/g%3E%3C/svg%3E");
}
.loadmore {
margin-right: -0.4em;
}
.loadmore,
.rtl .loadmore {
margin-right: 0;
margin-left: -0.4em;
margin: 0;
}
.footer {
margin: 0;
@@ -386,6 +400,9 @@ tbody tr:nth-child(n):hover th {
background: transparent;
padding: 0;
}
.footer ~ div {
margin-top: 0.8em;
}
#lang,
.logout {
z-index: 3;
@@ -394,6 +411,7 @@ tbody tr:nth-child(n):hover th {
overflow: hidden;
width: 2em;
height: 2em;
position: fixed;
}
#lang {
left: 18em;
@@ -403,8 +421,6 @@ tbody tr:nth-child(n):hover th {
}
.rtl .logout {
margin: 0;
left: 0;
right: auto;
}
#lang select,
#logout {
@@ -417,8 +433,8 @@ tbody tr:nth-child(n):hover th {
cursor: pointer;
z-index: 1;
}
#lang:after,
.logout:after {
#lang:before,
.logout:before {
position: absolute;
top: 0;
left: 0;
@@ -430,15 +446,16 @@ tbody tr:nth-child(n):hover th {
background: #2d3047 center no-repeat;
background-size: 70%;
}
#lang:after {
#lang:before {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' viewBox='0 0 470 470' enable-background='new 0 0 470 470' width='512px' height='512px'%3E%3Cg%3E%3Cpath d='m432.5,227.5h-77.031c-0.611-37.438-5.782-73.616-14.771-105.694h50.518c4.143,0 7.5-3.357 7.5-7.5s-3.357-7.5-7.5-7.5h-55.112c-8.018-24.165-18.316-45.521-30.553-62.656-2.408-3.371-7.093-4.153-10.462-1.745-3.371,2.407-4.152,7.092-1.745,10.462 10.618,14.868 19.688,33.199 26.965,53.939h-77.809v-69.306c0-4.143-3.357-7.5-7.5-7.5s-7.5,3.357-7.5,7.5v69.306h-77.81c7.277-20.74 16.347-39.071 26.965-53.939 2.407-3.37 1.626-8.055-1.745-10.462-3.372-2.407-8.055-1.625-10.462,1.745-12.237,17.135-22.535,38.492-30.553,62.656h-55.112c-4.143,0-7.5,3.357-7.5,7.5s3.357,7.5 7.5,7.5h50.518c-8.988,32.078-14.159,68.256-14.771,105.694h-77.03c-4.143,0-7.5,3.357-7.5,7.5s3.357,7.5 7.5,7.5h77.031c0.611,37.438 5.782,73.616 14.771,105.694h-50.519c-4.143,0-7.5,3.357-7.5,7.5s3.357,7.5 7.5,7.5h55.112c8.019,24.169 18.32,45.529 30.56,62.666 1.464,2.049 3.77,3.142 6.11,3.142 1.508,0 3.031-0.454 4.353-1.397 3.37-2.408 4.151-7.092 1.744-10.463-10.621-14.869-19.693-33.204-26.972-53.947h77.81v69.305c0,4.143 3.357,7.5 7.5,7.5s7.5-3.357 7.5-7.5v-69.306h77.81c-7.278,20.744-16.351,39.078-26.972,53.947-2.407,3.371-1.626,8.055 1.744,10.463 1.321,0.943 2.844,1.397 4.353,1.397 2.341,0 4.646-1.093 6.11-3.142 12.24-17.137 22.54-38.497 30.56-62.666h55.112c4.143,0 7.5-3.357 7.5-7.5s-3.357-7.5-7.5-7.5h-50.519c8.989-32.078 14.16-68.256 14.771-105.694h77.031c4.143,0 7.5-3.357 7.5-7.5s-3.357-7.499-7.5-7.499zm-107.36-105.694c9.313,31.683 14.695,67.958 15.326,105.694h-97.966v-105.694h82.64zm-180.28,0h82.64v105.694h-97.966c0.632-37.737 6.013-74.011 15.326-105.694zm0,226.388c-9.313-31.683-14.695-67.958-15.326-105.694h97.966v105.694h-82.64zm180.28,0h-82.64v-105.694h97.966c-0.632,37.737-6.013,74.012-15.326,105.694z' fill='%23ECEBE4'/%3E%3Cpath d='M401.17,68.83C356.784,24.444,297.771,0,235,0S113.216,24.444,68.83,68.83S0,172.229,0,235.001 c0,46.271,13.391,90.899,38.764,129.316l-28.718,86.148c-0.898,2.695-0.197,5.667,1.812,7.676c2.009,2.008,4.979,2.708,7.676,1.812 l86.15-28.716C144.102,456.609,188.729,470,235,470c62.771,0,121.784-24.444,166.17-68.83S470,297.771,470,235.001 C470,172.229,445.556,113.216,401.17,68.83z M235,455c-44.491,0-87.355-13.222-123.961-38.235 c-1.262-0.862-2.739-1.308-4.231-1.308c-0.797,0-1.598,0.127-2.372,0.385L29.02,440.979l25.14-75.414 c0.741-2.225,0.399-4.668-0.923-6.604C28.222,322.357,15,279.492,15,235.001C15,113.692,113.691,15,235,15s220,98.692,220,220.001 C455,356.309,356.309,455,235,455z' fill='%23ECEBE4'/%3E%3C/g%3E%3C/svg%3E");
}
.logout:after {
.logout:before {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' viewBox='0 0 512 512' enable-background='new 0 0 512 512' width='512px' height='512px'%3E%3Cg%3E%3Cpath d='m256,501c-129.6,0-235-102.2-235-227.8 0-87.8 50.6-166.3 132.1-204.9 10.2-4.8 22.4-0.5 27.2,9.7 4.8,10.2 0.5,22.4-9.7,27.2-67.1,31.8-108.7,96.1-108.7,168-7.10543e-15,103.1 87.1,187 194.1,187 107,0 194.1-83.9 194.1-187 0-72.4-44-138.9-112.2-169.5-10.3-4.6-14.9-16.7-10.3-27 4.6-10.3 16.7-14.9 27-10.2 82.9,37.1 136.4,118.3 136.4,206.7 0,125.6-105.4,227.8-235,227.8z' fill='%23FFFFFF'/%3E%3Cpath d='m256,287.9c-11.3,0-20.4-9.1-20.4-20.4v-236.1c0-11.3 9.2-20.4 20.4-20.4 11.3,0 20.4,9.1 20.4,20.4v236.1c0,11.3-9.1,20.4-20.4,20.4z' fill='%23FFFFFF'/%3E%3C/g%3E%3C/svg%3E");
}
/* need a real element for :focus ~ styling */
#lang:hover:after,
.logout:hover:after {
#lang:focus-within:before,
#lang:hover:before,
.logout:focus-within:before,
.logout:hover:before {
background-color: #ec5f12;
}
#menu {
@@ -447,6 +464,7 @@ tbody tr:nth-child(n):hover th {
width: auto;
flex: 0 0 20em;
max-width: 20em;
z-index: 1;
}
h1 {
background: #414073;
@@ -526,6 +544,70 @@ button:disabled {
background-color: rgba(76, 57, 87, 0.35);
cursor: not-allowed;
}
input[type="file"]::-ms-browse {
display: inline-block;
font-size: 85%;
text-align: center;
background: #4c3957;
color: #fff;
padding: 0.5em 0.8em 0.6em;
margin: 0;
border-style: none;
cursor: pointer;
}
input[type="file"]:hover::-ms-browse,
input[type="file"]:focus::-ms-browse {
color: #fff;
background: #ec5f12;
text-decoration: none;
}
input[type="file"]:disabled::-ms-browse {
background-color: rgba(76, 57, 87, 0.35);
cursor: not-allowed;
}
input[type="file"]::-webkit-file-upload-button {
-webkit-appearance: none;
display: inline-block;
font-size: 85%;
text-align: center;
background: #4c3957;
color: #fff;
padding: 0.5em 0.8em 0.6em;
margin: 0;
border-style: none;
cursor: pointer;
}
input[type="file"]:hover::-webkit-file-upload-button,
input[type="file"]:focus::-webkit-file-upload-button {
color: #fff;
background: #ec5f12;
text-decoration: none;
}
input[type="file"]:disabled::-webkit-file-upload-button {
background-color: rgba(76, 57, 87, 0.35);
cursor: not-allowed;
}
input[type="file"]::-moz-file-upload-button {
display: inline-block;
font-size: 85%;
text-align: center;
background: #4c3957;
color: #fff;
padding: 0.5em 0.8em 0.6em;
margin: 0;
border-style: none;
cursor: pointer;
}
input[type="file"]:hover::-moz-file-upload-button,
input[type="file"]:focus::-moz-file-upload-button {
color: #fff;
background: #ec5f12;
text-decoration: none;
}
input[type="file"]:disabled::-moz-file-upload-button {
background-color: rgba(76, 57, 87, 0.35);
cursor: not-allowed;
}
.links .active {
font-weight: normal;
background-color: #414073;
@@ -679,6 +761,9 @@ button:disabled {
-o-box-decoration-break: clone;
box-decoration-break: clone;
}
.logout {
position: absolute;
}
#lang {
margin-left: auto;
position: relative;

View File

@@ -819,7 +819,7 @@ legend{
font-size: 13px;
}
#tables a[title] {
#tables .structure, #tables .view {
float: none;
display: block;
color: #F1E5B3;

View File

@@ -1,7 +1,6 @@
/*
* Theme by Pepa Linha [http://webdream.cz]
* JUSH color syntax inspired by NetBeans
* @version 0.2 (February 2014)
*/
html,
@@ -360,7 +359,7 @@ p code + a:visited:hover {
float: none;
}
#tables a[title] {
#tables .structure, #tables .view {
float: none;
display: block;
}

View File

@@ -0,0 +1,152 @@
/*
@author: mariani
@package: ZeroCloud Theme https://www.zerocloud.it
*/
/*
blue: #2ba6cb
*/
h1{
background-color: #333; border-color: #666; color: #c9da29;
-webkit-box-shadow:inset 0 -7px 0 0 #c9da29;
-moz-box-shadow:inset 0 -7px 0 0 #c9da29;
box-shadow:inset 0 -7px 0 0 #c9da29;
border: 0!important;
}
table{ border-color: #666; }
table thead tr td, table thead tr th,
table thead tr.checked td, table thead tr.checked th{ background-color: #333!important; border-color: #666!important; color: #c9da29;}
table thead td a:link, table thead th a:link,
table thead td a:visited, table thead th a:visited,
table thead td a:hover, table thead th a:hover,
table thead td a:active, table thead th a:active
{color: #fff;}
.error {background:#FFEEEE url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIsSURBVDjLpVNLSJQBEP7+h6uu62vLVAJDW1KQTMrINQ1vPQzq1GOpa9EppGOHLh0kCEKL7JBEhVCHihAsESyJiE4FWShGRmauu7KYiv6Pma+DGoFrBQ7MzGFmPr5vmDFIYj1mr1WYfrHPovA9VVOqbC7e/1rS9ZlrAVDYHig5WB0oPtBI0TNrUiC5yhP9jeF4X8NPcWfopoY48XT39PjjXeF0vWkZqOjd7LJYrmGasHPCCJbHwhS9/F8M4s8baid764Xi0Ilfp5voorpJfn2wwx/r3l77TwZUvR+qajXVn8PnvocYfXYH6k2ioOaCpaIdf11ivDcayyiMVudsOYqFb60gARJYHG9DbqQFmSVNjaO3K2NpAeK90ZCqtgcrjkP9aUCXp0moetDFEeRXnYCKXhm+uTW0CkBFu4JlxzZkFlbASz4CQGQVBFeEwZm8geyiMuRVntzsL3oXV+YMkvjRsydC1U+lhwZsWXgHb+oWVAEzIwvzyVlk5igsi7DymmHlHsFQR50rjl+981Jy1Fw6Gu0ObTtnU+cgs28AKgDiy+Awpj5OACBAhZ/qh2HOo6i+NeA73jUAML4/qWux8mt6NjW1w599CS9xb0mSEqQBEDAtwqALUmBaG5FV3oYPnTHMjAwetlWksyByaukxQg2wQ9FlccaK/OXA3/uAEUDp3rNIDQ1ctSk6kHh1/jRFoaL4M4snEMeD73gQx4M4PsT1IZ5AfYH68tZY7zv/ApRMY9mnuVMvAAAAAElFTkSuQmCC") no-repeat scroll 0.8em center; padding-left:38px;}
.message, #menu p.message {background:#EEFFEE url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKfSURBVDjLpZPrS1NhHMf9O3bOdmwDCWREIYKEUHsVJBI7mg3FvCxL09290jZj2EyLMnJexkgpLbPUanNOberU5taUMnHZUULMvelCtWF0sW/n7MVMEiN64AsPD8/n83uucQDi/id/DBT4Dolypw/qsz0pTMbj/WHpiDgsdSUyUmeiPt2+V7SrIM+bSss8ySGdR4abQQv6lrui6VxsRonrGCS9VEjSQ9E7CtiqdOZ4UuTqnBHO1X7YXl6Daa4yGq7vWO1D40wVDtj4kWQbn94myPGkCDPdSesczE2sCZShwl8CzcwZ6NiUs6n2nYX99T1cnKqA2EKui6+TwphA5k4yqMayopU5mANV3lNQTBdCMVUA9VQh3GuDMHiVcLCS3J4jSLhCGmKCjBEx0xlshjXYhApfMZRP5CyYD+UkG08+xt+4wLVQZA1tzxthm2tEfD3JxARH7QkbD1ZuozaggdZbxK5kAIsf5qGaKMTY2lAU/rH5HW3PLsEwUYy+YCcERmIjJpDcpzb6l7th9KtQ69fi09ePUej9l7cx2DJbD7UrG3r3afQHOyCo+V3QQzE35pvQvnAZukk5zL5qRL59jsKbPzdheXoBZc4saFhBS6AO7V4zqCpiawuptwQG+UAa7Ct3UT0hh9p9EnXT5Vh6t4C22QaUDh6HwnECOmcO7K+6kW49DKqS2DrEZCtfuI+9GrNHg4fMHVSO5kE7nAPVkAxKBxcOzsajpS4Yh4ohUPPWKTUh3PaQEptIOr6BiJjcZXCwktaAGfrRIpwblqOV3YKdhfXOIvBLeREWpnd8ynsaSJoyESFphwTtfjN6X1jRO2+FxWtCWksqBApeiFIR9K6fiTpPiigDoadqCEag5YUFKl6Yrciw0VOlhOivv/Ff8wtn0KzlebrUYwAAAABJRU5ErkJggg==") no-repeat scroll 0.8em center; padding-left:38px;}
#dbs span, th a[href*="&db="]:not([href*="&select="]):not([href*="&table="]) {background:transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEYSURBVBgZBcHPio5hGAfg6/2+R980k6wmJgsJ5U/ZOAqbSc2GnXOwUg7BESgLUeIQ1GSjLFnMwsKGGg1qxJRmPM97/1zXFAAAAEADdlfZzr26miup2svnelq7d2aYgt3rebl585wN6+K3I1/9fJe7O/uIePP2SypJkiRJ0vMhr55FLCA3zgIAOK9uQ4MS361ZOSX+OrTvkgINSjS/HIvhjxNNFGgQsbSmabohKDNoUGLohsls6BaiQIMSs2FYmnXdUsygQYmumy3Nhi6igwalDEOJEjPKP7CA2aFNK8Bkyy3fdNCg7r9/fW3jgpVJbDmy5+PB2IYp4MXFelQ7izPrhkPHB+P5/PjhD5gCgCenx+VR/dODEwD+A3T7nqbxwf1HAAAAAElFTkSuQmCC") no-repeat scroll left bottom; padding-left:22px;}
span.separator {display: none;}
a[href$="&sql="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHGSURBVHjaxFPNLkNREP5aB6WhaKLSVtKFiIUqK1sLT2DhTXgDL2FlxSOw8FOLRiyQWhDRiKSEhKQJou49P9fMnFsLsevCJCcz594z3/m+mTmJKIrQjSXRpXUNoGqbm39qcMbAkbyIvbVwYQhD3tIeWsOQ1+QVH86Xyz+JXJPIOb9iAI4ZpOMd/yN/vb/vAdiC93cP0El2dNA6z4RjYyW2MaPU0BB0u+0BOGGsVML49LSA3J+cYDCblb0l6jeHBwg/26isrOB0a8uzYBlBgKShgD8M53J4aTTQqFaRSCYl+WxnG83zcxTmKpKg+vtFu9W8NDQDMCXW+VivYyAzjKmlJahUSpiYUKPVbCKTz0sCGzOyOpBLzdcXlCMdDDIxO4vboyoyhQIKlYocLi0uIjczIyBcA98dYqx9NywxUEyDi/P29IyF1VU5dFeroS+dRnF+Xvajk5N0ayjx8tq6+FuSyiwUF4LRHi/reLg4o9ijs6xG9RjWGowUi/h4fcXexoa0L4oc0mNZuVgFzID09VKBnFXoUb7Pnb5zQrvVovpkZC4QzwfiN6QM1eBqdxcmnq6IAA395Mlz8eTxTZwg/pcl/v01fgswAESqYZbsIsnLAAAAAElFTkSuQmCC") no-repeat scroll left bottom; padding-left:22px;}
a[href*="&dump="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJrSURBVHjajFPPaxNREP72V8ymTbGQbRB/IT0otdV6CcWTgqCoUFQQEXoSEQ/+AypK755E1KsULIpGgw1F9KC22lgstFgQLdoWhSab2PRHTNrs7nvObGhSsRa/ZXjv7c6b+eabWUVKiX9AJQuRRci2k+260N91VwgJIQSEV1mVnjf5axTjvCfFFn7hCcBlBzJNVRA0gAZTQ1ODgXC4gDtjV9AW2QNFUTA0/Q66kPLSqVg4shYF8vEdKQ7mln+i+/VVRM0oFpbmETLq/SS6J4R/OfHtHmV24XouHFo94REDAyE9hMZgBMkvT2GZFqxQE6by0/g4P74SoKLB2ZZzWA8ffqRQLBcxNTuFjRTwxpmbfad7Oo/rHhdN6B20/6JvaKyBCnODhqNbL+PRxHXUGXWINV5kl9TDrkQct/pnZKHkyPsDGcl4MJiWq5Ecsf84LxTL8nbyK2+Pke3XHWJAQkLXgMdDNjRNRTxlQ6UmakRD0vN8NEd7EBsFO6Impu1fzGCCrOSXwCro5HEiZiExnEVnrKlaypNhG4fba02aTC8ik1/ibZrM9RlIkkGnjH0jWWJQWRn8TpLI8fcZ6MSA1WrZFERx2eHPTEPqjksBqASDLh7ZZ+HlWA6H9tYyvhjNomNnI8Km7p8/f5+HGdB46/lJeOoYPHV8mbGy8gA59HngU74asNkKYKVzlQCuW9GA6B5si+DVeA4HWmsM4qksTnZY1TMz0NRauysaUAmt2+oxM1tCM6k8mS74WXjIdm8O+JdWg36oKgXqgnzb3TvRXvZEneN6YPNIFw7MY70W5haXnlUHbp3f+b/wW4ABAAtWTLcKdqLcAAAAAElFTkSuQmCC") no-repeat scroll 2px bottom; padding-left:22px;}
a[href$="&dump="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHzSURBVHjajJPPS+NQEMcnaaxpdWsp6Q8vtWtdkIo9+B948SjIgruCUg8F/wGP/glePe5JcBehwl4qePGm0J6KQj30UBHEzaFLUromTfPizJMnrxhhB4bJvDfzme97SZQgCOB/be98J2AsAMYYMP81KjKg0WhMYljHtS30RSz4gjkGdot559F7OLt8vvi1bJRBURS4vr8CTTQ3m80SFv1MpVJlwzBA13XuNGUwGKyY1p+Vk9aPzWw8C7ZjQXximu+9ATA5KhQK5Uwmw+nCIpEIJBIJOLjah3Q8w7379x5urFsOUEUhTl/C6R+ef35mARzPhW6vC+q/iHvyvaYwXwIQje6j1+tBv98H13VhNBpxxyPA5tw2TI50MPQsrMbXbOo53fmtaJIC7iSZAMPhkOe+73MA5Ruz3yCfz9NlvykLBUSjUR41TQPP8zhE7JNSyj8E0CbJpkiXKRoIRFABeQcQd0DFwlVV5evUTFBZRSiATEwnp4lCAa0LI2AoQC4WimRl4qgyYOw12rYNyWSSX6L4mKiBnukDK5VKYJrmmBpZwW6r1TotFotTuVyOQwQgnU7zV9npdKDdbj+hgnXRN/Yz1ev1zwg6QP+KU2disRiXblkWOI7zhJOPce+wWq2aoQDZarXaJ2xYQGfod5VKxQ2rexFgAI4OiAKxKkWeAAAAAElFTkSuQmCC") no-repeat scroll 2px bottom; padding-left:22px;}
a[href*="&import="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gEJFDQPlDJUDwAAAiNJREFUOMutk0tI1FEUh7//Y9TJghyc1KQ20lMthRAlgoKgVkWte6wid0EICUHUQjdBErRqHYmQghgU5KLQGB8FKVEMCi0G1JmRbPLJ/O89p8XYOAMZBB24HM5dfL/fOfdcB6Aj1j6kqm2qWv/o5NMk/xBOR6z9dVVpzbmQEyKxPMcBc5svbheHs91YK1hRjJWCY7FGsSKT3VcPtviquqaqVJVVY6xlZu0hYpRrpyJ/Vb7fN3sMwAG4965Hw+ElKrzdlPphPqTHaYw0EdiAQEwuW4MRg7GGzrYu7j6L8/hGg+MD7DNXmF7tpDpSg6MOYpWbzbe2VV/dMATGAuADTLt3UFEmU+OICCpK72hqW8CFExGymwAAnrya15X1QJ+PJFVVtW90QQvjRay4TmfW9XrPpOYdBFYQVXwP+mMpPM9lYCyF44K7KTI4kQJVQj4cqd1BNihowVpBAd9zuNQSZXAizcWWPXmH/WPJonp27ifGCEUOVMB34eXHNJ6Xy5C7+w3xHRDg6N4ylEKAEVSVkAfnm6MMTy1y9nhlXvHNpzSthyrYFfYBiCcylJf6WwAjOZrnOgxPLQLks+tAIDDydSkPrIuWYG2BA2NMbgYunGms5O3nRU43bDkYGEtzuTWar+OJDN5ma1szUKVh/07mv69TVxXm28JK/i/U15YQT2SKdkFEpeAV9P2D3pmmrJXywFgCY7FGCKxgrPnjMv1Y3hjif8QvwdlGGi2XXTgAAAAASUVORK5CYII=") no-repeat scroll 2px bottom; padding-left:22px;}
a[href$="&import="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gEJFDMETKEbQAAAAjZJREFUOMuVkjFoU2EUhc//3gsvptFCIdRHh2CrQ1AcmsUYHTKJDkJrFUdx6uJkpuLspCI4xaJLNik4SMGlOKgEdekQ0EEwFhJqCw+a16RJ//+/x0Heo6XN4B0v537nHLgKAKqNxXckSyTPPyu//IP/GFVtLL6f9INrKZXC791f3UvDysPP3tryjcHt7yTPkRQRaZL8KSKvRGRtbm7OxgCPZJ8kJtOnYaw99ZUfl8UQ5XK5kMlkQBI7OzuzURTNbmxs3Nne3v60srJyd2FhoQ0AztPLtflOv/22tdtCVo3hwvhFUATZbBaO48B1XUxMTCCfz6NUKmF6evqKtfZxnMABgOdXl+c7vTZ87wQUFcRyZOepqSmIyPWkAgA8+HCfFMG3rS8QEVCIvb09pFIpkES/30cYhmi325iZmYGI4BDgReW1Wl1d3apUKrler4coitBqtUASxhh0u10Mh0N4ngeSRwEAQBIk4bou0uk0PM+D53nQWsMYA/JfLRGBtfYoQEQSx/hIKQVrbbJzHGd0ghgQHxhj4LourLXQWkNrDdd1E81IQCy21iaAOEFcU2t9PEBEEvcYeDBZrNvf38ehPwAAay3CMEQul4Pv+4f/XSkEQYBisYhOpzMywb1Go/GmUCiM5fN5+L4PpRRIIggCRFGEZrOJ9fX1TWPMzQR+0Kler58RkUcicstxnPFMJgNjDMIwxGAw2DTG1K21T5aWlraOBRycWq120hhz1hgjWusf1Wp1eJzuL3uxkTGLHB98AAAAAElFTkSuQmCC") no-repeat scroll 2px bottom; padding-left:22px;}
a:link,
a:visited,
a:active
{
color: blue;
}
a:hover {
color: blue !important;
}
a.edit-all{
background: #fff;
}
/*
@media all and (min-device-width: 881px) {
#menu .links {height:22px; transition:.2s;}
#menu .links:hover {height:5em;}
#menu .links a {color:transparent; transition:.2s; display:block; margin-bottom:-1.25em;}
#menu .links > a + a {margin-left:22px;}
#menu .links > a + a + a {margin-left:44px;}
#menu .links > a + a + a + a {margin-left:66px;}
#menu .links:hover a {color:blue; margin:0;}
#menu .links a:hover {color:red;}
}
*/
#menu h1{
background-size: 9%;
background-position: top 16px left 18px;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABbmlDQ1BpY2MAACiRdZG9S0JRGMZ/amWU0VBDSIODRYOCWERj2eAiEWaQ1aLXr8CPy71KSGvQ0iA0RC19Df0HtQatBUFQBBGNzX0tIbf3ZKBEnsu574/nnOflnOeAPZLXCmZHAArFshENhzxL8WWP84Uu3HQTZCKhmfrM/HyEtuPzDpuqt37Vq/2+f0dvKm1qYOsWntR0oyw8LRxZL+uKt4UHtVwiJXwo7DPkgMJXSk82+FlxtsHvio1YdBbsqqcn28LJFtZyRkF4TNhbyFe03/Oom7jSxcUFqW6Zw5hECRPCQ5IKa+Qp45dalMz+9wV+fHOUxKPJX6eKIY4sOfH6RK1I17TUjOhp+fJUVe5/8zQz48FGd1cIOp8s620EnDtQr1nW15Fl1Y/B8QgXxaa/JDlNfYhea2reA+jfhLPLppbchfMtGHrQE0biR3LItGcy8HoKfXEYuIGelUZWv+uc3ENsQ57oGvb2YVT2969+A0VSaCp9B4rPAAAACXBIWXMAAAsSAAALEgHS3X78AAACxElEQVRYw7WXS4hPURzHz73+5TUrymthgUbMeIahaWI2ZmpkijxKeWwosmFDyWIQkmJlI4qdvBYeKWSQEmXhMbGgqTFhYqNpvPl+556j0+l37rn/6/jWZ6b7O/f+fr9z7++c8/snKqCHr6bZl4tAG2gCtWAsSMAP0Au6wB1wCbzkAw21Xbn+KyqsFKwGe0Bdjp+JmhZwELSCGyHnFWeGrurBKTBfVadrRYKb2fm0HjwqEfwz2Fz0Zt8n2AGOqnLaCd4KNVQDloAroQQ2BIL/Ap3gHngN+sEowEgjwUnPc6yLLWCpLtRBJU4NzNCvfajg4Cc4AQ6DHmMMVbn236ST5or5AGaC924NpLrgpOB8pY1gux28oEZov4m+HgOOS0W4DswTHHSDhZxMyZrYB6Y4tjXa598EmN0u4eEveuPpUeX1zGPfbRchs5ku3NSBb/xc/ZtOgxVgmWPn9TjzBlYKD34Ex1Qc7fXsQe0mgcXCDWfBQKQEnoD7gr051d+/Xhi8ruLqqmCrYwITwDBP1jH1VLBNSvXuJakvcgK90h6RWhvE/9Zv5anEfs8DoyMnMF6wDaT61XwTBmdFTkAq9DdMgKebtNm0RE6gVbC9MPvAXWGQx/LwSMF5FjQL9k6TwHlhkA3ntkgJdAjFzqK8aPoBDvJgn+oWicoajW6f5wL9QDv+XRaG2De2VaxsDqns4LDFjuddIEDecIPKtnRJB/jHbsnOqKzhmKuv2QFtxAy/lkxglcoakRphjJ/8gdkHjLgaNgET8Ah4XOJ781i/AM55gvfpiQ4qEWbAdpzNwhyVNSSuWJjLwU1dGzy2TVPKhrMxJ7nvKtCUGtHhJ8E+WWWHSpnlyeBrWfm2MXgOWAny3tsq6+2rFd8S+8Bb7kBahZOtJYPzh8hsKbi7CvI0RO+M1Ygd0H6sotzfiEUT4JJcoEr8PA/pD2HcmchgSlm1AAAAAElFTkSuQmCC');
}
#menu ul#tables a[href*="&select="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHkm9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1zztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wGhGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUHYJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWluUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhNTWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7nHADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGFrwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=") no-repeat scroll right bottom; display:inline-block; vertical-align:middle; overflow:hidden; padding-left:16px; width:0;}
/*
#menu ul#tables a.active[href*="&select="] {border-left:2px solid #00f; margin-left:-4px; padding-left:18px;}
*/
#menu ul#tables{padding: 0;}
.links a {margin-right:8px; display: block;}
.links a[href*="&create="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ6SURBVDjLpZNZSNRRGMV//2XGsjFrMg2z0so2K21xIFpepYUiAsGIICLffI8eWiBBeg3qQV+KwBYKLB8qpHUmrahcKLc0QsxldNSxdPz/79LD1ChBUXTh8sG93POdc75zDa01/7NsgGvPR09rzQmpVZZSCqlAKIWUCqk0QqoZWyKFRir1uvxIbsAGUFqXHQqkpP1L57M3Pm5MMJBKpQHUdF9BKIGQAlcJXOlOVykSdye3leO6MmkGQNyHw+uO/1X3bzGBK+S0B1IqAKqDg3986HeCZPffwvJtoNT7lOZLvUdtAPEDAKBkRzo3QwMUb89InN1uGGD3spdE214xe8MRUnM2MfppNW0Pqy7YAK5UKK2xLbhdP4hlmdxpGMQwwQT8ziNiI534c7cT6WrFazikzF2Eb8HS1IQEDdiWwcHAQmpehTkQSAcgNvSMiYFW5uUUMdV3HW+ywefGNqITJsbUUL75k4FWYJtQ+yaMZcXrk1ANk/33mbdiD7EvlRieETy+FJLkMFcjRRSW3emIAwiF1hqPBfu2LGSWbbA1uZ41SfWkrtxPrPcypsfFiWYzFGzGKTjFV28WEJeIUHETLdOgrmkI1VdHpCdEet5enP4qLK9mKrqMgedv6cyrAP+qxOTiUxAi7oEJi8frELoFoTLpa7nI/HQvscgSRt+0kV1SSW7qYtp7xrBMphm4Mi5h/VIfTcEq1u0oJaknSEdNiMYHET7UvcMpPEN31Ed7zxgASmk1I0g6dK66s8CRak5mVxjnfS05+TsZCw/T9baTx1nnGb47DrQksjE6HrsHYPz6nYt3+Sc3L8+wA2tz0J6pF5OD4WP7Kpq7f5fO79DfSxjdtCtDAAAAAElFTkSuQmCC") no-repeat scroll 2px bottom; padding-left:22px;}
.links a[href$="&create="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIpSURBVDjLpZNPSFRRFMZ/749/Kt3IqFTSRoSMmrGIYTTbpEJtjBCCok1Em9JVG1dRC8FFEES5aGFEgRRZWq1iLKKxBiNqLDcltQgmHR9hY6LOu+feFm+YGVsZXbh8nHO53/nud8+xjDH8z3IB7r5avGgMZ8XoBq01okFpjYhGtEGJLtmCKINo/XbgVFPUBdDG9PVEq0P/UvnSvdlwQYFoHQIY/3obpRVKFL5W+OIXUVThrL91AN+XihKCwIeTu85sqPryqsJXUvRARAMwkshsiKB7fw25UgKVJwA40V7H/cl5jh+oL+RGk/P0xIqxl11dr8AXjTYG14HRNxkcx+ZhMoNlg52/ND6VAWMoc6F5+2Zy/l9PMIDrWByL1jI+tcDRaN06BaXxbDqLUnq9AqPBteHpuwUcJ0AIcgBXH93h+/wEyyuLrPk5cmv7gNY8gdIYYyhz4PDeWuIpj85IsS2ujQ2zJAk6DkZpqGnixcwYyU+PifUOX7Eh6DoAx7aIpzwA4imPeMrj+bTH+88PaNkZQWwhsrULsXxie9oAzgcESgUe2NAZCeE6AXZGQhwKh/Cyc5RZVXQ39wFwoeMmjXVhgMqiB8awe0cVP36u0Fi/iW9zvwuzkF3+xUz6Nal0gv6uWww+O02lUwGwmv8FM3l55EtLTvQWXwm+EkRpfNEoUZRXHCE5PUFbuJ0nH4cot1wSH14C3LA2Os6x3m2DwDmgGlgChpLX0/1/AIu8MA7WsWBMAAAAAElFTkSuQmCC") no-repeat scroll left bottom; padding-left:22px;}
.links #content a[href*="&database="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKRSURBVDjLhVNLTBNRFD3TTju1FCcBaxuaQEr94ydiZIHGpcFISBOi0YREZWHCVoyRxKUxxq0LXcACQyLsjO6KjSEiDfHDz0S0CLSxlFKd2g7MTDudGd+bMAQCxJucuXfuu+fcO/PeYwzDALVoNMqRuI3guq7rR4g/SEBC/Svxc8T3EUTD4bCGTcZQAUI+RvxLr9d70u/3o6KiAm63G3Qtn89DFEUkk0lks9lRkrvW3t6e2lCgRZFI5F0ikaDtjN1MVVVjYmLCGBoa6qccC7Z1kQafz4f/WSAQAGlyaXOOpQ+SNNUymQxcLhc4joPD4TBzkiRBEASkUimEQiGzdlcBlmWRy+WgKIr5Xi6XUSgUUCwWzTVN+IAzeOOde71orP0eAaOkbrDWf6Cw2+3mBLSYgny3KULXPOUY2BUB/hMd4IOn8XfhMGYjvU+2TECLLRLDMNA0zYw5JYa6Ghke/hyEn9/gZEqo3OuHp7qW3yJgESjoNPSdlb8gWCOCr29BMT0Ip5tBYnIWqlL6o8irzVsEaHcKSqQCen4cweok+FAblNRz2JxlODx1cEkzGWmVbTl7Z/jHhgCF1Z3GYjIKf+U8+ANhQn4Gm6OMUiGI9MhHg5Gl1sbu8UnKNc8B7Ui3ipxEcwvlpVFw6hz2N1xGabkXdqeBYqEOmfefEZWac4e6xz9Z22hbn+BmLBZbi8fjEBdG4NF/QdUDSM88hQ4FawKJR6cxLDZl86qzZdtdoDYwMBAkQg/2LL/ovNLVh++Dd7G0OAau9hTkrKgnnE39GW3f/Z6enpUdBSx7ePu4eq+zi4VNw+TbV0gsxFd5b9X5i4+mpnY63tsErl6okhvrfWzT0SAMR3FMXsnean08Pb/b/fgHqpjCspi90kkAAAAASUVORK5CYII=") no-repeat scroll 2px bottom; padding-left:22px;}
#content p a[href*="&create="] {padding-left:22px;}
#content p a[href*="&select="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHkm9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1zztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wGhGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUHYJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWluUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhNTWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7nHADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGFrwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=") no-repeat scroll 2px bottom; padding-left:22px;}
#content p a[href*="&page="] {background-image:none; padding-left:0;}
#content p a[href$="&database="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIkSURBVDjLpVNNiFJRFP7eU1E0KSLTMpAwYSxyaidDtChm0WYQ3NSutv2s2kwwm2igNgMtooUQEQhhA9GqhSDTQsZZFDbNDBgVg5bSw9J8rzFF33udc+HGg0ladOHj3nPe+b7zc99VbNvG/yy30yiVSl4SnCNcsixrivYEgY7WJu0faX9EKGUyGVNyFFkBkY/T+WkoFEpFIhEEAgH4/X7w916vB8Mw0Gg00G63y+S7mM1mm4LIAYxisbhSr9c5nT1pjUYju1qt2oVC4YnkqbIUMk6Ew+F/9hyNRkFJLuyaATmFoqZp8Pl88Hq98Hg8wtfv99HpdNBsNhGPx0XsRAG3241ut4vBYCDs8XgMXdcxHA7FN/b9VUD25HK5RAUczKC+hYgcNpNN05xcAQdLkqIoIlj6VFWdXIEUkAQGV8M2k2vaG3z6sYGfVR39XzsHlm/dX3h5d31xlwAHM5goBd5+LuO75z3OnU3jyP4EVrZeKGub2p309cP7VKcAQ2Znoiz3deMVTk1Nw1RNTB+ahamMkD45w7RrfwSYwFdFf6K4Quf6pmvwKHswl7wh7Jvnc4gfTPHR52zhcqVSeZZMJgOxWEyI8BC5CmOnh63WKtZbZczPPsa94hX4XCLJQHG+xnw+f5SEFghZmvhefgvcTqn2HN3gBmZSZ5CInMaHr1Wsvivjy3ZvSZn0nHO5XJDIxwgWDbW2vL10m9xXCUGCQXi49qA1/xvyq6BCh7yZeQAAAABJRU5ErkJggg==") no-repeat scroll 2px bottom; padding-left:22px;}
#content p a[href*="&edit="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJvSURBVDjLpZPrS5NhGIf9W7YvBYOkhlkoqCklWChv2WyKik7blnNris72bi6dus0DLZ0TDxW1odtopDs4D8MDZuLU0kXq61CijSIIasOvv94VTUfLiB74fXngup7nvrnvJABJ/5PfLnTTdcwOj4RsdYmo5glBWP6iOtzwvIKSWstI0Wgx80SBblpKtE9KQs/We7EaWoT/8wbWP61gMmCH0lMDvokT4j25TiQU/ITFkek9Ow6+7WH2gwsmahCPdwyw75uw9HEO2gUZSkfyI9zBPCJOoJ2SMmg46N61YO/rNoa39Xi41oFuXysMfh36/Fp0b7bAfWAH6RGi0HglWNCbzYgJaFjRv6zGuy+b9It96N3SQvNKiV9HvSaDfFEIxXItnPs23BzJQd6DDEVM0OKsoVwBG/1VMzpXVWhbkUM2K4oJBDYuGmbKIJ0qxsAbHfRLzbjcnUbFBIpx/qH3vQv9b3U03IQ/HfFkERTzfFj8w8jSpR7GBE123uFEYAzaDRIqX/2JAtJbDat/COkd7CNBva2cMvq0MGxp0PRSCPF8BXjWG3FgNHc9XPT71Ojy3sMFdfJRCeKxEsVtKwFHwALZfCUk3tIfNR8XiJwc1LmL4dg141JPKtj3WUdNFJqLGFVPC4OkR4BxajTWsChY64wmCnMxsWPCHcutKBxMVp5mxA1S+aMComToaqTRUQknLTH62kHOVEE+VQnjahscNCy0cMBWsSI0TCQcZc5ALkEYckL5A5noWSBhfm2AecMAjbcRWV0pUTh0HE64TNf0mczcnnQyu/MilaFJCae1nw2fbz1DnVOxyGTlKeZft/Ff8x1BRssfACjTwQAAAABJRU5ErkJggg==") no-repeat scroll 2px bottom; padding-left:22px;}
#content p a[href*="&table="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJcSURBVDjLpZPtT5JhFMafrW997I9rscA+FFu2QRurtlw5cQ4InLpwBogIPNFSiNJ4C+JVkj0QTBHQKFPQlJfwlanY1tXz3ARkn2jd27Wz++yc33XOvd0UAOp/RNGR/X5zeH9rOlTDVKAK3fsqJrxlqN27GHPuYHh+G4rXRQzZNjEws47Hli/oo/PxNsAU3qvWT3/gX3TPuHrWBhiC30nSktXDtKLB1NI4NKkxqBMqjDByPFkcxNBCPwbCfXgUeEBq705m0AZM+qsk2e3hau88W+4ANOy+XPLFQrkrcbW31KkOYJx9rBaAOzPR0gVHW6x593q9cDgcqB6e4sZoogMYdXzD0ck5ZhfLsHGKVfAqVoadKcMdzcLr82PuwwZCoRACgQCWVzdhoK2gaVpDAMNzWzhkAXamQpze/I4t13w+j2AwiFwuh7W1NXg8HmQyGSgUCshkssuU3F7AQf0c84kK3n68KFc4hXQ6DavVCqlUCqVSSdaIx+NQq9UGMsHg7Ab2jxtwp5rOvqUqia3CUqnEObWn0mp1KBaLcLlckMvloPpfrhOAl230/SGLxQK3241CoQC9Xg9nskKk1emQzWZZkBZCoRBU3/NP2GMBgXTTObjSjI1GA8lkEgzDwO/3E4iObXY6nYhEIhCJRHoWcIW6b1pF7egMlYNT7NROUKzU8XX3GJ+3D2E0GgmAm4Zbh2s0mUyIRqMcAGKx+BIlMeSiYu1K/fbEMm4+TaFnJIHrSgZX5TFIZNPo7e1Fj9QOs9kMlUqFaw9pCASCnzwe7x15xG6/rUQiAZ/Px9/5XyhZOMVGKlOdAAAAAElFTkSuQmCC") no-repeat scroll 2px bottom; padding-left:22px;}
th a[href*="&table="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHkm9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1zztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wGhGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUHYJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWluUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhNTWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7nHADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGFrwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=") no-repeat scroll 2px bottom; padding-left:22px;}
#content p a[href*="&schema="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFOSURBVDjLtVK7SgNRED0b9iuM2lr4QK1DQIyk0FZsJAj+gH+ilRZb2NjaRHTLmA9QFKz9huzm7t37Hu+u7IJgQjR6YLjDzOXMmcMERIR5EE5qXA4z4sqACYWEC5wfLQXf/WtMIuDSoL0A7DZDjBj/uYI0l8jzEEJYJMkvCEZM4PqZIxlzpGk+kSCY18TGtGYcx9Tv96dOqBUMBgNyzsFaC621312Ac+59yJFlGRhj5VvVoigKvniglEK32w1mkd3r9ejPPAjOhqdknYX18p1/rzo3pYqTh0OSRkJI5UMgPn4s61sX66SkhtEGcISGsQad5gH2FvehfV5BaIF2cwet5RZyKeu68pe5ubKG7dUNP5AQGltMN57Mosgr5EIiVQmYGvtc1PVicqHY+dXpk8Dg7v22XKFo1ARe9v1bDOlXKKKCs4Sn1xdU1v3vIc2CD3bN4xJjfJWvAAAAAElFTkSuQmCC") no-repeat scroll 2px bottom; padding-left:22px;}
#content p a[href*="&privileges="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGnSURBVDjLxVM9T8JQFD2lBRQRFPAjEhIwXRgwEUjERRMnZPYXuPoHSJz8BQ7+BCcHJzZHiST4MWC0fsQBJUKCEQnGWihtfa/QBgK6MHiT2/tu3+1559x3y2iahlHMghFtZACuUqmkSdyiiaqqoJJo7HVFUQZi1w+Zcrnc9vl8LAXo7YexHhaNdaFQUDiSsFarFftXClriJz4eTqHJX7DMhDEbiiDlfALP80if1CFKLYjfxCUZR9s8ZcByvadG7w/QLl/guVRC8U2Etnutv5dlGXvr44S+3ZRFjcrgjEQvnFvG2pIfGzYOZ5c3KLCsWZjNZvual0wmOwD0oX/cVnFeXQDHfcDpcuGqtYJaTQKcHYBEImGebrDuY1AvPWImtIhjLoraSwtjHhvmv17Nwnw+/zcD/0QDt+9TUD1TmJ6zQWpImFTfyM64XhiLxdAr17h2E2Bnc9XcEEURzWaTFARM2na7HW63+3eAEul8tVqF1+tFMBiEw+EYmDpBEFAsFhEIBBCJRHQAhgyDQEDCFCgejzO5XE4bNn2Gp1IpJpPJaF05d8y//40/Nlww9OOVWvkAAAAASUVORK5CYII=") no-repeat scroll 2px bottom; padding-left:22px;}
#content p a[href*="&event="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJlSURBVDjLpZNbaM9hGMc/v8NsTqF2yMhZKIexmpFyRZIiblwouZDauLYoTVEryg2uXIoIOUU5zJkh4e9QDmtJbWxrbUzz/72/9/m6+P3HLslbT9/3ufm+n/f7Pm8gif9ZMcDxe717JLZ62UQzwxukZnhveBOptyHl8anwZk/3b5pZEwOYtGNDzejSfzm58dTH+b8JvFkpwMizdSCBT8E8OJftkzy4BPIOnONHQzPO+eIhBoM5CCrLwNKslBZM8uDykCbwtgMAl/o/GXhvBYMA2rtAlpGYZSR+UIGKCgCSggGSOHy1Q/0DTifufZUknbr/RZJ0+mHWn3mU9edbMu3qG9DmQ08lKSNw3jCJOIKzjzqJopBzLZ3EEVx40smDr/u4e96QGUXPGpkzYQSJywjCwSsIiKOADUvKiUNYX1tOUQhra8oJg4hZ02cQhhGrqyuyp03tTwbOGzKIQ7j8rIsn3Qd4fEVIIn6+kzAMaH35Fn37wbZD68gnCUl+EbAkI3CpIYmiCNZUlwEwbfIUgiBg1cIyJqbzGFPiWbl8GXUb66mqnkrJ2IvUbq88GEI2dQBRGHDjZTcAbZ8+ERDQnOvm+fszVM1egA89C8avwAeO2nlLAeqRxK7j79TzPa/mXJck6darTG8XdM3uhbry+piGrou5I1pcP17h7wwk5k4aRUfPANMrhtP2pZ8J44bx7nMfff29vGl/SNP1LQA0XdtCa2cO4GdhkPRg78kPVYm3kS71uNTjU8N5I/UpxSWracndZOn8ZVx6dZRhQcz9F3cAjgR/+51rt1c2AXXAaOA7cLTlcHvDL6y6kIpO9lqsAAAAAElFTkSuQmCC") no-repeat scroll 2px bottom; padding-left:22px;}
#content p a[href$="&view="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gEJFwohC2f85AAAAsxJREFUOMulk8tr3HUAxD+/1z5+u5smMYlmm6R1rTlEmrY0RKqtWMVWW6qtePBv8NaKUFGUgmBB9CJ48aIH8SKGBhGKKEIaPdgam0gTQ7Bm3U2zTbKPZrP7+32fHkqDx0LnNocZmGHGsdbyIHB5QPj/J8Vi8bDV8m0RtY5qGaeNMVijsdbiOF6cDDNXw47u8/l8/so9jXMvQqlU+lK0m6+LdjMRBAFCCBq1DYRU+L5P944OtIiRxtru/qHvhh7d8/K2QalUutysrx/zHEu5XGZl9TbWDUilsygDSimMbJGyEYVdAwB09g3MPTayb9RfXl7+RLTuHHOtYn5hkYHCCH5nAW0sUmmEVCiliIRisL8HWf8b0apj4qW9CvcL5+bSX6uNjcrD2gkYPTDG7zf+YWsrRinF9I8TWGt5Yvw4QioSgc+rx8e5uThPeWGGRrOt/Np6pa83v4ue3j4AlFBEsUDru+UBxEIihdwue7DwOKl0yPTlS77f0z9kMtmcp7XGdV2ymQRr1Qax1AwfeA6pNHEUEwvNYL4XYwxaa7Kd3QzsLlhnfm6mms11dOU6H8L3fep3WswuFFmrNu7ml4pYaKJwllv2Gk1RRciY8f7nGW7tEd7Zc28WNjcqB0W0heMFpNNJUgkPqRSbm1toY2lnZmj2/cYzB5/khf2naGf+ZerWNyyVVyqOtZbZ63/8EtVWDyV9j0xXby0Z5qJkmBGu5xuAcxOndr924kXHeA6nH3mPj+bO4OPy1beTkQ8wum//U9NXpi7drpRPhBtrXWEYkkikcIMEAGvNFQLTwUs7zwLw1t4JJosXgcnU9pSfPnzkla8//zRZbtRPR7E447ru0cB1soBTjdbTf1Z/4lrtB94d/Z4Pr58k5aYAIud+3jh2Ifhg53D4zpGRZxnuOsRi7VembvxMebH1sXO/dx67EFwE3gBywCbw2dX35fn/ANYEZmpcDQc/AAAAAElFTkSuQmCC") no-repeat scroll 2px bottom; padding-left:22px;}
#content p a[href*="&refresh="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAI/SURBVDjLjZPbS9NhHMYH+zNidtCSQrqwQtY5y2QtT2QGrTZf13TkoYFlzsWa/tzcoR3cSc2xYUlGJfzAaIRltY0N12H5I+jaOxG8De+evhtdOP1hu3hv3sPzPO/z4SsBIPnfuvG8cbBlWiEVO5OUItA0VS8oxi9EdhXo+6yV3V3UGHRvVXHNfNv6zRfNuBZVoiFcB/3LdnQ8U+Gk+bhPVKB3qUOuf6/muaQR/qwDkZ9BRFdCmMr5EPz6BN7lMYylLGgNNaKqt3K0SKDnQ7us690t3rNsxeyvaUz+8OJpzo/QNzd8WTtcaQ7WlBmPvxhx1V2Pg7oDziIBimwwf3qAGWESkVwQ7owNujk1ztvk+cg4NnAUTT4FrrjqUKHdF9jxBfXr1rgjaSk4OlMcLrnOrJ7latxbL1V2lgvlbG9MtMTrMw1r1PImtfyn1n5q47TlBLf90n5NmalMtUdKZoyQMkLKlIGLjMyYhFpmlz3nGEVmFJlRZNaf7pIaEndM24XIjCOzjX9mm2S2JsqdkMYIqbB1j5C6yWzVk7YRFTsGFu7l+4nveExIA9aMCcOJh6DIoMigyOh+o4UryRWQOtIjaJtoziM1FD0mpE4uZcTc72gBaUyYKEI6khgqINXO3saR7kM8IZUVCRDS0Ucf+xFbCReQhr97MZ51wpWxYnhpCD3zOrT4lTisr+AJqVx0Fiiyr4/vhP4VyyMFIUWNqRrV96vWKXKckBoIqWzXYcoPDrUslDJoopuEVEpIB0sR+AuErIiZ6OqMKAAAAABJRU5ErkJggg==") no-repeat scroll 2px bottom; padding-left:22px;}
#content p a[href*="&sql="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ5SURBVHjapFNLaxNRFP4mnZmQZtKYpJ2I8ZE0NSbSWKpgBYNUhIJQUDddCaILwb34C0RcCi60vpa14sZFoSjxUWxTFEubFkxf9kFS+7Jp0yQmM5mH905SF9pSwQt3vnPnnvPNd86cA13Xsds+23XKsdMdQx//s0z/6hi54he3e8/0d3ZuK0FTFGhUJkVVhSbLUAiq5IxSCQrBEkGWOu8Lh38HGrlpWnlXCKhNSbZQo3cEE9FomYAuKZstE2wFa8RR1cpKqK2o4JhxmLVJVAlh5Df6IFj5MgENcHq9EAMBg2RucBDVLpdxVon0iXdvIf8sQHRIsNReht3XjI3ZI8iuPAOrkDyorBq3G6vT08ikUuAsFiN46HkXXL56eI41QV1/BMF+GulvCfCMDFvNXtSIHrC0KDTPhXgc7lAQdQ2thk2XIpewnkzCJvTA4T8PabEbfDWD+ZFxyEUdX94sw6QVCkZlxWAQU+8/YGZgALV+v0HgbWmBNzQMR0M7it8fg+HWwQk2cLkkcvJh5NNFsCVJMgq1ubiE5o4OI5CS8FYrya8b9saLKC48gIlTIG/6sBaLw3PpHrTEMrSXr4kPIaAKFkbjSA0PEVuFlB+DO8Ah2HoB8tITVPE6iplDWOn7jLn0CSQevoDV6TI+zEpUASkkZzaTYrLIrH3C/qMCFEbE4th9OEQexfQBrPYP44d+DuY91eBp+1dGgFVIDb729kKpdJfQtIy2yFNMdN/E5McYzAebUEhOYjZuQXaj5+9W/nOYbl9vLN26doOFScVI9BXmZ6dy9jpnpO1O5dfsRtBxxlk4Xu9mT4Z80DkpVlhZvdp+d3RmpyH7JcAAnHiAVYWMsdkAAAAASUVORK5CYII=") no-repeat scroll 2px bottom; padding-left:24px;}
table tbody input[name*="check"] {display:block; float:left;}
table a[href*="&edit="][href*="&where"] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFUSURBVDjLrZM/SAJxGIZdWwuDlnCplkAEm1zkaIiGFFpyMIwGK5KGoK2lphDKkMDg3LLUSIJsSKhIi+684CokOtTiMizCGuzEU5K3vOEgKvtBDe/2Pc8H3x8NAM1fQlx4H9M3pcOWp6TXWmM8A7j0629v1nraiAVC0IrrwATKIgs5xyG5QiE+Z4iQdoeU2oAsnqCSO1NSTu+D9VhqRLD8nIB8F0Q2MgmJDyipCzjvYJkIfpN2UBLG8MpP4dxvQ3ZzGuyyBQ2H+AnOOCBd9aL6soh81A5hyYSGWyCFvxUcerqI4S+CvYVOFPMHxLAq8I3qdHVY5LbBhJzEsCrwutpRFBlUHy6wO2tEYtWAzLELPN2P03kjfj3luqDycV2F8AgefWbEnVqEHa2IznSD6BdsVDNStB0lfh0FPoQjdx8RrAqGzC0YprSgxzsUMOY2bf37N/6Ud1Vc9yYcH50CAAAAAElFTkSuQmCC") no-repeat scroll right bottom; padding-right:18px;}
table input + a[href*="&edit="][href*="&where"] {width:0; float:left; display:block; overflow:hidden; text-decoration:none; padding:0 0 0 18px; background-position:2px bottom;}
/*
table thead a[href*="&modify=1"] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gEKDjA70u7s9gAAAMZJREFUOMvtksFpwzAUhr9fcUsWyAQewWDIHt6iLrlriBDIBl4maARPYNH6VtAh2FEuCSQksUV77Qc66Ef63nvw5JyLTNA0DXme03UdVVU9PnDOxWEYJk9d109z733MrqLN/oAkiBEJEAjYfqwJIbzsMLu9vC9XoIgxJ94yEX6+meNOoAXACWPAmEsnqQIBx/CFgEGRo0DEdMHuc81vkPd+soy1lqIoaNsWa+2jYG4PkkYoy/IuHMcx6XPf9xj+yL8gYQ/mOAPpeHRKiIdANAAAAABJRU5ErkJggg==") no-repeat scroll right bottom; }
table thead a[href*="&modify=1"] {width:0; display:inline-block; height:16px; overflow:hidden; text-decoration:none; padding:0 0 0 16px; vertical-align: middle;}
*/
table td:first-child {white-space:nowrap;}
.sqlarea,
fieldset, pre, input, textarea, select {
border-radius: 0;
}
input[type="image"]{
padding: 0;
}
input[name="delete"], input[name="drop"] {background:transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHSSURBVHjapFM5bsJQEB2zSIDFJrHYpEtyAyoKJAp6CrqIkBPkNDlBAKXjBEgUpKOBCyQNijFiEZvZl8z7wsjESYpkpNFfPO/Nmz9j6Xg80n/M9fWi3W7fMOnd4XAo8qogAbvO5xKvL6lU6s0aL1kVMDjP5ye/36+Gw2FyOp3EQFqtVtTr9WixWHT5/JhOp6s2ghP4ORaLyaFQiGazGa3Xa0HgdrvJ6/WSpmk0Go0MjnvIZDLVM0Gr1brm/WskEkkA3O/3abvdQjq5XC6xgoiVka7rNB6PNT6ns9nsu+OkpODxeBLBYJAGgwHt9/uzQ8Vms6Hdbie+KYqC+ASTFrARBMx2HwgEaDKZiHqn0yktl0uxtzrMMAyKx+MCc+4Cs13hwQCC1GQy+W3Lms2mUIUygbEqEBLNun8z8zswVgUfLO0WD4Z6kekn8/l8okNM8GFVUMYDoVWQ6HA4bEAzoyzL1O12kbRsJajwhYZhiUajJEnShWSAQaqqKnU6HahEGysXg9RoNPJ8+cwZZLSKp47m8/k5Kxzg4XBocNxDLper2ka5Xq+LUeatilahJLN1mEJ+ZDHKJthGAKvVauJnYi9ysHIqQee1xOsLg3/+mf5inwIMAJMhb74NwG5wAAAAAElFTkSuQmCC") no-repeat scroll left center; padding:1px 5px 1px 18px; border:0; cursor:pointer; font-size:.9em;}
input[name="delete"]:hover, input[name="drop"]:hover {color:red; background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJdSURBVDjLpZP7S1NhGMf9W7YfogSJboSEUVCY8zJ31trcps6zTI9bLGJpjp1hmkGNxVz4Q6ildtXKXzJNbJRaRmrXoeWx8tJOTWptnrNryre5YCYuI3rh+8vL+/m8PA/PkwIg5X+y5mJWrxfOUBXm91QZM6UluUmthntHqplxUml2lciF6wrmdHriI0Wx3xw2hAediLwZRWRkCPzdDswaSvGqkGCfq8VEUsEyPF1O8Qu3O7A09RbRvjuIttsRbT6HHzebsDjcB4/JgFFlNv9MnkmsEszodIIY7Oaut2OJcSF68Qx8dgv8tmqEL1gQaaARtp5A+N4NzB0lMXxon/uxbI8gIYjB9HytGYuusfiPIQcN71kjgnW6VeFOkgh3XcHLvAwMSDPohOADdYQJdF1FtLMZPmslvhZJk2ahkgRvq4HHUoWHRDqTEDDl2mDkfheiDgt8pw340/EocuClCuFvboQzb0cwIZgki4KhzlaE6w0InipbVzBfqoK/qRH94i0rgokSFeO11iBkp8EdV8cfJo0yD75aE2ZNRvSJ0lZKcBXLaUYmQrCzDT6tDN5SyRqYlWeDLZAg0H4JQ+Jt6M3atNLE10VSwQsN4Z6r0CBwqzXesHmV+BeoyAUri8EyMfi2FowXS5dhd7doo2DVII0V5BAjigP89GEVAtda8b2ehodU4rNaAW+dGfzlFkyo89GTlcrHYCLpKD+V7yeeHNzLjkp24Uu1Ed6G8/F8qjqGRzlbl2H2dzjpMg1KdwsHxOlmJ7GTeZC/nesXbeZ6c9OYnuxUc3fmBuFft/Ff8xMd0s65SXIb/gAAAABJRU5ErkJggg==")}
/*
input[name="logout"] {background:transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJHSURBVDjLlZPNi81hFMc/z7137p1mTCFvNZfGSzLIWNjZKRvFRoqNhRCSYm8xS3+AxRRZ2JAFJWJHSQqTQkbEzYwIM+6Yid/znJfH4prLXShOnb6r8/nWOd8Tcs78bz0/f+KMu50y05nK/wy+uHDylbutqS5extvGcxaWqtoGDA8PZ3dnrs2srQc2Zko41UXLmLdyDW5OfvsUkUgbYGbU63UAQggdmvMzFmzZCgTi7CQmkZwdEaX0JwDgTnGbTCaE0G4zw80omhPI92lcEtkNkdgJCCHwJX7mZvNaB0A14SaYJlwTrpHsTkoFlV1nt2c3x5YYo1/vM9A/gKpxdfwyu/v3teCayKq4JEwT5EB2R6WgYmrs2bYbcUNNUVfEhIfFYy69uci+1fuRX84mkawFSxd/4nVWUopUVIykwlQxRTJBTIDA4Pp1jBZPuNW4wUAPmCqWIn29X1k4f5Ku8g9mpKCkakRLVEs1auVuauVuyqHMo8ejNCe+sWPVTkQKXCMmkeZUmUZjETF1tc6ooly+fgUVw9So1/tRN6YnZji46QghBFKKuAouERNhMlbAHZFE6e7pB+He8MMw+GGI4xtOMf1+lsl3TQ4NHf19BSlaO1DB9BfMHdX0O0iqSgiBbJkjm491hClJbA1LxCURgpPzXwAHhg63necAIi3XngXLcRU0fof8ETMljIyM5LGxMcbHxzvy/6fuXdWgt6+PWncv1e4euqo1ZmabvHs5+jn8yzufO7hiiZmuNpNBM13rbvVSpbrXJE7/BMkHtU9jFIC/AAAAAElFTkSuQmCC") no-repeat scroll right center; padding:1px 22px 1px 5px; border:0; cursor:pointer; font-size:.9em;}
*/
input[name="logout"]:hover {font-weight: bold;}
#content h2{ background-color: #333; color: #fff; }
#fieldset-search input,
#fieldset-search select{
margin-right: 5px;
}
/* aperto di default */
#fieldset-search{
display: block;
}
#suggest_tablefields_container{
width: 200px;
}
.sqlarea{
width: 850px;
height: 600px;
}

View File

@@ -341,6 +341,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
}
function selectSearchProcess($fields, $indexes) {
global $driver;
$return = array();
foreach ((array) $_GET["where"] as $key => $where) {
$col = $where["col"];
@@ -356,11 +357,11 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
} else {
$text_type = preg_match('~char|text|enum|set~', $field["type"]);
$value = $this->processInput($field, (!$op && $text_type && preg_match('~^[^%]+$~', $val) ? "%$val%" : $val));
$conds[] = $name . ($value == "NULL" ? " IS" . ($op == ">=" ? " NOT" : "") . " $value"
$conds[] = $driver->convertSearch($name, $val, $field) . ($value == "NULL" ? " IS" . ($op == ">=" ? " NOT" : "") . " $value"
: (in_array($op, $this->operators) || $op == "=" ? " $op $value"
: ($text_type ? " LIKE $value"
: " IN (" . str_replace(",", "', '", $value) . ")"
))); //! can issue "Illegal mix of collations" for columns in other character sets - solve by CONVERT($name using utf8)
)));
if ($key < 0 && $val == "0") {
$conds[] = "$name IS NULL";
}
@@ -451,6 +452,9 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
return " <span class='time'>" . @date("H:i:s") . "</span><!--\n" . str_replace("--", "--><!-- ", $query) . "\n" . ($time ? "($time)\n" : "") . "-->";
}
function editRowPrint($table, $fields, $row, $update) {
}
function editFunctions($field) {
$return = array();
if ($field["null"] && preg_match('~blob~', $field["type"])) {
@@ -654,5 +658,3 @@ qsl('div').onclick = whisperClick;", "")
}
}
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);

2
externals/jush vendored

View File

@@ -0,0 +1,32 @@
<?php
/** Disable tables
* @link https://www.adminer.org/plugins/#use
* @author Andrea Mariani, https://www.fasys.it/
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
*/
class AdminerDisableTables {
function tableName($tableStatus) {
// tables without comments would return empty string and will be ignored by Adminer
$disabledTables = [
'tableName1' => true,
'tableName2' => true,
'tableName3' => true,
//...
];
$select = filter_input(INPUT_GET, 'table', FILTER_SANITIZE_STRING);
if(isset($select) && $disabledTables[$select]) die(Adminer\h('Access Denied.'));
if($disabledTables[$tableStatus['Name']]){
return false;
}
return Adminer\h($tableStatus['Name']);
// tables without comments would return empty string and will be ignored by Adminer
//return Adminer\h($tableStatus['Comment']);
}
}

View File

@@ -1,5 +1,5 @@
<?php
$drivers["clickhouse"] = "ClickHouse (alpha)";
add_driver("clickhouse", "ClickHouse (alpha)");
if (isset($_GET["clickhouse"])) {
define("DRIVER", "clickhouse");
@@ -22,7 +22,7 @@ if (isset($_GET["clickhouse"])) {
return $file;
}
if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) {
$this->error = $file;
$this->error = lang('Invalid credentials.') . " $http_response_header[0]";
return false;
}
$return = json_decode($file, true);
@@ -372,21 +372,27 @@ if (isset($_GET["clickhouse"])) {
return preg_match("~^(columns|sql|status|table|drop_col)$~", $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);
function driver_config() {
$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);
}
return array(
'jush' => "clickhouse",
'types' => $types,
'structured_types' => $structured_types,
'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(),
);
}
$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

@@ -3,10 +3,9 @@
* @author Steve Krämer
*/
$drivers['firebird'] = 'Firebird (alpha)';
add_driver('firebird', 'Firebird (alpha)');
if (isset($_GET["firebird"])) {
$possible_drivers = array("interbase");
define("DRIVER", "firebird");
if (extension_loaded("interbase") ) {
@@ -312,9 +311,14 @@ ORDER BY RDB$INDEX_SEGMENTS.RDB$FIELD_POSITION';
return preg_match("~^(columns|sql|status|table)$~", $feature);
}
$jush = "firebird";
$operators = array("=");
$functions = array();
$grouping = array();
$edit_functions = array();
function driver_config() {
return array(
'possible_drivers' => array("interbase"),
'jush' => "firebird",
'operators' => array("="),
'functions' => array(),
'grouping' => array(),
'edit_functions' => array(),
);
}
}

View File

@@ -0,0 +1,11 @@
Enable drivers in this directory like this:
<?php
function adminer_object() {
include "./plugins/drivers/simpledb.php"; // the driver is enabled just by including
return new Adminer; // or return AdminerPlugin if you want to use other plugins
}
// include original Adminer
include "./adminer.php";
?>

View File

@@ -1,8 +1,7 @@
<?php
$drivers["simpledb"] = "SimpleDB";
add_driver("simpledb", "SimpleDB");
if (isset($_GET["simpledb"])) {
$possible_drivers = array("SimpleXML + allow_url_fopen");
define("DRIVER", "simpledb");
if (class_exists('SimpleXMLElement') && ini_bool('allow_url_fopen')) {
@@ -476,9 +475,14 @@ if (isset($_GET["simpledb"])) {
return $return;
}
$jush = "simpledb";
$operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "IS NOT NULL");
$functions = array();
$grouping = array("count");
$edit_functions = array(array("json"));
function driver_config() {
return array(
'possible_drivers' => array("SimpleXML + allow_url_fopen"),
'jush' => "simpledb",
'operators' => array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "IN", "IS NULL", "NOT LIKE", "IS NOT NULL"),
'functions' => array(),
'grouping' => array("count"),
'edit_functions' => array(array("json")),
);
}
}

55
plugins/fk-disable.php Normal file
View File

@@ -0,0 +1,55 @@
<?php
/**
* Allow Disable foreign keys
* @author Andrea Mariani, fasys.it
*/
class AdminerFkDisable
{
private function deleteAllBetween($beginning, $end, $string) {
$beginningPos = strpos($string, $beginning);
$endPos = strpos($string, $end);
if ($beginningPos === false || $endPos === false) {
return $string;
}
$textToDelete = substr($string, $beginningPos, ($endPos + strlen($end)) - $beginningPos);
return $this->deleteAllBetween($beginning, $end, str_replace($textToDelete, '', $string)); // recursion to ensure all occurrences are replaced
}
public function head(){
$sql = filter_input(INPUT_GET, 'sql');
if (!isset($sql)) {
return;
}
$query = trim(filter_input(INPUT_POST, 'query'));
if(filter_input(INPUT_POST, 'fk_disable')){
if($query) {
$query = trim($this->deleteAllBetween("-- FK:D0", "-- FK:D1", $query));
$_POST['query'] = "-- FK:D0\nSET FOREIGN_KEY_CHECKS=0;\n-- FK:D1\n\n{$query}\n\n-- FK:D0\n;SET FOREIGN_KEY_CHECKS=1;\n-- FK:D1";
}
$fk_disable_checked = ($_POST['fk_disable']) ? 'checked="checked"' : "";
}
?>
<script<?php echo Adminer\nonce();?> type="text/javascript">
function domReady(fn) {
document.addEventListener("DOMContentLoaded", fn);
if (document.readyState === "interactive" || document.readyState === "complete" ) {
fn();
}
}
domReady(() => {
document.querySelectorAll('#form p')[1].insertAdjacentHTML('beforeend', '<label><input type="checkbox" name="fk_disable" value="1" <?= $fk_disable_checked ?> /><?= Adminer\lang('Disable Foreign Keys') ?></label>')
})
</script>
<?php
}
}

View File

@@ -1,8 +1,7 @@
<?php
/** Require One-Time Password at login
* You can generate the secret and install it into Google Authenticator e.g. with https://github.com/sonata-project/GoogleAuthenticator
* @link https://www.adminer.org/plugins/#use
* @link https://www.adminer.org/plugins/otp/
* @author Jakub Vrana, https://www.vrana.cz/
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)

View File

@@ -83,6 +83,11 @@ class AdminerPlugin extends Adminer {
return $this->_appendPlugin(__FUNCTION__, $args);
}
function editRowPrint($table, $fields, $row, $update) {
$args = func_get_args();
return $this->_appendPlugin(__FUNCTION__, $args);
}
function editFunctions($field) {
$args = func_get_args();
return $this->_appendPlugin(__FUNCTION__, $args);

View File

@@ -0,0 +1,234 @@
<?php
/**
* Suggests fields and tablenames
* @author Andrea Mariani, fasys.it
*/
class AdminerSuggestTableField
{
public function head(){
if (!isset($_GET['sql'])) {
return;
}
$suggests = [
'___mysql___' => [
'DELETE FROM', 'DISTINCT', 'EXPLAIN', 'FROM', 'GROUP BY', 'HAVING', 'INSERT INTO', 'INNER JOIN', 'IGNORE',
'LIMIT', 'LEFT JOIN', 'NULL', 'ORDER BY', 'ON DUPLICATE KEY UPDATE', 'SELECT', 'UPDATE', 'WHERE',
]
];
foreach (array_keys(Adminer\tables_list()) as $table) {
$suggests['___tables___'][] = $table;
foreach (Adminer\fields($table) as $field => $foo) {
$suggests[$table][] = $field;
}
}
?>
<style>
#suggest_tablefields_container{min-width:200px;margin:0;padding:0;overflow-y:auto;position:absolute;background-color:#fff;}
#suggest_tablefields{list-style:none;}
#suggest_tablefields dt{font-weight:bold;}
#suggest_tablefields dd{margin:0;}
#suggest_tablefields dd strong{background-color:#ff0;}
#suggest_search{width:110px;}
#suggest_tablefields_drag{cursor:move;}
#suggest_tablefields_stick{cursor:pointer;}
.noselect {-webkit-touch-callout: none;-webkit-user-select: none;-khtml-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;}
.xborder{border: 1px inset rgb(204, 204, 204);}
/*textarea.sqlarea {display: block!important;}*/
</style>
<script<?php echo Adminer\nonce(); ?> type="text/javascript">
function domReady(fn) {
document.addEventListener("DOMContentLoaded", fn)
if (document.readyState === "interactive" || document.readyState === "complete" ) {
fn()
}
}
function insertNodeAtCaret(node) {
if (typeof window.getSelection != "undefined") {
var sel = window.getSelection()
if (sel.rangeCount) {
var range = sel.getRangeAt(0)
range.collapse(false)
range.insertNode(node)
range = range.cloneRange()
range.selectNodeContents(node)
range.collapse(false)
sel.removeAllRanges()
sel.addRange(range)
}
} else if (typeof document.selection != "undefined" && document.selection.type != "Control") {
var html = (node.nodeType == 1) ? node.outerHTML : node.data
var id = "marker_" + ("" + Math.random()).slice(2)
html += '<span id="' + id + '"></span>'
var textRange = document.selection.createRange()
textRange.collapse(false)
textRange.pasteHTML(html)
var markerSpan = document.getElementById(id)
textRange.moveToElementText(markerSpan)
textRange.select()
markerSpan.parentNode.removeChild(markerSpan)
}
}
function getTable(suggests, tableName){
var table = "<dt>"+ tableName +"</dt>"
for(var k in suggests[tableName]){
table += "<dd><a href='#' data-text='"+ tableName + "`.`" + suggests[tableName][k] +"'>"+ suggests[tableName][k] +"</a></dd>"
}
return table
}
function compile(data){
document.getElementById('suggest_tablefields').innerHTML = data
document.getElementById('suggest_search').value = '';
//console.log(data)
}
domReady(() => {
const suggests = JSON.parse('<?php echo json_encode($suggests) ?>')
const form = document.getElementById('form')
const sqlarea = document.getElementsByClassName('sqlarea')[0]
form.style.position = "relative"
var suggests_mysql = ""
suggests_mysql += "<dt><?php echo Adminer\lang('Tables') ?></dt>"
for(var k in suggests['___tables___']){
suggests_mysql += "<dd><a href='#' data-table='1'>"+ suggests['___tables___'][k] +"</a></dd>"
}
suggests_mysql += "<dt><?php echo Adminer\lang('SQL command') ?></dt>"
for(var k in suggests['___mysql___']){
suggests_mysql += "<dd><a href='#' data-nobt='1'>"+ suggests['___mysql___'][k] +"</a></dd>"
}
var posLeft = (sqlarea.offsetWidth + 3)
form.insertAdjacentHTML('afterbegin',
'<div id="suggest_tablefields_container" style="height:'+ sqlarea.offsetHeight +'px;top:0;left:'+ posLeft +'px">'+
'<span class="noselect" id="suggest_tablefields_drag">drag</span>|'+
'<span class="noselect" id="suggest_tablefields_stick" data-pos-left="'+ posLeft +'px">stick</span>&nbsp;'+
'<input autocomplete="off" id="suggest_search" type="text" placeholder="<?php echo Adminer\lang('Search') ?>..."/><dl id="suggest_tablefields" class="noselect"></dl></div>')
compile(suggests_mysql)
document.addEventListener('click', function (event) {
if(event.target.getAttribute('id') === 'suggest_search'){
return
}
if (event.target.matches('.jush-custom')) {
var table = getTable(suggests, event.target.textContent)
compile(table)
return
}
if (!event.target.matches('#suggest_tablefields') && !event.target.matches('a') && !event.target.matches('strong') && !event.target.matches('.sqlarea') && !event.target.matches('.jush-sql_code') && !event.target.matches('.jush-bac') && !event.target.matches('.jush-op')){
compile(suggests_mysql)
return
}
}, false)
document.getElementById('suggest_tablefields').addEventListener('click', function (event){
if(event.target.matches('a') || event.target.matches('strong')){
var target, text, bt = "`"
if(event.target.matches('strong')) {
target = event.target = event.target.parentElement
}
else{
target = event.target
}
text = target.textContent
sqlarea.focus()
if(target.getAttribute("data-text")){
text = target.getAttribute("data-text")
}
if(target.getAttribute("data-nobt")){
bt = ""
}
insertNodeAtCaret(document.createTextNode(bt + text + bt + " "))
if(target.getAttribute("data-table")){
var table = getTable(suggests, target.textContent)
compile(table)
}
sqlarea.dispatchEvent(new KeyboardEvent('keyup'))
}
}, false)
document.getElementById('suggest_search').addEventListener('keyup', function () {
var value = this.value.toLowerCase()
if (value != '') {
var reg = (value + '').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, '\\$1')
reg = new RegExp('('+ reg + ')', 'gi')
}
var tables = qsa('dd a', qs('#suggest_tablefields'))
for (var i = 0; i < tables.length; i++) {
var a = tables[i]
var text = tables[i].textContent
if (value == '') {
tables[i].className = ''
a.innerHTML = text
} else {
tables[i].className = (text.toLowerCase().indexOf(value) == -1 ? 'hidden' : '')
a.innerHTML = text.replace(reg, '<strong>$1</strong>')
}
}
}, false)
//drag / stick
document.getElementById('suggest_tablefields_stick').addEventListener('click', function () {
var obj = document.getElementById('suggest_tablefields_container')
obj.style.position = "absolute"
obj.style.left = this.getAttribute('data-pos-left')
obj.style.top = 0
obj.classList.remove("xborder")
})
window.onload = function(){
draggable('suggest_tablefields_container')
}
var dragObj = null
function draggable(id) {
var obj = document.getElementById(id)
var m = document.getElementById('suggest_tablefields_drag')
m.onmousedown = function(){
obj.style.position = "fixed"
obj.classList.add("xborder")
dragObj = obj
}
}
document.onmouseup = function(){
dragObj = null
}
document.onmousemove = function(e){
var x = e.pageX
var y = e.pageY
if(dragObj == null) return
dragObj.style.left = x +"px"
dragObj.style.top= y +"px"
}
})
</script>
<?php
}
}

View File

@@ -40,8 +40,8 @@ tinyMCE.init({
function selectVal(&$val, $link, $field, $original) {
if (preg_match("~_html~", $field["field"]) && $val != '') {
$ellipsis = "<i>…</i>";
$length = strlen($ellipsis);
$ellipsis = "<i>…</i>";
$length = strlen($ellipsis);
$shortened = (substr($val, -$length) == $ellipsis);
if ($shortened) {
$val = substr($val, 0, -$length);

View File

@@ -2,7 +2,7 @@ Adminer - Database management in a single PHP file
Adminer Editor - Data manipulation for end-users
https://www.adminer.org/
Supports: MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, SimpleDB, Elasticsearch, MongoDB, Firebird
Supports: MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, Elasticsearch, MongoDB, SimpleDB (plugin), Firebird (plugin), ClickHouse (plugin)
Requirements: PHP 5+
Apache License 2.0 or GPL 2

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
@@ -150,7 +150,7 @@
<td>50</td>
</tr>
<tr>
<td>click</td>
<td>check</td>
<td>name=comments<datalist><option>name=comments</option></datalist></td>
<td></td>
</tr>
@@ -383,7 +383,7 @@
<td>50</td>
</tr>
<tr>
<td>click</td>
<td>check</td>
<td>name=comments<datalist><option>name=comments</option></datalist></td>
<td></td>
</tr>
@@ -420,7 +420,7 @@
<tbody>
<tr>
<td>open</td>
<td>/adminer/?username=ODBC&amp;db=adminer_test&amp;table=interprets<datalist><option>/adminer/?username=ODBC&amp;db=adminer_test&amp;table=interprets</option></datalist></td>
<td>/adminer/?username=ODBC&amp;db=adminer_test&amp;table=albums<datalist><option>/adminer/?username=ODBC&amp;db=adminer_test&amp;table=albums</option></datalist></td>
<td></td>
</tr>
<tr>
@@ -485,12 +485,7 @@
<td></td>
</tr>
<tr>
<td>uncheck</td>
<td>name=defaults<datalist><option>name=defaults</option></datalist></td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>check</td>
<td>name=defaults<datalist><option>name=defaults</option></datalist></td>
<td></td>
</tr>
@@ -540,6 +535,7 @@
<td>Trigger has been created.<datalist><option>Trigger has been created.</option></datalist></td>
<td></td>
</tr>
</tr>
</tbody></table>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
@@ -1237,7 +1233,7 @@ END</td>
</tr>
<tr>
<td>click</td>
<td>xpath=(//a[contains(text(),'=')])[3]<datalist><option>xpath=(//a[contains(text(),'=')])[3]</option></datalist></td>
<td>xpath=(//a[contains(text(),'=')])[1]<datalist><option>xpath=(//a[contains(text(),'=')])[1]</option></datalist></td>
<td></td>
</tr>
<tr>
@@ -1255,14 +1251,9 @@ END</td>
<td>link=Warnings<datalist><option>link=Warnings</option></datalist></td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//div[@id='warnings']/table/tbody/tr/td[3]<datalist><option>//div[@id='warnings']/table/tbody/tr/td[3]</option></datalist></td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@id='warnings']/table/tbody/tr/td[3]<datalist><option>//div[@id='warnings']/table/tbody/tr/td[3]</option></datalist></td>
<td>//div[@id='warnings']/div/table/tbody/tr/td[3]<datalist><option>//div[@id='warnings']/div/table/tbody/tr/td[3]</option></datalist></td>
<td>Truncated incorrect DOUBLE value: '1.2.3'</td>
</tr>
</tbody></table>

View File

@@ -2,7 +2,7 @@ Transactions in export
Create view and routine options
Variables editation
Blob download and image display in edit form (important for Editor with hidden fields in select and SQL command)
Add title to Logout, edit (in select) and select (in menu) for style "hever"
Add title to Logout and edit (in select) for style "hever"
Export by GET parameters
Draggable columns in alter table (thanks to Michal Manak)
<option class> for system databases and schemas - information_schema and driver-specific (thanks to Vaclav Novotny)