View tables v PostgreSQL

Databáze v PostgreSQL obsahuje informační schéma (information_schema) ve kterém jsou různé pohledy (view), ze kterých lze získat informace o objektech v databázi. View information_schema.tables obsahuje informace o všech tabulkách (tables) a pohledech (views) v aktuální databázi.

select * from information_schema.tables;

Výpis celého pohledu information_schema.tables.

select * from information_schema.tables where table_schema = 'public';

Výpis všech informací o tabulkách a pohledech ve schématu public.

select * from information_schema.tables where table_schema = 'nazev_schematu';

Výpis všech informací o tabulkách a pohledech ve schématu s názvem nazev_schematu.

select table_name from information_schema.tables where table_type = 'VIEW';

Výpis všech pohledů (názvů pohledů) v aktuální databázi.

select table_name from information_schema.tables where table_type = 'BASE TABLE';

Výpis všech tabulek (názvů tabulek) v aktuální databázi.

Jak najít tabulky obsahující určité sloupce v PostgreSQL

Může se stát, že víte název sloupce, ale nevíte, v jaké tabulce se tento sloupec nachází. Informace o objektech databáze lze v PostgreSQL nalézt ve schématu information_schema.

Informační schéma (information schema) je množina pohledů (views), které obsahují informace o objektech v databázi. Informace o sloupcích lze nalézt v information_schema.columns view. Zdroj: postgresql.org/…/information-schema.html

Následující select vrátí názvy tabulek, které obsahují sloupce s názvem nazev_sloupce.

select table_name from information_schema.columns where column_name like 'nazev_sloupce'

Daný pohled (information_schema.columns) obsahuje řadu dalších informací např. datový typ sloupce.

Změna textu na malá/velká písmena v Idea IDE

Občas je potřeba změnit určitý text na upper case (velká písmena) nebo lower case (malá písmena). Pro tuto akci má Idea IDE klávesovou zkratku. Označte text, který chcete převést na malá/velká písmena a stiskněte Ctrl+Shift+U. Tato akce funguje i například při commitu při zadávání commit message.

Stejnou akci je možné vyvolat přes nabídku Edit -> Toggle Case. Pro to aby byla volba zpřístupněna je třeba mít označen text.

idea_zmena_textu_na_mala_velka_pismena

Proměnný počet parametrů v Javě

Java umožňuje zadat metodě libovolný počet parametrů pomocí trojtečkové notace. Vnitřně si Java vytvoří pole argumentů a toto pole předá metodě. Jedná se tedy o zjednodušený zápis oproti tomu, abyste museli sami vytvořit pole a to předat.

Mějmě proměnné

 String ahoj = "Ahoj";
 String nazdar = "Nazdar";
 String cau = "Čau";
 String[] pole = {"AA", "BB", "CC", "DD"};
 List<String> seznam = Arrays.asList("XXX", "YYY", "ZZZ");

a metodu

public static void method(Object ... params) {
    for (int i = 0; i < params.length; i++) {
        if (i > 0) {
            System.out.print(" | ");
        }
        System.out.print(params[i]);
    }
    System.out.println();
}

Metodu je možné zavolat bez argumentů, s jedním nebo několika argumenty a nebo za argument zadat pole objektů.

method();
method(ahoj, nazdar, cau);
method(pole);
method(seznam);
method(seznam.toArray());

Výsledek

Ahoj | Nazdar | Čau
AA | BB | CC | DD
[XXX, YYY, ZZZ]
XXX | YYY | ZZZ

Pokud chceme argumenty kombinovat (zadat jak argument tak pole argumentů zároveň) je potřeba vytvořit pole s argumenty a to předat metodě.

List<Object> objectParamList = new ArrayList<Object>();
objectParamList.add(cau);
objectParamList.add(new Date());
objectParamList.addAll(Arrays.asList(pole));
objectParamList.add(123);
objectParamList.addAll(seznam);
objectParamList.add(Math.random());
method(objectParamList.toArray());

Výsledek

Čau | Sun Jan 24 16:41:59 CET 2016 | AA | BB | CC | DD | 123 | XXX | YYY | ZZZ | 0.37927696865182803

Zapsání změn v Gitu jako někdo jiný

V Gitu při zapisování změn (commit) je možné určit autora. Jinak řečeno, je možné provést commit jako někdo jiný. To se může hodit v případě, že zapisujete změny někoho jiného a chcete, aby změny byly připsány tomuto autorovi (aby bylo vidět, že jejich autorem byl někdo jiný než vy).

git commit

Provede zapsání změn a za autora bude uveden ten, kdo je určen v souboru .gitconfig.

git commit --author="František Koudelka <fk@email.cz>"

Provede zapsání změn a za autora bude uveden „František Koudelka“.

git commit --amend --author="Jan Nový <jn@email.cz>"

Pozmění poslední commit a za autora bude uveden „Jan Nový“. Také se změní výchozí zpráva k revizi (commit message) za tu, která je zadána při tomto commitu.

