Registrace – ošetření duplicit více unikátních dat

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
darkweaver
Člen | 18
+
0
-

Dobrý den,
řeším menší problém u registrace, kterou vytvářím. Mám databázovou tabulku, ve které jsou sloupce jmeno a email a tyto sloupce jsou definovány jako unikátní. Problém je v tom, že nevím, jak ošetřit tyto dvě duplicity tak, aby mi registrace vždy vyplivla co je právě duplicitního, jestli jméno, email nebo oboje. Zatím to mám řešeno tak, že odchytávám vyjímku DibiDriverException a poté jí kontroluji na kód 1062.

try
               {
                 $model = $this->getModel();
                 $model->registration($data);

                $this->flashMessage('Registrace proběhla úspěšně!');
                $this->redirect('this');

               }catch (\DibiDriverException $e){
                      if ($e->getCode() == \DibiMySqlDriver::ERROR_DUPLICATE_ENTRY){
                              $form->addError('Takové jméno nebo email již používá někdo jiný.');
                      }

               }

Potřeboval bych ale, aby mi registrace řekla přímo, co je duplicitní, jestli jméno nebo email. Snažil jsem se to řešit tak, abych použil pouze 1 dotaz do databáze, ale myslím, že to tak nepůjde. Proto bych se chtěl zeptat zdejších diskutujících, zda-li je nenapadá nějaké řešení tohoto problému.

Velice děkuji.

Editoval darkweaver (30. 8. 2011 23:09)

hAssassin
Člen | 293
+
0
-

myslim, ze jednim dotazem to nepujde. Asi bude nejlepsi (a vim ze sem to tak driv delal) bude se zeptat jednim dotazem jestli existuje login, druhym jestli existuje email (podle toho pripadne vypsat chybove hlasky) a tretim dotazem (pokud ani jedno neexistuje) vlozit noveho uzivatele do DB.

voda
Člen | 561
+
0
-

Mělo by to jít poznat z chybové hlášky $e->getMessage(). U mě v MySQL vypadá takhle

Duplicate entry 'user' for key 'jmeno'
Mikulas Dite
Člen | 756
+
0
-

Na dva dotazy to není dostatečně atomocký. Stačí to tam vložit, a pokuď db vrátí ten správný error, vrátit chybovou hlášku. Ale rozhodně to nezjišťuj podle error message, na to je dělaný kód. Konkrétně 1062 pro tuhle chybu: http://dev.mysql.com/…-server.html.

voda
Člen | 561
+
0
-

Erro message by se samozřejmě použila pouze na zjištění který sloupec to byl. Sice se mi to taky moc nelibí, ale jediná další varianta je další dotaz. Buď v transakci si zjistit předem, nebo až pokud db vyhodí chybu Duplicate entry tak dalším dotazem zjistit, který sloupec to byl.

uestla
Backer | 799
+
0
-

Taky bych parsoval chybovou zprávu, ale moc bych se o tom nešířil :-)

list(, $column) = Strings::match('# for key \'(.*)\'$#i');
voda
Člen | 561
+
0
-

Pokud si je člověk vědom problémů které to může přinést a dokáže si je pohlídat, tak nevidím problém v tom to použít. A já bych spíš použil sscanf(), ale je to samozřejmě jedno.

Bernard Williams
Člen | 207
+
0
-

Nazdárek,

já osobně bych to zjistil dotazem:

SELECT jmeno, email FROM table WHERE jmeno=? OR email=?;

a pak v presenteru to dal do podmínky a podle toho hodil hlášku:

if ($row['jmeno']==$data['jmeno'])
   "Takové jméno již existuje."
elseif ($row['email']==$data['email'])
   "Takový e-mail již existuje."
else
   INSERT INTO table ...

Parsováním chybové hlášky bych to určitě neřešil.. kdo ví, jakou DB budeš v budoucnu používat nebo jestli se v další verzi tvar té hlášky nezmění.

Bernard

Editoval Bernard Williams (31. 8. 2011 19:12)

voda
Člen | 561
+
0
-

@**Bernard**: V tom případě bys ale měl použít transakce a taky pozor, že ten první select může vrátit i dva řádky.