Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: stud 30. 08. 2015, 13:09:03

Název: Native queries (aneb databáze a OOP)
Přispěvatel: stud 30. 08. 2015, 13:09:03
Mám dotaz víceméně ze zvědavosti. Líbí se mi koncept native queries: https://en.wikipedia.org/wiki/Native_Queries
Chápu, jak se to používá a v čem jsou výhody. Jak se to ale implementuje (např. v Javě nebo v C++)? C# má LINQ přímo v jazyku, ale např. u Javy nechápu, jak to udělali. Na webu je hodně příkladů použití, ale nic (jsem nenašel) o implementaci.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: perceptron 30. 08. 2015, 13:27:52
v c# je to v syntaxi jazyka

v jave sa volania metod prekladaju jednoducho na sql za tym ziadna magia neni

aj ked v jave v tejto oblasti vyhralo jpa resp hibernate

v java 8 su pokusy prepojit lambdy a sql: http://www.jinq.org/ opat ziadna magia.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: Radek Miček 30. 08. 2015, 13:37:08
v java 8 su pokusy prepojit lambdy a sql: http://www.jinq.org/ opat ziadna magia.

S tou magií nevím. Zrovna Jinq funguje tak, že provádí abstraktní interpretaci bajtkódu - pro složitý bajtkód to nefunguje.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: Franta <xkucf03/> 30. 08. 2015, 13:37:39
Koukni taky na http://www.jooq.org/ – umožňuje psát typově bezpečné dotazy. Je to někde na půli cesty mezi psaním čistého SQL a ORM.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: zboj 30. 08. 2015, 13:46:12
Koukni taky na http://www.jooq.org/ – umožňuje psát typově bezpečné dotazy. Je to někde na půli cesty mezi psaním čistého SQL a ORM.

Pleteš si (stejně jako perceptron) NQ a SODA.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: zboj 30. 08. 2015, 13:54:43
Mám dotaz víceméně ze zvědavosti. Líbí se mi koncept native queries: https://en.wikipedia.org/wiki/Native_Queries
Chápu, jak se to používá a v čem jsou výhody. Jak se to ale implementuje (např. v Javě nebo v C++)? C# má LINQ přímo v jazyku, ale např. u Javy nechápu, jak to udělali. Na webu je hodně příkladů použití, ale nic (jsem nenašel) o implementaci.

Je to magie ve všech jazycích (na rozdíl od SODA, což si lidi evidentně pletou s NQ). V Javě bych to psát nechtěl (překládá se bytecode do OQL). Jednodušeji to jde v C++, C++/CLI, C++/CX, Objective-C a úplně nejjednodušeji ve Swiftu (ale pořád musí být člověk borec, aby to napsal rozumně a použitelně). Dá se pak napsat něco jako

Kód: [Vybrat]
let objects = database.findObjects({ obj:MyObject in obj.someField <= 1234 })
Na rozdíl od SODA to je čitelnější a přirozenější (vypadá to jako lambda výraz, ale převádí se na OQL nebo něco podobného). Klidně se vsadím, že 95% (to je ještě opatrný odhad, možná i 99%) programátorů by to ale nenapsalo ani v C++, ani v ObjC, ani ve Swiftu - je to hodně advanced. Na druhou stranu hotovou implementaci může použít jednoduše každý a je to mnohem lepší než "string-based query interface" (viz odkazovaný článek).
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: Ondrej Nemecek 30. 08. 2015, 14:32:28
Pleteš si (stejně jako perceptron) NQ a SODA.

Prosím tedy vysvětlit, co je NQ a SODA - v čem tkví rozdíl. A jak si v tom stojí ORM.

řípadně i odkaz na zdroje - nějak se mi to nedaří najít.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: zboj 30. 08. 2015, 14:45:45
Pleteš si (stejně jako perceptron) NQ a SODA.

Prosím tedy vysvětlit, co je NQ a SODA - v čem tkví rozdíl. A jak si v tom stojí ORM.

řípadně i odkaz na zdroje - nějak se mi to nedaří najít.

S ORM to nemá nic společného. NQ je něco jako

Kód: [Vybrat]
Query(obj:MyObject in obj.field >= 1234)
kdežto SODA bude něco jako

