Adminer 4.6.0

Školení, která pořádám

Prošel jsem všechny pull requesty, bugy, diskuze, osobní maily a komentáře na tomto blogu týkající se Admineru a drtivou většinu jsem vyřídil. Někdo dostal odpověď i na čtyři roky starý mail. Nejspolehlivější způsob komunikace je přes pečlivě vytvořené a otestované pull requesty, případně bugy. Nechce se mi řešit jen problémy týkající se Oracle a MS SQL, které nemám nainstalované. Obzvlášť MS SQL se hodně měnila mezi verzemi a co funguje v jedné, nefunguje v druhé. Takže i když někdo pošle pull request, tak hrozí, že oprava to zase někde jinde rozbije. Pokud by se našel někdo, kdo by se o některý z těchto ovladačů chtěl starat, tak bych to uvítal.

Největší změnou Admineru 4.6.0 je zobrazení varování u prováděných dotazů. Jde např. o oříznutí hodnoty, dělení nulou a podobné nefatální chyby. Implementoval jsem to pro MySQL a PostgreSQL (pro SQLite jsem obdobu nenašel). Mimochodem API pro PostgreSQL v PHP mě pobavilo. Funkce pg_last_notice původně vracela jen poslední varování, ke kterému došlo. Verze PHP 7.1 ale přidala i možnost vrátit všechna varování nebo je smazat. Takže místo jasného API string pg_last_notice(), array pg_all_notices() a bool pg_clear_notices() je jedna zmatlaná funkce mixed pg_last_notice(option). V některých případech dovedu pochopit, že se API změní a např. místo bool přijímá int, ale tohle prostě nechápu.

Další výraznou novinkou je práce s uloženými funkcemi v PostgreSQL. Vypisuje se jejich seznam a dají se volat, vytvářet, měnit a mazat. Práce s nimi je v Admineru asi dokonce spolehlivější než v MySQL, kde se parametry parsují z definice procedury, ale v PostgreSQL se jednoduše načítají z information_schema.parameters (dostupné od PostgreSQL 9.4). PostgreSQL dovoluje stejný název použít u více uložených funkcí, pokud přijímají různé parametry. Adminer pro odkaz na editaci a volání proto místo pouhého názvu používá unikátní ID funkce, které se ale bohužel při úpravě funkce změní. Odkazy proto nejsou stabilní. Pokud by to byl problém, tak by se asi dal seznam parametrů předávat v URL, i když by se získání té správné funkce poněkud zkomplikovalo.

Změnil jsem práci s výchozími hodnotami. Dříve Adminer zpracoval zadanou výchozí hodnotu vždy jako řetězec a jen v určitých případech ji použil přímo, obvykle jako volání funkce. Nyní se jako řetězec zpracuje jen u textových sloupců a v ostatních případech se použije bez ošetření. Výjimkou jsou výchozí datumové literály, které se taky zpracují jako řetězec. Uvidíme, jak to bude fungovat. Uživatel čeká, že když jako výchozí hodnotu zadá 2018-02-02, tak se použije jako řetězec, ale když zadá NOW(), tak se použije bez ošetření. Rozlišit mezi těmito dvěma případy není u všech datových typů jednoduché.

Externí odkazy (vytvořené z URL ve vypisovaných hodnotách) jsem přestal přesměrovávat přes www.adminer.org. K tomu docházelo proto, aby se cílové adresy nedozvěděly, kde všude Adminer běží. Jak prohlížeče postupně začaly podporovat rel="noreferrer", tak jsem toto přesměrování začal na základě user-agenta vypínat. Teď už tento atribut podporuje i IE, tak jsem přesměrování vypnul úplně. V březnu 2018 navíc zruším i automatické přesměrování na stránce https://www.adminer.org/redirect/ a uživatel bude muset na odkaz ještě jednou kliknout, čímž zavřu open redirect, kterým tato stránka v současnosti je.

Opravil jsem jednu poměrně závažnou chybu v SQLite a PostgreSQL, ke které ale naštěstí nedocházelo moc často. Pokud uživatel vypíše sloupce, které neobsahují primární ani unikátní klíč, tak se pro omezení editovaných záznamů použije hodnota všech vypsaných sloupců. V MySQL to nebyl problém, protože aktualizační dotaz je omezen klauzulí LIMIT 1. V SQLite a PostgreSQL ale žádná taková klauzule u tohoto dotazu není, což vedlo k tomu, že se změnily všechny řádky vyhovující podmínce, ne jen jeden. Nová verze to řeší tak, že LIMIT 1 emuluje (v PostgreSQL pomocí WHERE ctid = (SELECT ctid FROM ... LIMIT 1), v SQLite obdobně pomocí rowid). V Oracle tato chyba zůstala.

Zároveň jsem stránku pro výpis záznamů změnil tak, aby vždy získávala i primární klíč (případně i umělý primární klíč v PostgreSQL s OID a v SQLite s rowid). Díky tomu jsou odkazy na editaci mnohem jednodušší, kratší a jednoznačnější. Drobnou nevýhodou je, že pokud si dáte vypsat např. jen sloupce title, tak Adminer ve skutečnosti provede dotaz SELECT `title`, `id`, což i oznámí. Sloupec `id` se ve výsledku skryje, ale pokud chcete vykonaný dotaz dále upravovat nebo někam zkopírovat, tak tam ten sloupec navíc může překážet. Uvidíme, jestli to bude způsobovat problémy. Díky předchozí opravě tato změna vlastně až tak potřeba není, ale přidal jsem ji v zájmu defenzivního přístupu. Umělý primární klíč mimochodem Adminer získával už dříve i u dotazů bez vybraných sloupců.

Další změny jsou drobnější:

Jakub Vrána, Adminer, 5.2.2018, diskuse: 3 (nové: 0)

Diskuse

Milan:

Ahoj, děkuji za novou verzi. Narazil jsem však na to, že přestalo u dodatečných vzhledů fungovat skrývání odkazu "upravit" na výpisu tabulek. Odkaz je často nahrazován za ikonu. Důvodem je podle mě to, že mezi tagy <input> a <a> přibyl tag <script>. Styly jsou definovány pro "input + a". Předpokládám, že jde o vlastnost/chybu vzniklou už při 4.4.0. Nejsem si jistý, zda je jednodušší opravit styly, nebo pořadí výpisů HTML tagů, aby nebylo potřeba opravovat dotčené styly. Pozoruji to minimálně na vzhledu "hever". Díky

ikona Jakub Vrána OpenID:

Přidal jsem tomu třídu "edit", upravte prosím styly a pošlete pull request.

ikona Jakub Vrána OpenID:

Mimochodem, spíš bych na to odkazoval pomocí td:first-child a.

Vložit komentář

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2018 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.