nový SqlPreprocessor pro Nette\Database
- paranoiq
- Člen | 392
současný SQL preprocesor v Nette\Database mi nevyhovuje a tak jsem napsal nový. každý ohlas je vítán, hlavně pokud jde o jiné databáze než MySQL. zatím nejsou testy
pokusná verze SQL procesoru je zde: https://gist.github.com/1277781 (zatím jako rozšíření)
otevřená issue tady: https://github.com/…e/issues/381
SqlPreprocessor
funkčnost SQL preprocesoru usnadňuje zápis a čtení přímo psaných
dotazů a automatické generování dotazů u metod query()
,
exec()
a fetch…()
má dva režimy:
- režim ‚placeholder‘ (zpětně kompatibilní), ve
kterém je prvním parametrem celý SQL dotaz a pozice argumentů je v něm
označena znakem
?
, stejně jako v PDO a současném Nette\Database
$db->exec("UPDATE x SET y = ? WHERE z = ?", $y, $z);
- režim ‚alternate‘, ve kterém se útržky SQL dotazu střídají s argumenty. pozice argumentů není vyznačena nijak. není to totiž třeba. zápis kódu v tomto režimu je mnohem přehlednější, hlavně při větším množství parametrů. připomíná zápis z dibi, ale bez protivných modifikátorů
$db->exec("UPDATE x SET y = ", $y, "WHERE z = ", $z);
o který režim jde pozná podle toho, zda je ve statementu
placeholder ?
zpracování polí
umí podle kontextu chytře rozeznávat jak naložit s argumentem typu pole. režimy zpracování jsou:
- insert: pro
INSERT
aREPLACE
(a multi-insert) - assoc: pro
UPDATE
aSET
- where: pro použití za klauzulí
WHERE
aHAVING
nebo za některým z logických operátorů. generuje trojice klíč, operátor (=
,LIKE
,IS NULL
* aIN
), hodnota, spojené operátoremAND
- order: pro
ORDER BY
aGROUP BY
. klíč je název sloupce, hodnota je směr řazení:FALSE
a<= 0
jeDESC
- in: pro použití za
IN
,ANY
,SOME
,ALL
. generuje seznam hodnot v závorce - pokud není rozpoznám žádný vhodný mód, vytvoří se seznam hodnot
oddělený čárkou. např.
pro:
$db->exec("CALL fnc(?)", $arr);
*) zpracování typu bool:
databáze PostgreSQL a MySQL 5 a vyšší umí krom IS NULL
také
IS TRUE
a IS FALSE
– zde se přímo nabízí
generovat toto porovnání. bylo by ale třeba stanovit lepší rozlišování
podpory než je v poli ISupplementalDriver::$supports – podle verzí db
další
ošetřuje typ hodnoty (int
) pro LIMIT
,
OFFSET
a TOP
nahrazuje substituce, jako současný preprocesor
PRO:
- přehlednější kód díky nové syntaxi
- lepší práce s poli než ve stávajícím řešení
PROTI:
- další mezivrstva požírající kousek výkonu. preprocesor je trochu složitější než stávající
- pro Selection/ActiveRow není až tak třeba. většinou se uplatní jen při použití Connection jako DBAL
SqlFragment
SqlFragment je obdoba SqlLiteral, ale krom samotného literálu mu lze předat i argumenty. lze tedy jednodušeji vytvářet správně naformátované a ošetřené útržky SQL kódu
neměl by funkčnost SqlFragment obstarávat přímo SqlLiteral? je nová třída třeba?
Editoval paranoiq (13. 12. 2011 13:13)
- David Grudl
- Nette Core | 8215
Z velké části je to implementováno, i když trošku jinak.
- místo dvou režimů je k dispozici jeden, který funguje podobně jako v dibi: vždy se jako placeholder používá otazník a za výrazem následuje tolik parametrů, kolik je ve výrazu otazníků. https://github.com/…f7b7797f0337
- doplnil jsem zpracování polí pro WHERE/HAVING a ORDER BY/GROUP BY. https://github.com/…5221fda581fb
- substituce jsme už dříve odstranili https://github.com/…97e653e02549
- jako SqlFragment funguje SqlLiteral https://github.com/…68b51e7e28ff