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
INSERTaREPLACE(a multi-insert) - assoc: pro
UPDATEaSET - where: pro použití za klauzulí
WHEREaHAVINGnebo 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 BYaGROUP BY. klíč je název sloupce, hodnota je směr řazení:FALSEa<= 0jeDESC - 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 | 8285
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