Článek v rubrikách:

»PHP
»MySQL

ORM, dibi, MySQL defaultní hodnoty (pokračování článku)

Článek rozebírá konkrétněji diskusi o nakládání s defaultními hodnotami ve vlastním ORM.


Defaultní hodnoty ORM a CRUD

Co je cílem? Stavíme vlastní ORM. Chceme vymyslet logiku nakládání s defaultními hodnotami, blíže v tomto článku MySQL povinné hodnoty, NULL hodnoty, defaultní hodnoty, prázdné hodnoty a jak by se mělo chovat ORM.

Víceméně se budeme omezovat na PHP 5.3 a vyšší (late static binding se bude hodit).

Potřebujeme zabezpečit klasický CRUD (create, read, update, delete).

Mnou zvolené použití:

Insert

Způsob I1,

  1. $c=new Customer();
  2. $c->name="František Omáčka";
  3. $c->save();

alternativně způsob I2,

  1. $c=new Customer(array('name'=>"František Omáčka"));
  2. $c->save();

alternativně způsob I3,

  1. $c=Customer::create();
  2. $c->name="František Omáčka";
  3. $c->save();

Read

Způsob R1 (tam asi není co řešit, zatím není důležité jak tohle bude realizováno),

  1. $c=Customer::find(1);

Update a Delete

V podstatě řešíme stejný problém, u delete jsou nám defaultní hodnoty lhostejné, ale půjde o stejný problém, přece je zbytečné z databáze načítat řádek, když ho chci smazat.

Při updatu mi záleží na tom, aby nebylo vždy nutné načíst dopředu záznam z databáze před jeho úpravou! A teď kudy do toho, pokud nechci načítat dopředu, nepoužiji find() nebo podobnou metodu. Vytvářet novou instanci new Customer by mohlo být matoucí, co takhle tedy, jak navrhuje Jakub Vrána (getByPrimary), to ale také trochu zavání tím, že se to načítá z databáze (programátor by to tak mohl chápat?) a mohlo by to být matoucí.

Každopádně bude důležité vytvořit instanci tak, aby se nenastavovali defaultní hodnoty. V případě nastavení defaultních hodnot by pak při volání metody save() objekt vždy myslel, že byly nastaveny i hodnoty, které se nastavili jako defaultní a při updatu by je přepsal!

Způsob U1,

  1. $c=Customer::getByPrimary(1);
  2. $c->name="František Omáčka";
  3. $c->save();

alternativně nevhodný způsob U2,

  1. $c=new Customer();
  2. $c->ID=1;
  3. $c->name="František Omáčka";
  4. $c->save();

Tento způsob ani nebude možný! Protože v konstruktoru se automaticky nastaví defaultní hodnoty.

Takže dotaz zní: Kdy a kde nastavovat v ORM defaultní hodnoty a zda vůbec potřebujeme v ORM objektu pracovat s defaultními hodnotami.

UPDATE 9.12.2009

Začal jsem psát ukázku jak by takové ORM mohlo vypadat, přepsal jsem nějaké své staré kódy a nějaký starší pokus, který už jsem zde prezentoval ORM, Zend_Db, Doctrine, DibiTableX a co bych navrhl pro dibi, prošel jsem také Ormion od Honzy Marka (výhodou je, že se zabývá dibi, což je cílem).

Rozhodl jsem se hodně přiblížit kódu Ormionu, i když některé věci bych popsal jinak. Čerpat lze také z www.phpactiverecord.org. To jsou snad jediné věci, které se zabývají PHP 5.3 a ORM. Jde snad o nejnovější pokusy k dnešnímu dni.

Základním souborem pro ORM jsem zvolil továrnu Db.php, která má za úkol pouze vytvářet a vracet konfigurační soubory pro jednotlivé objekty. Nebo vracet připojení k databázi, typicky objekt DibiConnection, případně jiný layer, továrna Db tedy neslouží jen pro ORM, ale pro použití i mimo ORM, naše ORM bude plně svázané s dibi. Jsou zde také uloženy všechny Exceptions, ale asi by měli být ve zvláštním souboru.

Samotný konfigurační soubor jsem definoval např. takto CustomerConfig.php, k vytvoření takového souboru používám skript, který analyzuje mysql tabulku a vytvoří potřebné direktivy, stačí zadat jen název tabulky. Celé ORM se skládá ze třech abstraktních tříd DbRow.php, DbTableConfig.php a DbTable.php (ta zatím není důležitá).

podobné články

09.12.2009DbDibiOrm(67%)
15.12.2009DbDibiOrm - DibiConnection - staticky, instančně, přistupovat přímo k dibi factory?(33%)
15.12.2009ORM, Row Data Gateway, Table Data Gateway, Active Record, Data Mapper(33%)
03.12.2009MySQL povinné hodnoty, NULL hodnoty, defaultní hodnoty, prázdné hodnoty a jak by se mělo chovat ORM(33%)
22.07.2009ORM, Zend_Db, Doctrine, DibiTableX a co bych navrhl pro dibi(33%)