Kód: [Vybrat]
Query(MyObject.self).whereField("field").geqThan(1234)
z čehož plyne, že NQ je lepší (z hlediska bezpečnosti, resp. kontroly během kompilace). Navíc SODA je ukecaný guláš. Na druhou stranu SODA je lepší než textové OQL v kódu.

Kdo zkusí implementovat NQ v různých jazycích, krásně zjistí, v čem se různé implementace OOP liší - každý jazyk v něčem hapruje, např. C++ nemá introspekci (ale preprocesor to nahradí), Swift nemá implicitní konverzi typů (v dřívější betě měl, ale už je pryč), v Javě se člověk musí hrabat v bajtkódu. Microsoftí C++ (CLI nebo CX) je na tom z tohoto pohledu asi nejlépe, ale zase to je okrajová záležitost.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: Ondrej Nemecek 30. 08. 2015, 15:05:32
Pleteš si (stejně jako perceptron) NQ a SODA.

Prosím tedy vysvětlit, co je NQ a SODA - v čem tkví rozdíl. A jak si v tom stojí ORM.

řípadně i odkaz na zdroje - nějak se mi to nedaří najít.

Jasně, díky, už jsem se toho taky dovtípil - v NQ se ty podmínky zapisují pomocí java kódu (vezměme jako příklad javu), takže to vypadá, jakoby se podmínka vyhodnocovala přímo v javě (kde se ve skutečnosti vyhodnocuje to je jiná otázka, zřejmě se z bajtkódu vyganeruje sql). Například zde http://www.java-objects-database.com/jodb-general-section/help/native-query.html je příklad, kde se podmínka zapíše jako

Kód: [Vybrat]
return pilot.getPoints() > 100 && pilot.getPoints() < 500 ;
V SODA se uvádí název sloupce, takže by tam bylo něco jako

Kód: [Vybrat]
Query.from(Pilot.class).where("points > ?", 100).and("points < ?", 500).selectAll();
Jenže třeba Dari http://www.dariframework.org/ překládá textovou SODA-like syntax na predikáty http://www.dariframework.org/javadocs/com/psddev/dari/db/PredicateParser.html Otázka je, zda jde ve výsledku o NQ nebo SODA.

Která vrstva rozhoduje, jestli jde o NQ nebo SODA? Když se SQL generuje z bajtkódu v runtime, je to NQ, ale když se generuje za běhu programu, je to SODA? Trochu se to komplikuje...

A za ORM byste teda považoval jen to, jakým způsobem se zabalí výsledek SQL dotazu do objektů?
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: zboj 30. 08. 2015, 15:13:41
Pleteš si (stejně jako perceptron) NQ a SODA.

Prosím tedy vysvětlit, co je NQ a SODA - v čem tkví rozdíl. A jak si v tom stojí ORM.

řípadně i odkaz na zdroje - nějak se mi to nedaří najít.

Jasně, díky, už jsem se toho taky dovtípil - v NQ se ty podmínky zapisují pomocí java kódu (vezměme jako příklad javu), takže to vypadá, jakoby se podmínka vyhodnocovala přímo v javě (kde se ve skutečnosti vyhodnocuje to je jiná otázka, zřejmě se z bajtkódu vyganeruje sql). Například zde http://www.java-objects-database.com/jodb-general-section/help/native-query.html je příklad, kde se podmínka zapíše jako

Kód: [Vybrat]
return pilot.getPoints() > 100 && pilot.getPoints() < 500 ;
V SODA se uvádí název sloupce, takže by tam bylo něco jako

Kód: [Vybrat]
Query.from(Pilot.class).where("points > ?", 100).and("points < ?", 500).selectAll();
Jenže třeba Dari http://www.dariframework.org/ překládá textovou SODA-like syntax na predikáty http://www.dariframework.org/javadocs/com/psddev/dari/db/PredicateParser.html Otázka je, zda jde ve výsledku o NQ nebo SODA.

Která vrstva rozhoduje, jestli jde o NQ nebo SODA? Když se SQL generuje z bajtkódu v runtime, je to NQ, ale když se generuje za běhu programu, je to SODA? Trochu se to komplikuje...