V Idea IDE je také možné změnu autora provést při commitu.

git_zapsani_zmen_jako_nekdo_jiny_v_idee

Provede zapsání změn jako „Petr Zelený“.

V případě, že chcete změnit poslední commit, je třeba zaškrtnout volbu „Amend commit“.

git_zapsani_zmen_jako_nekdo_jiny_v_idee_02

Změní poslední commit tak, že bude obsahovat také nové změny a autorem bude „honzik“.

Nepodporované verze Lubuntu (Ubuntu)

Standardní vydání verze Lubuntu (Ubuntu) je podporováno 9 měsíců. Verze označená LTS (Long Term Support) je podporována 5 roků. Podpora znamená, že jsou vydávány bezpečnostní opravy a updaty.

Verzi a délku podpory jednotlivých verzí lze nalézt na následující adrese (na obrázku je stav z ledna 2016).

lubuntu_nepodporovana_verze_02

I když je verze nepodporovaná, neznamená to, že by byla nepoužitelná. Je možné danou verzi nainstalovat, nebo nadále používat, jen operační systém a programy nebudou získávat updaty. Také není možné instalovat nové programy z centrálního úložiště.

lubuntu_nepodporovana_verze

Vymazání cache v Chrome

Při vytváření webových stránek a hraní si s kaskádovými styly se může lehce stát, že prohlížeč stále zobrazuje webovou stránku s původními styly a nechce, ani po znovu načtení stránky, vzít v potaz změněný soubor stylů.

U prohlížeče Google Chrome se k vymazání cache (a také historie, cookie, hesel, …) dostanete přes Chrome menu (ikona se třemi vodorovnými čarami) -> Další nástroje -> Vymazat údaje o prohlížení … Pro vymazání souborů stylů slouží volba „Obrázky a soubory v mezipaměti“.

chrome_vymazání_cache

Zdroj: support.google.com

Převod streamu primitivních datových typů na stream objektů

V předchozím příspěvku jsem se věnoval streamům, které jako elementy obsahují primitivní datové typy. Jednalo se o následující streamy: IntSteam, DoubleStream, LongStream. Pomocí metody boxed() je možné stream primitivních datových typů převést na stream objektů odpovídajícího datového typu.

// Převod na stream objektů.
Stream<Integer> si = IntStream.range(1, 10).boxed();
Stream<Long> sl = LongStream.of(1_415, 402_112, 999).boxed();
Stream<Double> ds = DoubleStream.generate(() -> Math.random()).limit(5).boxed();

// Zobrazení elementů streamu.
si.forEach(System.out::println);
sl.forEach(System.out::println);
ds.forEach(System.out::println);

Streamy primitivních datových typů v Javě

Java kromě Stream<Object> nabízí i streamy primitivních datových typu. Přesněji řečeno má takové streamy tři:

  • IntStream
  • DoubleStream
  • LongStream

Vytvoření streamu primitivních datových typů
K vytvoření streamu primitivních datových typů je možné, tak jako pro stream objektů, použít metody generate() a iterate().

// IntStream obsahující deset sedmiček.
IntStream isg = IntStream.generate(() -> 7).limit(10);
// IntStream s elementy 0, 1, 2, 3, 4.
IntStream isi = IntStream.iterate(0, i -> i + 1).limit(5);

// Nekonečný DoubleStream, který obsahuje náhodná čísla.
DoubleStream dsg = DoubleStream.generate(() -> Math.random());
// DoubleStream s elementy 1.1, 2.2, 4.4, 8.8, 17.6.
DoubleStream dsi = DoubleStream.iterate(1.1, i -> i + i).limit(5);

// Nekonečný LongStream, který obsahuje čísla 9876543210.
LongStream lsg = LongStream.generate(() -> 9876543210L);
// LongStream obsahující čísla (řády) od 1 miliónu po 1 bilión.
LongStream lsi = LongStream.iterate(1_000_000, num -> num * 10).limit(9);

Dalším způsobem je použít statickou metodu of() a do ní uvést výčet hodnot.

IntStream intStream = IntStream.of(1, 3, 5, 7);
DoubleStream doubleStream = DoubleStream.of(0.52, 15.24, 7.879);
LongStream longStream = LongStream.of(14_854, 4_854);

Stream je možné vytvořit taktéž z pole pomocí statické metody java.util.Arrays.stream().

int[] intArray = { 1, 2, 3, 4};
double[] doubleArray = {12.548, 0.99, 103.1};
long[] longArray = {12, 778_755_441_784L, 1_221};

// IntSteam s elementy 1, 2, 3, 4.
IntStream isFromArray = Arrays.stream(intArray);
// DoubleStream s elementy 0.99 a 103.1.
DoubleStream dsFromArray = Arrays.stream(doubleArray, 1, 3);
// LongStream s elementem 1221.
LongStream lsFromArray = Arrays.stream(longArray, 2, 3);

IntStream a LongStream mají navíc k dispozici statické metody range() a rangeClosed().

