Doctrine migráció, lehet egyszerűbben?
Már nem először volt egy “kevés” szívás a Doctrine migrációkkal. Ma éppen az jött elő, hogy PostgreSQL tábla alatt kellett volna primary key-t cserélni. Ennek véghezvitelében “rengeteget” segített a Doctrine semmitmondó dokumentációja. A probléma lényege, hogy egy migráció kell a korábbi primary key eldobásához, egy pedig az új felvételéhez. Kész elmebaj.
Mielőtt végképp frusztrálni kezdett volna a dolog fogtam a db connection-t és nyers sql parancsokkal elintéztem a dolgot. Megvolt 5 perc alatt, azt csinálta, amit én szeretnék, ráadásul még ismerem is.
Ezzel párhuzamosan elgondolkoztam, hogy mi is egy migrációt kezelő alrendszer lényege (és miért ilyen bonyolult a Doctrine). Alapvetően két osztálytípusra van szükség:
- egy menedzser osztályra, amely vezérli a migrációt egyik lépésről egy másikra
- egy (jobban mondva több) osztály, amely(ek) az egyes migrációs lépéseket reprezentálják
Nézzük a másodikat, az ugyanis az egyszerűbb. Itt egy interface-t kell definiálnunk, amit bármilyen osztály megvalósíthat:
interface MigrationStep
{
public function up(PDO $con);
public function down(PDO $con);
}
A menedzser osztály kicsit bővebb
class MigrationManager
{
private $_pdo;
public function __construct(PDO $pdo)
{
$this->_pdo = $pdo;
}
public function migrateTo($step = null)
{
// migrál a megadott lépésig, null esetén a legfrissebb állapotig
// végigmegy a lépéseken az aktuális állapottól (->getVersion()) a $step-ig
// közben betölti a lépést, példányoítja, futtatja, minden lépés végén menti a verziót
}
public function getMigrations()
{
// visszaadja a migrációs lépéseket tartalmazó file tömbjét
// migrációs lépés száma => file elérési útja párként
}
public function getVersion()
{
// visszaadja az aktuális verziót
}
public function setVersion()
{
// beállítja a migrált verziót
}
}
Ehhez kell néhány megállapodást tenni:
- a migrációs lépések egy könyvtárban vannak
- a migrációs lépés file-ok formátuma LÉPÉS_OSZTÁLYNÉV
pl. 12_ArticlePrimarykeyUpdate.php
Úgy gondolom ennyi a migráció és nem több. Ennyire van szükség. A Doctrine által bevezetett plusz API csak kavarás, felesleges tanulnivaló (lenne, ha érdekelne).
Hodicska Gergely 23:37 on 2010. 01. 13. Permalink
Az én megközelítésem a következő volt:
- Az esetek túlnyomó többségében a template-nek átadott paramétereket escape-elni kell. (Az, hogy ez épp tömb kulcs vagy nem, az lényegtelen, ami bele teszünk egy HTML oldalba, arra kell a htmlspecialchars, nem építünk arra, hogy X mezőben csak szám lehet stb., mindig escape-elünk.)
- Ha valamiért mégsem escapelve van szükség az adatra, akkor az legyen elérhető az eredeti formában is.
E kettő nyomán: alap esetben a template változók már automatikusan escape-elve is vannak (az hogy ez hogyan történik, azt a válasz formátuma határozza meg), így ha épp valaki siet, akkor sem fordulhat elő, hogy elfelejti (és ott van kapásból a biztosnági rés), és ha neked nem az escape-elt változat kell, akkor ott már egy tudatos fejlesztői döntés miatt fogod az eredetit használni.
Szabolcs Sulik 08:53 on 2010. 01. 14. Permalink
Igen, a symfony-ban is így van, output escaper példányokba csomagolja a változókat. Ezzel csak annyi a problémám (nem is annyira probléma, inkább furcsa), hogy szeretek/szeretnék helperekben, metódusokban type hinteket használni, és kicsit érdekesen mutat az
echo show_me_the_user($user->getRawValue())hívás a sablonban. Emellett a ZF 2.0-ben is bevezetnek majd hasonló eljárást. Azt is olvastam, hogy a symfony-s coredev-ek szerint pont ez a feature a leginkább performance killer.Mind mindenhol, itt is lehet érvelni mellette és ellene is. A greebo-ban elsősorban a minimalizmus a célom, nem feltétlenül az, hogy bolondbiztos megoldást adjak a problémákra
. Az cél kettős: 1. minimális API bevezetése (amit a PHP tud azt használom, és sok mindent tud
), 2. a lehető legegyszerűbb, legkevesebb osztállyal megoldható felépítés (6 osztály az essence és 6 osztály a conveniences “csomagban”). Majd írok egy hosszabb bejegyzés a témában részletesen kifejtve a gondolataim.
Emellett majd ki fogom próbálni, hogy milyen válaszidőt produkál a rendszer, ha van benne valamilyen automatikus escapelés.
A templatezéssel a küzdelmem inkább arról szól, hogy egy osztállyal és dekorációval szeretném (és fogom is, már megvan a felépítés) megoldani (értsd template inheritance). Emellett a symfony component mintájára kap majd egy plusz metódust, ahol a templatehez esetlegesen tartozó logika foglal helyet.
Szabolcs Sulik 16:18 on 2010. 01. 14. Permalink
Na megnéztem, a symfony a tömb kulcsait nem escapeli.