A za ORM byste teda považoval jen to, jakým způsobem se zabalí výsledek SQL dotazu do objektů?

"Textová" syntax nikdy není NQ. NQ vůbec nesouvisí s bajtkódem (ani s Javou), jen to prostě v Javě jinak než přes bajtkód nejde.
ORM je způsob ukládání objektů do relační databáze. S dotazy nijak nesouvisí. Perzistence je jiná vrstva (buď OODB nebo ORM) někde pod OO rozhraním.
Suma sumarum SODA je primitivní překlad do OQL nebo něčeho podobného, kdežto NQ je zápis přímo v jazyce (proto "native").
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: noef 30. 08. 2015, 15:16:16
Když se SQL generuje z bajtkódu v runtime, je to NQ, ale když se generuje za běhu programu, je to SODA? Trochu se to komplikuje...

Ehm, není to přesně to samé? Nebo jde jen o ten bytekód (to nezní moc obecně)?
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: zboj 30. 08. 2015, 15:50:09
BTW v ideálním OO jazyce by to šlo přímočaře, jenže takový jazyk neexistuje. Je totiž potřebný přístup k AST. V jazycích s přetěžováním operátorů se to dá většinou nějak napsat, ale je to buď prasárna nebo nedokonalé. Swift by byl v tomto ohledu téměř dokonalý, kdyby měl implicitní konverzi typů, jenže ta by zase haprovala jinde (proto ji odstranili).
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: Ondrej Nemecek 30. 08. 2015, 15:55:33
"Textová" syntax nikdy není NQ. NQ vůbec nesouvisí s bajtkódem (ani s Javou), jen to prostě v Javě jinak než přes bajtkód nejde.
ORM je způsob ukládání objektů do relační databáze. S dotazy nijak nesouvisí. Perzistence je jiná vrstva (buď OODB nebo ORM) někde pod OO rozhraním.
Suma sumarum SODA je primitivní překlad do OQL nebo něčeho podobného, kdežto NQ je zápis přímo v jazyce (proto "native").

Dobře, jak vznikne z NQ ten SQL?
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: zboj 30. 08. 2015, 16:01:29
"Textová" syntax nikdy není NQ. NQ vůbec nesouvisí s bajtkódem (ani s Javou), jen to prostě v Javě jinak než přes bajtkód nejde.
ORM je způsob ukládání objektů do relační databáze. S dotazy nijak nesouvisí. Perzistence je jiná vrstva (buď OODB nebo ORM) někde pod OO rozhraním.
Suma sumarum SODA je primitivní překlad do OQL nebo něčeho podobného, kdežto NQ je zápis přímo v jazyce (proto "native").

Dobře, jak vznikne z NQ ten SQL?

OQL, ne SQL. To je právě ta magie. V Javě z bajtkódu, jinak se musí nějak poskládat AST. Když jsem si s tím hrál naposledy v C++, microsoftí překladač zkolaboval a v clangu jsem tak našel bug v linkeru. Swift to v poslední verzi zvládá hezky (operátor se dá přetížit několikrát s různými návratovými hodnotami a automatická inference typu udělá z "x == 100" buď bool nebo predikát podle místa použití - tak má ostatně OOP vypadat), jen ta implicitní konverze chybí.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: Ondrej Nemecek 30. 08. 2015, 16:07:04
Když se SQL generuje z bajtkódu v runtime, je to NQ, ale když se generuje za běhu programu, je to SODA? Trochu se to komplikuje...

Ehm, není to přesně to samé? Nebo jde jen o ten bytekód (to nezní moc obecně)?

Myslel jsem to tak, že pro NQ je potřeba nějaká manipulace s batekódem (po kompilaci) anebo podpora v runtime (která s bajtkódem něco dělá za běhu), kdežto SODA jen jednoduše pospojuje řetězce a hotovo.


Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: zboj 30. 08. 2015, 16:09:53
Když se SQL generuje z bajtkódu v runtime, je to NQ, ale když se generuje za běhu programu, je to SODA? Trochu se to komplikuje...

Ehm, není to přesně to samé? Nebo jde jen o ten bytekód (to nezní moc obecně)?