// IntSteam s elementy 0, 1, 2, 3, 4.
IntStream isFromRange = IntStream.range(0, 5);
// LongStream s elementy 100, 101, 102, 103.
LongStream lsFromRange = LongStream.rangeClosed(100, 103);

Zdroj: HORSTMANN, Cay S. Java SE 8 for the really impatient. Upper Saddle River, NJ: Addison-Wesley, 2014, xv, 215 pages. ISBN 0321927761.

Zrádný LEFT JOIN

V SQL je JOIN klauzule používána pro spojení tabulek. Klauzule LEFT JOIN spojí všechny záznamy z tabulky uvedené nalevo od klauzule se záznamy v tabulce uvedené napravo.

SELECT * FROM tabulka_jedna LEFT JOIN tabulka_dve

Zrádností LEFT JOINu (to samé platí i pro RIGHT JOIN) je to, že vezme všechny záznamy z levé tabulky a přiřadí je k (spojí je s) záznamům v pravé tabulce. Pokud ale v pravé tabulce není záznam, bude sloupec obsahovat null. Takhle to vypadá zřejmě, pojďme se ale podívat na následující příklad (v PostgreSQL).

Vytvoříme si schéma ZLJ (Zrádný Left Join) a v něm si vytvoříme tři tabulky. Tabulka USER bude obsahovat údaje o uživateli jako je jeho id, číslo, jméno. Tabulku AUTH_TYPE bude číselník s typy autorizací (sms, pin, heslo). Jako poslední vytvoříme tabulku AUTHENTCATION, která bude uchovávat údaje týkající se authentikace (typ, kdy byla vytvořena,) a bude provázána s tabulkou USER pomocí cizího klíče. Tabulky si rovnou naplníme daty.

DROP SCHEMA IF EXISTS ZLJ CASCADE;
CREATE SCHEMA ZLJ;

CREATE TABLE ZLJ.USER (
	user_id	serial not null,
	user_number varchar(10) not null,
	username varchar(10) not null,

	primary key(user_id)
);

CREATE TABLE ZLJ.AUTH_TYPE (
	auth_type_id serial not null,
	type varchar(10) not null,

	primary key(auth_type_id)
);

CREATE TABLE ZLJ.AUTHENTICATION (
	authentication_id serial not null,
	user_id int not null,
	auth_type_id int not null,
	created timestamp not null,

	primary key(authentication_id),
	foreign key(user_id) references ZLJ.USER(user_id),
	foreign key(auth_type_id) references ZLJ.AUTH_TYPE(auth_type_id)
);

INSERT INTO ZLJ.USER (user_number, username) VALUES
	('9954258641', 'fnovotny'),
	('9865662384', 'franta03'),
	('9932652322', 'mariem');

INSERT INTO ZLJ.AUTH_TYPE (type) VALUES
	('pin'),
	('sms'),
	('password');

INSERT INTO ZLJ.AUTHENTICATION (user_id, auth_type_id, created) VALUES
	(1, 2, '2016-01-05 21:11:58'),
	(3, 3, '2016-01-05 22:03:17');

Všimněte si jedné věci. Všechny sloupce mají definované omezení NOT NULL. To znamená, že do každého sloupce záznamu je nutné vložit hodnotu. Neexistuje sloupec, ve kterém by mohla být NULL hodnota.

Naši databázi voláme z nějaké aplikace. Tato aplikace požaduje následující údaje: authentication_id (id záznamu v tabulce AUTHENTICATION) a auth_type_id (foreign key na záznam v číselníku). Tyto údaje potřebuje pro určitého uživatele. Jelikož chceme mít ve výsledku obsaženy všechny uživatele, použijem LEFT JOIN.

SELECT authentication_id, auth_type_id 
FROM 
ZLJ.USER LEFT JOIN ZLJ.AUTHENTICATION ON (ZLJ.USER.user_id = ZLJ.AUTHENTICATION.user_id)
WHERE user_number = ?

Za otazník se v prepared statementu dosadí user_number. Jelikož mají všechny sloupce omezení NOT NULL, vždy dostaneme nějakou hodnotu. Chyba. Aplikace začne občas padat. Přesněji řečeno začne padat v momentě, kdy se pokusíme v tabulce AUTH_TYPE dohledat záznam type dle auth_type_id, které získáme  z předchozího selectu. Pokud totiž budeme hledat záznam auth_type_id pro user_number 9865662384, dostaneme NULL.

Dotaz:

SELECT * 
FROM 
ZLJ.USER LEFT JOIN ZLJ.AUTHENTICATION ON (ZLJ.USER.user_id = ZLJ.AUTHENTICATION.user_id)

Výsledek:

postgresql_zradny_left_join

Dotaz:

select * from 
	(SELECT * FROM ZLJ.USER LEFT JOIN ZLJ.AUTHENTICATION ON (ZLJ.USER.user_id = ZLJ.AUTHENTICATION.user_id)) as SEL 
where auth_type_id is null;

Vrátí záznamy, které mají ve sloupci auth_type_id NULL.

postgresql_zradny_left_join_02