38 komentářů k článku Videotutoriál Doctrine 2 a NotORM: ukládání dat:

  1. Honza Marek

    Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

    3: Přiřadit do neexistujícího sloupce prostě nejde. Nenamapovaná proměnná není považována za sloupec.

    4: Doctrine nechává validaci na vyšší vrstvě. Já používám validátory ze Symfony a jsem s tímto řešením naprosto spokojen. Kontrola probíhá pomocí onFlush události, takže se děje tak nějak sama.

    6: Nechápu proč píšeš, že to nejde, když o odstavec dál napíšeš, že to jde.

    7: No a? Proxy třídám jednou nastavíš adresář, kam se mají vyrábět, potom se o ně už opravdu nemusíš starat.

    1. Jakub VránaAutor příspěvku

      Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

      3. Problém je v tom, že když napíšu cathegory místo category, tak se o tom nijak nedozvím.

      1. Cechjos

        Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

        To je ale odpovědnost (a „problém“ vzhledem k __get/set metodám) programátora, aby udržel objekty v požadovaném stavu. Co když bude chtít před persistnutím ještě použít nějaké metody daného objektu (které používají property, u které se uklepl) – bude problém Doctrine, že se nějakou černou magií nedozvěděl o problému v objektu, o kterém nemůže mít páru? A mají ho zajímat property, u kterých mu programátor neřekl, že je chce ukládat do dtb? (Odpověď může být: Dle dokumentace; ale stejně je to v prvé řadě odpovědnost programátora.)

        1. Jakub VránaAutor příspěvku

          Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

          Já očekávám, že když někde udělám překlep, tak mi nějaká vrstva oznámí chybu. Stejně jako v prvním díle se ukazuje, že Doctrine touto vrstvou bohužel není.

          1. paranoiq

            Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

            tuhle věc řeší třeba v Nette NObject. není to práce persistenční vrstvy

        2. Oldis

          Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

          neni, jde o chybu, a tudiz by o ni mel programatora nekdo spravit, misto toho aby se preklepl, pokracoval a za tyden hledal proc neco nefunguje jak ma, proc se neco neuklada, a pidil se kodem kde to tak asi muze bejt, zbytecna ztrata casu a prostredku.

          1. jos

            Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

            1. sme v PHP, smiř se s tim, nebo pošli patch; očekávej že nebude přijat, protože autoři PHP si váží víc bastlířů/amatérů než programátorů (asi kvůli poměru 100:1)

            2. jestli nemáš unittesty, seš nahranej tak jako tak

            3. jestli používáš knihovny který ti brání v unittestování, tvuj problém (nevim jak je na tom Doctrine)

            1. Oldis

              Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

              dostatecnej error reporting dobre predchazi potrebe monstroznich konstrukci testů

              1. jos

                Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

                eh, tak to ani náhodou, to bys musel tu aplikaci celou proklikat všema možnejma cestama po každým commitu

  2. jos

    Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

    1. může to dávat smysl v databázích bez cizích klíčů.

    2. sám píšeš, že to vynutit jde, kvalita zdejšího tutoriálu je nesouvisející věc.

    3. nezapomínej že de o instanci PHP třídy. kdo nemá error_reporting = -1 tak má pravděpodobně víc problémů; u NotORM by se naopak někdo mohl zeptat: a to si to pole musim dycky osekat sám? proč notor nezná strukturu db? (odpověď na tuhle otázku je zároveň odpovědí proč je hloupost srovnávat Doctrine a NotORM)

    4. to je hustý, pošli jim patch.

    5. jednak koukam, že (viditelná) podpora transakcí je v NotORMu až od 5. ledna 2011 (ehm?); druhak si sám tu transakci v příkládku nestartuješ (předpokládam stejnou konfiguraci db v obou případech), což je tragédie; beztak já osobně považuju transakce za něco, do čeho mi sebechytřejší udělátko nemá co kecat a jako programátor se o to rád postaram sám

    dál – píšeš, že insert vrací NotORM_Row; za předpokladu, že update to vrací taky: co bude v atributu visits?

    6. to sis našel pořádnej klacek, to je jako bych o nějakým autě tvrdil že jezdí pomalu a ještě bych drze řekl že sem jezdil pozpátku.

    7. jak píše %první%, ten adresář se dá nastavit

    disclaimer: autor názoru je zároveň autorem svého vlastního db bazmeku a nepoužívá ani Doctrine NotORM

    1. HosipLan

      Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

      ad 5: Jakub na tohle transakci nepotřebuje, protože jeden update, kde na úrovni databáze zvýšíš hodnotu políčka +1 je vždy atomický. Ten záznam si tam získává pouze pro vytvoření objektu $article, přes který se to musí updatovat, protože se to tváří jako ActiveRecord

      1. jos

        Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

        v tom umělohmotným příkladě to nepotřebuje, v reálným světě by mu za to ten co by přišel o data zlomil obě ruce

    2. Jakub VránaAutor příspěvku

      Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

      5. NotORM se nesnaží být kompletní náhradou práce s databází jako Doctrine. V konstruktoru nepřijímá DSN, ale objekt třídy PDO, což se může zdát jako nepodstatný detail, ale znamená to možnost s databází pracovat i přímo pomocí tohoto objektu. Takže 5. ledna do NotORM přibyla pouze zkratka pro obsluhu transakcí přímo pomocí PDO. Pokud považuješ „transakce za něco, do čeho ti sebechytřejší udělátko nemá co kecat“, tak ti asi přístup Doctrine také nemůže příliš vyhovovat.

      1. jos

        Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

        jo tak, to je jen zkratka, OK

        neznám komplexně přístup Doctrine, vyhovuje mi toto:

        1. instance držící spojení do databáze odmítne spustit dotaz pokud není nastartovaná transakce

        2. v destruktoru rollbackne všechny necommitnutý transakce

      2. jos

        Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

        tak sem si chtěl sám odpovědět na otázku „insert vrací NotORM_Row; za předpokladu, že update to vrací taky: co bude v atributu visits?“ a bylo to velmi zábavné

        předně – odpověď je, že update vrací počet ovlivněnejch řádků nikoliv NotORM_Row; když chci vědět jakou hodnotu tam vlastně máme, musíme si tam extra šáhnout (s tim nemam problém)

        takže stáhnul sem, rozbalil, a připojil se k db; prdnul sem si to do skriptu kterej používam na pokusy v projektu co hákuju, takže už v něm bylo zhruba toto:

        <?php
        // require všeho možnýho
        $env = dejsemenv();
        $cfg = $env()->cfg();
        $db = $env->db();
        $db->trans_begin();
        
        // ... tady si hraju, dále pískoviště
        
        $db->trans_rollback();

        na pískoviště sem rutinně vložil

        <?php
        ...
        $pdo = new PDO(
            sprintf(
                "odbc:Driver={SQL Server Native Client 10.0};Server=%s;Database=%s;Trusted_Connection=no"
              , $cfg->get('db.host')
              , $cfg->get('db.dbName')
            )
          , $cfg->get('db.user')
          , $cfg->get('db.passwd')
        );
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $db = new NotORM($pdo);

        z naší db vrstvy rázem vyletělo


        Warning: ROLLING BACK UNCOMMITED TRANSACTION

        což je E_USER_WARNING generovanej z destruktoru naší db vrstvy

        jak sem rutinně postupoval, tak sem si nevšiml, že proměnná $db je už obsazená a ono ->trans_rollback() se zavolalo na NotORMu

        dovolím si na tomto místě parafrázi:

        Já očekávám, že když někde udělám překlep, tak mi nějaká vrstva oznámí chybu. Ukazuje se, že NotORM touto vrstvou bohužel není.

        ale což, dyť se skoro nic nestalo, že … instance NotORM je od teď $no

        jedu dál, vyrobil sem tabuli

        create table dbo.lolek (
          id int not null constraint lolek_pk primary key
        )
        insert into dbo.lolek (id) select 1

        chci vysosat ten řádek

        <?php
        ...
        $pdo = new PDO(...);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $no = new NotORM($pdo);
        $row = $no->dbo.lolek[1];

        aha, parse error, no nic, na schémata můžu zapomenout, ještě že to defaultuje na dbo

        <?php
        ...
        $pdo = new PDO(...);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $no = new NotORM($pdo);
        $row = $no->lolek[1];

        výsledek:

        Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 102 [Microsoft][SQL Server Native Client 10.0][SQL Server]Incorrect syntax near ')'. (SQLExecute[102] at extpdo_odbcodbc_stmt.c:254)' in D:Hyposdvl-branchesjostrunkLibNotORMResult.php:122
        Stack trace:
        #0 LibNotORMResult.php(122): PDOStatement->execute(Array)
        #1 LibNotORMResult.php(379): NotORM_Result->query('SELECT * FROM l...')
        #2 NotORMResult.php(413): NotORM_Result->execute()
        #3 LibNotORMResult.php(505): NotORM_Result->fetch()
        #4 wwwfoo.php(69): NotORM_Result->offsetGet(1)
        #5 {main}
          thrown in LibNotORMResult.php on line 122

        copak se asi stalo? nastavim $no->debug = true;

        Notice: Use of undefined constant STDERR - assumed 'STDERR' in LibNotORMResult.php on line 116
        Warning: fwrite() expects parameter 1 to be resource, string given in LibNotORMResult.php on line 116

        ksakru, s widlema se s timhle můžu jít klouzat, dobrá

        $no->debug = function() {var_dump(func_get_args());};
        $row = $no->lolek[1];

        výsledek:

        array(2) {
          [0]=>
          string(33) "SELECT * FROM lolek WHERE (id = )"
          [1]=>
          array(0) {
          }
        }

        aha, vono se na webu sice píše, že s MSSQL to bylo testovaný, no asi sem neměl použít ODBC, ale ten experimentální dblib, kterej funguje zas jen na unixech;

        na vině je totiž NotORM_Result::qu­ote()
        $this->notORM->connection->quote($val)
        (btw takhle zformátovanej vnořenej ternární výraz, to se jen tak nevidí)

        takže šup, vohákovat, na quotování kašlu, jen chci vidět co to vrací

        <?php
        ...
        var_dump($row->update(array('id' => new NotORM_Literal('id + 1'))));
        // int(1)

        no a jak sem to napráskal na začátku, vrací to počet ovlivněnejch řádků

        no není ten NotORM úžasný?

        BTW toto:

        // friend visibility emulation
        abstract class NotORM_Abstract

        je MASAKR! (a není to jediná věc co mě při běhání po zdrojácích NotORMu rozesmála, odteď když budu někde číst o tom, jak se v PHP prasí, tak si vzpomenu na Jakuba Vránu)

        1. Jakub VránaAutor příspěvku

          Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

          Parafráze chyby je zcela nesmyslná, zápis $a = new X; $a = new Y; je v PHP zcela korektní a občas se používá. Když původní objekt potom protestuje, že jste na něm nezavolali nějakou metodu, tak to není něco, s čím by NotORM mohlo cokoliv udělat.

          K tabulkám, jejichž název nevyhovuje PHP identifikátoru, lze přistupovat přes složené závorky: $no->{"dbo.lolek"}[1], případně dočasnou proměnnou.

          V dokumentaci je jasně uvedeno, že $no->debug = true způsobí zapisování dotazů do STDERR. Nijak to nesouvisí s operačním systémem, ale s tím, odkud je skript spuštěn. Při spuštění z příkazového řádku směřuje tato konstanta na chybový výstup, při spuštění z webu si ji můžete nadefinovat třeba na otevřený chybový log.

          NotORM jsem testoval s ovladačem PDO_DBLIB v PHP 5.2 na Windows ( php_pdo_mssq­l.dll). O kompatibilitě s ODBC není nikde žádná zmínka.

          Metoda update skutečně vrací počet ovlivněných řádků přesně podle dokumentace.

          Co se NotORM_Abstract týče – jestli znáte lepší způsob, jak v PHP vytvořit vlastnosti a metody, které nejsou vidět zvenku a přitom je můžou volat třídy stejné knihovny, tak sem s ním! Nicméně mám pocit, že by vám asi nejlépe vyhovovalo, když by všechno prostě bylo public.

          Svým příspěvkem jste ukázal dvě věci: neumíte PHP a divíte se, že něco funguje přesně podle dokumentace.

          1. jos

            Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

            zdovolením se budu držet tykání, je tomu tak od začátku tohohle threadu

            ad parafráze: stěžoval sem si na to, že ať zavolam na instanci NotORM cokoliv, tak to bude mlčet do chvíle než to začnu třeba iterovat, zkus si to přečíst ještě jednou

            ad $no->{„dbo.lolek“}: FUJ!

            ad STDERR: oukej, souvislost se SAPI mi nedošla; když se tady ale oháníš tim jak je NotORM jednoduchej na používání (což nerozporuju), tak by sis tam měl sapi očichat a podle toho se zachovat

            ad PDO_DBLIB:
            a) v tom bodě sem si nestěžoval na NotORM, ale na PDO (BTW informace s čim a na čem si to testoval sou na notorm.com strohý)
            b) http://cz.php.net/manual/en/ref.pdo-dblib.php – je experimentální a s PHP 5.3 se už nedodává (používam 5.3.3)
            c) z dblib sme (ještě za časů 5.2) slezli, je to zabugovaný
            d) splet sem si to s něčim nad FreeTDS, to je buřt
            e) v tom pdo_odbc mají zřejmě chybu, klidně jí reportuj jestli chceš, databází s ODBC rozhraním je dost

            ad „public pocit“: ani náhodou, mělo by to bejt private; taky se v PHP snažim hrát si na OOP, ale neznamená to, že sem ochotnej dělat takovýhle prasečinky;

            ad „lepší způsob“: třeba to něčemu nastrkat do konstruktoru? ale ty seš tady veterán a já jen cucák, tak co bych ti radil jak programovat

            BTW tváří se to, že si můžu napískat jaká třída se má instancovat pro řádky výsledku, bohužel to musí dědit NotORM_Abstract

            ad um PHP: zdá se že sme dva, ale jenom jeden měl tu drzost napsat o PHP knížku

            ad fungování dle dokumentace: dyť sem se tomu nedivil, jen sem položil otázku, nedostal sem odpověď, tak sem to šel vyzkoušet a pak sem popsal co sem zažil než sem se dobral odpovědi

            svým příspěvkem sem se snažil ukázat dvě věci:

            1. Vrána je pololhář a demagog (dle zdejší diskuze je vidět že nejsem sám kdo si to myslí)
            2. dokáže to každej (bejt demagog)

            jo a ještě k tomu NotORM_Literal kterej mě tak zajímal (jen jako proof of misconcept):

            CREATE TABLE whatever (id DATETIME NOT NULL CONSTRAINT plk PRIMARY KEY);
            
            $no = new NotORM($pdo);
            $row = $no->whatever()->insert(array('id' => new NotORM_Literal('CURRENT_TIMESTAMP')));
            var_dump($row->delete());
            // int(0)

            a co teprve kdyby to bylo součástí podmínky „je menší než“

            1. Jakub VránaAutor příspěvku

              Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

              Za vykání se omlouvám. Tón tvého příspěvku mi vyzněl tak formálně, až jsem na dřívější tykání zapomněl :-).

              Je nějaký důvod, proč bys s výsledkem nic nedělal? Když NotORM řekneš „nedělej nic“, tak holt nedělá nic. To je jako kdyby ses rozčiloval, že když napíšeš $a = 5, tak se nic nestane s proměnnou $b.

              Jak bych se v případě webového SAPI měl zachovat? Vypsat to na standardní výstup a riskovat, že se to zobrazí uživateli na ostrém webu? Nebo generovat PHP chyby, i když to žádné chyby nejsou? Ne – nejrozumnější je podle mě opravdu současné chování – ať si to uživatel v tom případě určí sám.

              Co se MS SQL týče – máš nějakou zkušenost s driverem přímo od Microsoftu? S PDO_SQLSRV NotORM milerád otestuji, pokud je to reálně použitelné.

              Podporu pro ODBC přidávat nechci – nefunkčnost quote je vlastnost, nikoliv bug (jde o to, že každý systém escapuje jinak a zvenku nelze zjistit jak, tak quote radši nedělá nic).

              „Lepší způsob“ – metodu nastrkat do konstruktoru? Raději toho opravdu necháme.

              Co se toho dědění z NotORM_Abstract týče, mohl bys to prosím víc rozvést? Po pravdě řečeno jsem nikdy moc nepočítal s tím, že by tu třídu někdo dědil z něčeho jiného než z NotORM_Row, protože to je půlka NotORM. Ale zároveň nevidím důvod, proč by to nešlo a jednoduchý příklad mi funguje.

              Je vidět, že každému ta demagogie tak dobře nejde :-). A žádného pololhaní si skutečně nejsem vědom.

              Co se výsledku insert týče, tak jsem si této slabiny vědom. Napadá tě, co s tím? Původně totiž insert vracel jen lastInsertId (pokud bylo), což bylo z pohledu návrhu čistší. Ale vracet celou řádku je často velmi praktické (např. se díky tomu dá volat $db->article()->insert($article)->article_tag()->insert($arti­cle_tag)). Ale nevím, co s tím, protože této funkčnosti se vzdávat nechci, selectu navíc je škoda (skoro nikdy se nepoužije) a detekovat se to nijak nedá (uložit něco jiného se může kdykoliv třeba kvůli triggerům). Mimochodem Doctrine trpí stejným problémem, ne? Nejlepší mi prostě přijde na vývojáři nechat rozhodnutí o tom, jestli je potřeba tahat skutečně uložený řádek.

              1. jos

                Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

                Za vykání se omlouvám.

                já zase za tu ošklivou rétoriku co sem zvolil

                Je nějaký důvod, proč bys s výsledkem nic nedělal?

                není, ale tu chybu že zavolam metodu na jiný proměnný klidně udělat můžu a nedozvim se to

                Jak bych se v případě webového SAPI měl zachovat? Vypsat to na standardní výstup a riskovat, že se to zobrazí uživateli na ostrém webu?

                já bych to risknul, když už chce někdo debugovat na ostrým serveru, tak snad ví co dělá a nenakonfiguruje si NotORM tak aby debugovací hlášky viděl uživatel

                kdejakej začátečník by za to asi byl vděčnej, protože IMHO typicky nahodí na localhostě nějakej LAMP a pak chce rychle v browseru vidět jak mu to funguje a ne googlit co to je to STDERR a co má místo true přiřadit do NotORM::$debug

                na druhou stranu, ze svýho začátečnickýho období si pamatuju že sem nerad četl manuály, takže to může bejt i dobrá lekce

                Nebo generovat PHP chyby, i když to žádné chyby nejsou?

                tak když nevadí že to píšeš na stderr, tak E_USER_NOTICE mi nepřipadá zas tak odlišný

                BTW my nastavujeme display_errors podle přihlášenýho uživatele

                máš nějakou zkušenost s driverem přímo od Microsoftu

                jo (se sqlsrv.dll, ne s PDO obalem), dokud sme nenarazili na jeden nepříjemnej bug, tak sme si to nemohli vynachválit (nechá si nastavit výstupní kódování, vyrábí příslušný PHP datový typy (s ostatníma je všechno string), kompletní chybový hlášky, ne jen „the statement has been terminated“ jako s mssql.dll)

                ten bug – když v triggeru došlo k chybě která zmršila transakci (to sem poprvý viděl hlášku „transaction doomed“), tak se ten driver tvářil jako že je všechno OK a běžící skript si v lepším případě záhadně nabil držku (protože se snažil použít neexistující data), v horším to skončilo vyjímkou bez stackframe (možná kecam, je to už přes rok)

                bug sme nareportovali tušim ještě když byla verze 1.1, ve verzi 2.0 byl pořád

                a teď koukam, je venku 2.0.1, v changelogu (teda na tom blogu) nic nevidim, snad někde vyhrabu ten testcase a prubnu to

                Podporu pro ODBC přidávat nechci – nefunkčnost quote je vlastnost, nikoliv bug

                tak to je nemilý (že to takhle vzdali), a co si na uživateli v případě použití ODBC vynutit dodání quotovacího mechanismu? nebo ještě líp – zbavit se deklarovaný závislosti na PDO a dodávat s NotORM tenkej obal nad PDO aby uživatel mohl dodat svou implementaci?

                a nebo pro ODBC použít prepared statements? a nebo pro všechno?

                minimálně bych uživateli sdělil že s ODBC má zatim smůlu

                „Lepší způsob“ – metodu nastrkat do konstruktoru? Raději toho opravdu necháme.

                no já tam vidim kupu protected memberů a jednu metodu access() u který sem našel jen jedno volání na něčem jiným než $this, tak snad by to nebyl nepřekonatelnej problém

                Co se toho dědění z NotORM_Abstract týče …

                no kdyby někdo chtěl zapojit NotORM do existujícího projektu, přičemž by chtěl jako třídu výsledku použít něco svýho (nejlépe něčeho, co dědí netknutelnej kód dodanej třetí stranou), tak je nahranej

                nicméně ten scénář je dost zhovadilej, to jo

                … jsem si této slabiny vědom. Napadá tě, co s tím?

                buď aspoň hlučně upozornit uživatele v manuálu (možná už to tam je?), nebo radši při přístupu na ten atribut prostě líně šáhnout do databáze

                jak píšeš, teď v podstatě nutíš uživatele aby do tý databáze vlezl sám, protože přes ten Catchable fatal error co se vygeneruje při echování (toho atributu) se nedostane; přičemž uložení a použití od sebe může bejt v kódu dost daleko, takže to udělá pesimisticky pro každej případ

                1. Jakub VránaAutor příspěvku

                  Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

                  STDERR – rozhodování mezi tím, co považuji za nesprávné a přitom to je pohodlné pro uživatele, není nikdy jednoduché. Asi to zatím nechám tak, jak to je.

                  ODBC – třída PDO ani metoda quote není finální, takže si klidně můžeš vytvořit jejího potomka, který ti data ošetří na míru. Do NotORM ho dost dobře dát nejde.

                  Abstract – mě právě předávání parametrů do konstruktoru přestalo bavit, když už jich bylo asi pět a pořád přibývaly. To také není úplně nejšťastnější konstrukce.

                  Insert – To by asi celkem snadno šlo, díky za tip!

  3. Honza Marek

    Unit of Work

    Samozřejmě hlavním rozdílem při ukládání dat v Doctrine 2 a NotORM je v tom, že Doctrine 2 implementuje pattern Unit of Work. Zjednodušeně to znamená, že Doctrine má přehled o všech entitách a pokud na entity manageru zavolám metodu flush, tak UOW zjistí, co je nového, otevře transakci, vymyslí si nějaké SQL dotazy, provede je a commitne transakci. O veškeré sledování změn a případnou optimalizaci se v NotORM musí starat programátor.

    Osobně nechápu, jak tato informace může být v porovnání opomenuta.

  4. Nox

    Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

    2. Type hinting?

    3. Do neexistujícího sloupce? Doctrine výslovně operuje s tím, že entita != tabulka (entita může být v části tabulky ale i napříč několika tabulkami), tudíž mi tento bod nedává smysl.
    Osobně místo docblock => databáze pracuji databáze => docblock, takže kromě úpravy relací mám všechny settery i s type hintingem automaticky = téměř 0 práce navíc (co se setterů týče, třeba to taky tak někomu bude vyhovovat).

    5. Pokud z entity nechcete číst, stačí zvýšit pomocí DQL. Pokud chcete, 2 dotazy být musí. I když asi může nastat situace, kdy to není jasné dopředu…

    6. DQL

    7. Nechápu motivaci pro tento bod… mě osobně je jedno jestli si něco vytváří pokud to není enormní množství dat atp. Člověk někam nastaví složku a pak už o nějakých proxy nemusí vůbec vědět a když to smažete, nic se nestane… To je jako stěžovat si že framework vytváří cache soubor

  5. Palo

    Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

    No neviem, mne osobne sa napriek všetkému úsiliu autorov Doctrine projektu NotORM zdá lepším riešením. Jednoduchšie sa v tom programuje a výsledok je efektívnejší.

    6. bod je ukážkovým príkladom, prečo by som Doctrine nepoužil. Podľa jedného z autorov sa k tomu používa DQL, ktoré je abstrakciou nad SQL.
    Lenže ja ju v jeho nasledujúcom príklade nevidím:
    $em->createQuery("UP­DATE Article a SET a.visits = 0")->execute();
    To som rovno mohol použiť:
    $mysql->query("UPDATE Article a SET a.visits = 0");
    Výsledok by bol rovnaký. Mám z toho taký pocit, že v Doctrine sa DQL používa všade tam, kde to ORM efektívne nedokáže. DQL by som teda prirovnal k takému „hackovaniu“ ORM.

    1. v6ak

      Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

      Toto zastávání nativního SQL před DQL je jako kritizovat OOP na jednoduchém příkladě, kdy nemá přínos.

      DQL (HQL, …) nabízí práci s objekty, které nabízejí mapř. i dědičnost. V SQL je to problematické.

      To, že jedno řešení je v jednom případě zhruba stejné jako druhé. ještě neznamená, že tomu tak bude vždy.

      1. Jakub VránaAutor příspěvku

        Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

        Já milerád vyřeším nějaký příklad, kde by měly výhody Doctrine vyniknout. Zkus prosím napsat nějaké zadání (co se má udělat, nikoliv jak se to má udělat – jako kdyby to psal manažer).

          1. Jakub VránaAutor příspěvku

            Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

            Přiznám se, že vůbec nevidím, jak by při řešení této úlohy mohlo Doctrine vyniknout. Vím o možnostech dědičnosti (Mapped Superclass odpovídá bodu 4, Single Table Inheritance bodu 1+2 a Class Table Inheritance bodu 3), ale to nic nemění na tom, že se musím rozhodnout, který přístup si vyberu, a že každý z nich má svoje nevýhody.

            Zkus to konkrétněji – který způsob bys pro řešení toho problému vybral?

            1. notnotorm

              Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

              A není právě pohodlná dědičnost tabulek výhodou Doctrine2 oproti NotORM? Zadání myslím není potřeba více upřesňovat. Pokud se totiž „špatně“ rozhodnu v Doctrine2, tak jednoduchou změnou konfigurace (metadat pro mapování) vyberu jiný typ dědičnosti a do aplikačního kódu vůbec nezasahuji.

        1. František Kučera

          Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

          Ad „Zkus prosím napsat nějaké zadání (co se má udělat, nikoliv jak se to má udělat – jako kdyby to psal manažer).“

          Budu stručný: „napište to levně a rychle“

          :-)

          (samozřejmě ORM není všelék, při použití mizerné technologie to dopadne blbě, stejně tak špatný kód nebo použití ORM na nesprávném místě způsobí škodu – ale jinde to naopak ušetří peníze a zrychlí vývoj)

        2. notnotorm

          Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

          Manažer:
          Zákazník chce do existující řešení přidat podporu pro vícejazyčnost a to tak, že nechce samostatné weby. Výchozí jazyk bude stávající. Nevyplněná data pro jiný jazyk se použijí z výchozího jazyku. A když už to budete dělat, tak tam prosím přidejte verzování změn.

          Řešení pomocí Doctrine2:
          Jelikož pro aplikaci platí že model != databáze je taková úprava velmi snadná.

          • Zavedou se rozhraní Translatable (např. metody getActualLocale(), setActualLocale() a getTranslatable­Fields()) a Versionable, které budou implementovat modely nebo jejich rodičovská třída.
          • Vytvoříme 2 třídy navíc, které nám vygenerují schémata (objekt -> tabulky) pro zvolený typ ukládání jazykových mutací a ukládání informací o verzích (způsob ukládání do tabulke je libovolný).
          • Celou logiku pro každý model budou vykonávat jen další 2 nové třídy – listenery s metodami onFlush(), postLoad(), …
          • Nastavení aktuálního jazyku, výhozího jazyku a registraci listenerů zařídíme změnou konfigurace Dependency Injection Containeru (např. ze Symfony2).

          Nyní již máme vícejazyčný a verzovací web hotov – 4 nové třídy, změna třídy EntityRepository, ze které dědí všechny repository modelů a úprava konfigurace. Téměř žádný zásah do kódu samotné aplikace (závisí na objektovém návrhu, architektuře původní aplikace apod. – nesmí to být bastl). A možná spousta automaticky vygenerovaných tříd, které mi vytváří generátor kódu (např. pokud zvolím, že každá entita bude mít svou vlastní extra „tabulku“ pro překlady nebo verze).

          1. Jakub VránaAutor příspěvku

            Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

            Když je to tak jednoduché, můžete to tedy ukázat na stávajícím příkladě? V tabulkách category a tag bych chtěl mít názvy ve dvou jazycích (třeba angličtina a čeština), články budou vždy v jednom jazyce (nebudou překládané, čeština a angličtina bude mít různou sadu článků). A chtěl bych mít možnost vložit kategorii (včetně všech podporovaných jazyků), vložit článek (v zadaném jazyce) a vypsat seznam článků a seznam kategorií.

            Zdrojáky jsou k dispozici, takže by to snad neměl být problém.

            1. notnotorm

              Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

              Popis řešení v Doctrine2 jsem již načrtl. Nezlobte se na mě, ale vážně nemám čas Vás učit pracovat s Doctrine2. Jasně jsem napsal, že aplikace musí být navržena způsobem, že model != tabulka (jde o pohled na problém). Ukázková aplikace, na kterou vede odkaz, představuje spíš sadu skriptů pro práci s tabulkami a ne aplikaci s dobře definovaným modelem. Je politování hodné, že jsou neustále srovnávány dva nástroje pro práci s daty pouze z jedné strany a druhá strana je opomíjena (možná se Vám ji nedaří vidět). A tímto přístupem je veden celý seriál srovnávající NotORM a Doctrine2. Je potřeba si vážně uvědomit, že první písmeno ve zkratce ORM znamená Object. To znamená, že chci na straně aplikace pracovat s objekty, využívat veškeré výhody OOP a Doctrine2 mi má nějak zajistit namapování těchto objektů na databázi (ať už RDBMS nebo OODBMS).

              Pro lepší pochopení načrtnutého řešení dodávám pár postřehů:

              Jelikož je k dispozici dostupné řešení automatického překladu entit https://github.com/l3pp4rd/DoctrineExtensions, nemá myslím cenu psát znovu ukázkovou aplikaci.

              1. Jakub VránaAutor příspěvku

                Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

                Návrhem modelu se bude zabývat třetí díl seriálu, to avizuji od samého začátku. Že model není tabulka, je zcela samozřejmé a platí to jak pro Doctrine, tak pro NotORM.

                Já po vás nechci, abyste mě učil pracovat s Doctrine. Chci pouze podložit tvrzení „to je strašně jednoduché, udělalo by se to takhle a takhle“. Dokud není hotový kód (který by opět mohl vzniknout pro Doctrine i pro NotORM), tak je to pouhé teoretizování. Takže je škoda, že si na podložení svých výroků (které by jistě zajímalo i ostatní čtenáře) nenajdete čas.

                1. notnotorm

                  Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

                  Vždyť jsem psal, že už to někdo napsal. A řeší to úplně podobným způsobem http://www.gediminasm.org/article/translatable-behavior-extension-for-doctrine-2.

                  Zavádí rozhraní Translatable https://github.com/l3pp4rd/DoctrineExtensions/blob/master/lib/Gedmo/Translatable/Translatable.php a pro veškerou logiku používá jeden listener (z důvodu abstrakce pro použití jak RDBMS tak OODBMS je rozdělen na abstraktní třídu https://github.com/l3pp4rd/DoctrineExtensions/blob/master/lib/Gedmo/Translatable/AbstractTranslationListener.php a ORM nebo ODM třídu).

                  Už teď jsem zvědaví na třetí díl. Je zajímavé sledovat, jak ikona české scény PHP se snaží neustále všechny přesvědčit, jak je ORM téměř nanic (nebo aspoň, že Doctrine2 to dělá blbě). Mě to vážně připadá jako kdybych řekl, že na Hello World je nejlepší procedurální programování a tím pádem je vždy lepší než objektově orientované programování. A ještě zajímavější je sledovat, jak se nechají takhle zmanipulovat ostatní PHP programátoři http://php.vrana.cz/doctrine-lead-developer-explains-my-wtfs-part-2.php#d-11371.

                  1. Jakub VránaAutor příspěvku

                    Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

                    Zrovna jednoduché mi to tedy nepřijde. Právě proto jsem to chtěl vidět na současném příkladu – ideálně nejen jak by se změnil kód, ale i jaké by se vytvořily tabulky a jaké by se položily dotazy (a zda by měly šanci být efektivní). Pak bychom toto řešení opět mohli srovnat s tím, jak by se to udělalo v NotORM.

                    V tomto seriálu se nikoho o ničem přesvědčovat nesnažím. Na jednoduchém zadání jsem si vyzkoušel Doctrine, narazil jsem na nějaké problémy, znám elegantnější řešení onoho zadání a se vším tímhle jsem seznámil čtenáře. Jen prostě nemám příliš velkou důvěru v knihovnu, kde i jednoduché věci se dělají dost krkolomně a provádí neefektivní kód.

                    Možná o překladech vytvořím čtvrtý díl, když se k psaní kódu nemáte sám.

    2. František Kučera

      Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

      Ad „Mám z toho taký pocit, že v Doctrine sa DQL používa všade tam, kde to ORM efektívne nedokáže.“

      Pozor: tyhle *QL (jako DQL) jazyky jsou součástí ORM. ORM neznamená, že místo psaní dotazů budu jen volat nějaké metody – to je jen jedna z možností – ta druhá je psaní dotazů – pořád je to ORM, ale ten jazyk není SQL, ale je to trochu jiný dotazovací jazyk, který pracuje na úrovni objektů.

  6. František Kučera

    Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

    Ad $article->category = $values["cate­gory_id"]

    Je něco překvapujícího na tom, že do proměnné, která má obsahovat objekt (kategorii), nemůžu přiřadit primitivní datový typ (číselné ID kategorie)? Mě na tom tedy nic nepřekvapuje. (ale možná jsem jen „zmlsaný“ staticky typovanými jazyky)

    Ad „Pokus o přiřazení neplatné entity nezpůsobí žádnou chybu. Místo toho se prostě přiřadí hodnota NULL.“

    Jako kategorii jsme nastavili null, tak se NULL uloží do databáze. V modelu asi není NOT NULL, tak se prostě uloží. Je na tom něco divného? Metoda find() vrací pro neexistující entity null, což je celkem standardní chování, podle mého nic nečekaného.

    Ad „Vynulování počtu návštěv u všech článků si vyžádá tolik dotazů, kolik je článků.“

    Když iteruji přes všechny články a každý samostatně ukládám, tak se logicky provede tolik UPDATů, kolik je článků. Framework prostě dělá to, co mu programátor řekne – podle mého opět nic překvapivého nebo záludného.

    Disclaimer: autor názoru má rád SQL a rozhodně se ho neštítí. Má celkem rád i ORM*, ale respektuje, že ne na všechny úlohy je vhodné (což lze vyřešit použitím nativního SQL pro vybrané části aplikace).

    *) obecně – Doctrine 2 nezná a nepoužívá

  7. designerrr

    Re: Videotutoriál Doctrine 2 a NotORM: ukládání dat

    Jen tak pro info ty proxy třídy tam nejsou pro nic za nic, ale kvuli lazy loadingu. Vygeneruje se třída, která obsahuje gettery pro všechny attributy a v případě přístupu přes getter se záznam nahraje až když je opravdu potřeba. Proto taky není moc chytré používat ty public attributy, při přístupu k nim se totiž těžko něco ověří.

Napsat komentář

Tato diskuse je již příliš stará, pravděpodobně již vám nikdo neodpoví. Pokud se chcete na něco zeptat, použijte diskusní server Devel.cz

Zdroj: https://www.zdrojak.cz/?p=3405