Hurmetta ja lurexia

elokuu 27, 2008

Doctrine

Filed under: Ohjelmointi,Työjuttui — Olli @ 23:26

Oulurastisivustoa uudistaessani päätin ottaa härkää sarvista ja ottaa viimeinkin käyttöön valmiita työkaluja nollasta lähtemisen sijaan. Symfonyyn tutustuessani ihastuin sen käyttämään ORM:n (Propel) helppouteen ja siitä lähtien olen halunnut moista jossain projektissa käyttää. ORM (Object Relational Mapper) tarkoittaa siis relaatiotietokannan käsittelyä normaalien olioiden avulla. Hieman eri frameworkkeja tutkittuani päätin kokeilla Doctrinea, josta olen kuullut hyvää puhuttavan ja varsin hyvältähän tuo ensituntumalta vaikuttaa.

Otetaanpa esimerkkinä tuoreimpien uutisten hakeminen. Vanha koodi meni jotakuinkin seuraavasti:

<?php
$db     = DbConnector::connect();
$news   = array();
$query  = "SELECT u.id, u.otsikko AS title, u.teksti AS text, " .
              "COALESCE(s.lyhenne, 'Webmaster') AS author, " .
              "UNIX_TIMESTAMP(u.aika) AS date " .
          "FROM news u " .
          "LEFT JOIN club s ON u.seura_id = s.id " .
          "ORDER BY u.aika DESC";

$db->setLimit($limit, $offset);
$db->query($query);

while ($row = $db->fetchAssoc())
{
  $newsItem = new NewsItem();
  $newsItem->setId($row['id']);
  $newsItem->setTitle($row['title']);
  $newsItem->setText($row['text']);
  $newsItem->setDate($row['date']);
  $newsItem->setAuthor($row['author']);

  $news[] = $newsItem;
}

return $news;
?>

Ok, myönnetään, eipä tuo muutenkaan mitenkään vängästi ole toteutettu aikoinaan. Mutta sitten sama Doctrinea käyttäen (nimesin samalla taulujen kentät uudelleen):

<?php
$news = Doctrine_Query::create()
          ->from("News n")
          ->leftJoin("n.Club c")
          ->limit($limit)
          ->offset($offset)
          ->orderBy("n.news_date DESC")
          ->execute();

return $news;
?>

Hieman hommaa järkeistin myös siirtämällä ajan muotoilun ja puuttuvan nimen muotoilun näkymän puolelle, jolloin ollaan jälleen lähempänä MVC-mallia. Mutta nyt siis tuota palautettua Doctrine_Collection-tyyppistä oliota voi iteroida normaalisti taulukon tapaan, sillä se muistaakseni toteuttaa ArrayIterator-rajapinnan. Yksittäisten olioiden kenttiin pääsee käsiin seuraavilla tavoilla:

<?php
// tulostaa esim. "Olli"
echo $item->author;
echo $item->get('author');
echo $item['author'];
?>

Ja mikäli viiteavaimet ovat kunnossa, myös vierastaulujen kenttien käsittely onnistuu helposti:

<?php
echo $item->Club->name; // tulostaa esim. "Oulun Tarmo"
?>

Näppärää, eikö? Kovin suuria kommentteja en Doctrinesta vielä näin parin tunnin testailun perusteella osaa esittää, mutta vaikuttaa ihan hyvältä. Pienenä haittapuolena tuo käyttämäni 0.11-versio ei osaa lisätä relaatioita luomilleen malleille, kun mallit luodaan käyttämällä jo olemassa olevaa tietokantaa. Esimerkiksi YML-tiedostoista homma onnistuu ongelmitta, mutta nyt eri olioiden (tai taulujen) suhteet täytyy lisätä luokkiin manuaalisesti.

Jatkanpa tutustumista.

Powered by WordPress