Symfony, Propel und SQL Aggregate Functions

Da ich jetzt fast zwei Stunden gebraucht habe um einen GROUP BY und COUNT query in Symfony hinzukriegen, hier mal die Erklärung dazu.

Bei Google hab ich auch nichts sonderlich hilfreiches gefunden, bis auf einen Beitrag:
hier … und da die letzte Antwort.

Will man also einen Query wie folgt mit Propel bauen:


SELECT referer.ID, referer.IP, referer.CREATED_AT, count(*) AS cnt

FROM `referer`

WHERE referer.CREATED_AT >'2009-07-22 00:00:00'

GROUP BY referer.URL

ORDER BY referer.CREATED_AT ASC LIMIT 25

macht man so:

$c = new Criteria();
$c->addAsColumn('cnt', "count(*)");
RefererPeer::addSelectColumns($c);
$c->add(RefererPeer::CREATED_AT,date('Y-m-d').' 00:00:00',Criteria::GREATER_THAN);
$c->addAscendingOrderByColumn(RefererPeer::CREATED_AT);
$c->addGroupByColumn(RefererPeer::URL);
$c->setLimit(sfConfig::get('max_refererdashboard',25));
$called = RefererPeer::doSelect($c);

Die Objekte im Ergebnis Array enthalten nun aber nicht die neue Column ‘cnt‘.
Die muss man dem Model noch beibringen.

Um das Model Objekt zu erstellen benutzt Symfony eine hydrate() Funktion aus der Base Klasse.
Die muss im Model überschrieben werden und darin die neue Column cnt in das Ergebnis Objekt aufgenommen werden.

ungefähr so:

class Referer extends BaseReferer
{
public function hydrate($row, $startcol = 0, $rehydrate = false)
{
$r = parent::hydrate($row, $startcol, $rehydrate);
$this->cnt = $row[7];
return $r;
}
}

Dann gehts!