Myslel jsem to tak, že pro NQ je potřeba nějaká manipulace s batekódem (po kompilaci) anebo podpora v runtime (která s bajtkódem něco dělá za běhu), kdežto SODA jen jednoduše pospojuje řetězce a hotovo.

NQ jsou v podstatě záležitost compile time (v ideálním případě). SODA je záležitost run time.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: Ondrej Nemecek 30. 08. 2015, 16:18:18
"Textová" syntax nikdy není NQ. NQ vůbec nesouvisí s bajtkódem (ani s Javou), jen to prostě v Javě jinak než přes bajtkód nejde.
ORM je způsob ukládání objektů do relační databáze. S dotazy nijak nesouvisí. Perzistence je jiná vrstva (buď OODB nebo ORM) někde pod OO rozhraním.
Suma sumarum SODA je primitivní překlad do OQL nebo něčeho podobného, kdežto NQ je zápis přímo v jazyce (proto "native").

Dobře, jak vznikne z NQ ten SQL?

OQL, ne SQL. To je právě ta magie. V Javě z bajtkódu, jinak se musí nějak poskládat AST. Když jsem si s tím hrál naposledy v C++, microsoftí překladač zkolaboval a v clangu jsem tak našel bug v linkeru. Swift to v poslední verzi zvládá hezky (operátor se dá přetížit několikrát s různými návratovými hodnotami a automatická inference typu udělá z "x == 100" buď bool nebo predikát podle místa použití - tak má ostatně OOP vypadat), jen ta implicitní konverze chybí.

A NQ interpretuje tedy libovolný nativní kód? To by byl ten principielní rozdíl oproti v SODA, kde jsou jen předpřipravené metody....

NQ jsou v podstatě záležitost compile time (v ideálním případě). SODA je záležitost run time.

Aha, v tom případě si nedokážu představit, jak NQ funguje. To jako analyzuju bytekód (v případě javy) a nahradím v něm nativní zápis dotazu za něco jiného? Vygeneruju kód na míru mému nativnímu dotazu?
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: zboj 30. 08. 2015, 16:27:41
A NQ interpretuje tedy libovolný nativní kód? To by byl ten principielní rozdíl oproti v SODA, kde jsou jen předpřipravené metody....

Libovolný ne, ale může se z toho vytvořit parciální dotaz, který předfiltruje objekty a zbytek se inicializuje a otestuje. NQ může být v podstatě cokoliv typu boolean.

Aha, v tom případě si nedokážu představit, jak NQ funguje. To jako analyzuju bytekód (v případě javy) a nahradím v něm nativní zápis dotazu za něco jiného? Vygeneruju kód na míru mému nativnímu dotazu?

V Javě jo. Jinak se (v nějakém lepším jazyce) z boolovského výrazu vytvoří AST a z něj následně OQL nebo cokoliv, co vzniká i ze SODY.
Ono to je celé hodně komplikované a jen to ukazuje, že dnešní OOP v praxi dost pokulhává (každý jazyk trochu jinak). Až bude Swift opensourcován, stačí přidat do něj implicitní konverze (což bude vlastně uncommenting vyřzeného kódu) a máme (z pohledu OODB) ideální jazyk.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: zboj 31. 08. 2015, 11:45:18
http://www.cs.utexas.edu/~wcook/papers/SafeQuery05/SafeQueryFinal.pdf
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: Ondrej Nemecek 31. 08. 2015, 12:09:08
Díky, nejdřív jsem myslel, že posíláš svojí diplomku :-) ale vypadá to, že to psal někdo jiný. Naštěstí to je psané docela srozumitelně.

Koukal jsem ještě na LINQ a jestli to je integrální součást C# tak to je docela frajeřina.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: bsmk 31. 08. 2015, 12:13:08
Ku konceptu NQ ma blizko v scale napisana kniznica Slick (http://slick.typesafe.com/).
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: Franta <xkucf03/> 08. 09. 2015, 22:28:00
Koukni taky na http://www.jooq.org/ – umožňuje psát typově bezpečné dotazy. Je to někde na půli cesty mezi psaním čistého SQL a ORM.
Pleteš si (stejně jako perceptron) NQ a SODA.

Píšu, ať se na to podívá, ne že je to NQ. Ono někdy poslouží líp nástroj typu JOOQ, než tam přidávat ještě další úroveň abstrakce (a svým způsobem magie) a posouvat se ještě dál od nativního jazyka, se kterým pracuje databáze. V extrémních případech je i ručně psané SQL příliš vysokoúrovňové a optimalizátor v databázi nesestaví plán tak, jak bys potřeboval.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: zboj 09. 09. 2015, 14:15:40
Koukni taky na http://www.jooq.org/ – umožňuje psát typově bezpečné dotazy. Je to někde na půli cesty mezi psaním čistého SQL a ORM.
Pleteš si (stejně jako perceptron) NQ a SODA.

Píšu, ať se na to podívá, ne že je to NQ. Ono někdy poslouží líp nástroj typu JOOQ, než tam přidávat ještě další úroveň abstrakce (a svým způsobem magie) a posouvat se ještě dál od nativního jazyka, se kterým pracuje databáze. V extrémních případech je i ručně psané SQL příliš vysokoúrovňové a optimalizátor v databázi nesestaví plán tak, jak bys potřeboval.

JOOQ jen generuje kód. "Magie" to je jen pro někoho, kdo neví, jak to funguje. Taky by to mělo být efektivnější.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: Franta <xkucf03/> 09. 09. 2015, 22:58:24
JOOQ jen generuje kód. "Magie" to je jen pro někoho, kdo neví, jak to funguje. Taky by to mělo být efektivnější.

Neříkám, že NQ je špatné, naopak, je to dost zajímavá věc… Ale jistou magičnost tomu upřít nelze – v zásadě jde o funkci, která převádí výraz v jednom jazyce na výraz v jiném jazyce (třeba Java → SQL nebo Java → JPQL) a problém je v tom, že definiční obor té funkce je velmi široký (formálně) a obor hodnot je oproti tomu hodně omezený a tak úplně to na sebe nepasuje. Jen malá podmnožina hodnot definičního oboru dává smysl a je rozumně převoditelná na výstup.

Na jednu stranu tedy NQ pomáhá (píšu v Javě, kompilátor mi kontroluje výrazy), ale na druhou stranu škodí – zvyšuje nejistotu (ne vše, co jde zkompilovat, je OK), zatemňuje, přidává další úroveň abstrakce/nepřímosti a klade vyšší nároky na programátora.

Rozhodně nechci NQ zavrhovat, ale přijde mi hloupé odsuzovat nástroje typu JOOQ a považovat je za něco nedostatečného – když právě tyhle nástroje můžou být lepší volbou.
Název: Re:Native queries (aneb databáze a OOP)
Přispěvatel: zboj 10. 09. 2015, 02:17:25
JOOQ jen generuje kód. "Magie" to je jen pro někoho, kdo neví, jak to funguje. Taky by to mělo být efektivnější.

Neříkám, že NQ je špatné, naopak, je to dost zajímavá věc… Ale jistou magičnost tomu upřít nelze – v zásadě jde o funkci, která převádí výraz v jednom jazyce na výraz v jiném jazyce (třeba Java → SQL nebo Java → JPQL) a problém je v tom, že definiční obor té funkce je velmi široký (formálně) a obor hodnot je oproti tomu hodně omezený a tak úplně to na sebe nepasuje. Jen malá podmnožina hodnot definičního oboru dává smysl a je rozumně převoditelná na výstup.

Na jednu stranu tedy NQ pomáhá (píšu v Javě, kompilátor mi kontroluje výrazy), ale na druhou stranu škodí – zvyšuje nejistotu (ne vše, co jde zkompilovat, je OK), zatemňuje, přidává další úroveň abstrakce/nepřímosti a klade vyšší nároky na programátora.

Rozhodně nechci NQ zavrhovat, ale přijde mi hloupé odsuzovat nástroje typu JOOQ a považovat je za něco nedostatečného – když právě tyhle nástroje můžou být lepší volbou.

Vyšší nároky nikde nevidím, spíš naopak. NQ nepřidává žádnou úroveň, naopak ubírá.