MySQL-spezifische Funktionen in DQL nutzen

in  Zikula Apps , ,

MySQL-spezifische Funktionen in DQL nutzen

Im Kern von Doctrine 2 wird Wert darauf gelegt, dass die Doctrine Query Language (DQL) möglichst portabel bleibt, damit Projekte einfach mit unterschiedlichen Datenquellen arbeiten können. Bei Webanwendungen kommt es immer wieder einmal vor, dass man eine bestimmte Funktion benötigt, die zwar in MySQL existiert, jedoch nicht von DQL unterstützt wird.

Man kann in solchen Fällen eigene DQL-Funktionen erstellen, dies ist aber in den meisten Fällen zum Glück nicht nötig. Denn in den DoctrineExtensions von Benjamin Eberlei befinden sich bereits eine ganze Reihe von MySQL-Funktionen. Dieses Paket ist idealerweise auch im Zikula Core enthalten, so dass man sie für die eigenen Module direkt nutzen kann.

Zumindest in Zikula 1.3.x sind die Funktionen aber per Standard nicht via Symfony registriert (für 1.4 habe ich das nicht nachgeschaut, aber dort verhält es sich vermutlich ähnlich). Daher habe ich einfach die Funktionen, die ich benötigt habe, geladen und dem EntityManager von Doctrine bekannt gemacht. Das folgende Beispiel ist Code aus einer Repository-Methode, die eine gegebene QueryBuilder-Instanz erweitert:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$config = $this->getEntityManager()->getConfiguration();
$config->addCustomNumericFunction('ACOS', 'DoctrineExtensions\\Query\\Mysql\\Acos');
$config->addCustomNumericFunction('COS', 'DoctrineExtensions\\Query\\Mysql\\Cos');
$config->addCustomNumericFunction('RADIANS', 'DoctrineExtensions\\Query\\Mysql\\Radians');
$config->addCustomNumericFunction('SIN', 'DoctrineExtensions\\Query\\Mysql\\Sin');
$qb->addSelect(
    '(6371 * ACOS( COS( RADIANS(\'' . $lat . '\') )
        * COS( RADIANS( tbl.latitude ) )
        * COS( RADIANS( tbl.longitude ) - RADIANS(\'' . $long . '\') )
        + SIN( RADIANS(\'' . $lat . '\') )
        * SIN( RADIANS( tbl.latitude ) ) ) ) AS ' . /*HIDDEN */ 'distance'
)
->having('distance <= :distance')
->setParameter('distance', $radius)
->orderBy('distance');

Das Keyword HIDDEN ist derzeit auskommentiert, da in Zikula 1.3 noch eine ältere Version von Doctrine 2 verwendet wird, die dieses Schlüsselwort noch nicht unterstützt. Bei der Umstellung des Modules auf 1.4 wird es dann aktiviert, was die weitere Behandlung des Abfrageergebnisses etwas vereinfacht. Denn mit dem zusätzlichen Feld distance liefert die Abfrage nicht mehr die selekterten Objekte alleine, sondern ein Array mit Paaren aus den Objekten und dem neuen Feld zurück.

Weitere Beiträge in Kategorie Zikula Apps

Kommende Neuerungen in Symfony 5.2
- Vor zwei Tagen wurde Symfony 5.2.0-BETA2 veröffentlicht. Dies nehme ich zum Anlass, um einmal einen Überblick über die wichtigsten neuen Funktionen zu geben, auf die wir uns im Rahmen dieses Updates …
Zikula Core 3.0.3 mit Sicherheits-Update von Symfony 5
- Vor kurzem hatten wir über das Release von Zikula 3.0.1 berichtet, welches wichtige Korrekturen für Zikula 3 bereitgestellt hat. Vor einer Woche wurde die nächste Version 3.0.2 veröffentlicht. …
Symfony Services asynchron im Hintergrund aufrufen
- Oftmals greift man in Symfony-Projekten auf CLI-Kommandos mit Hilfe der Symfony Console-Komponente zurück, um länger laufende Prozesse außerhalb des Webservers durchzuführen. In komplexeren Vorhaben …
Zikula 3.0.1 veröffentlicht - erstes Bugfix Release für Zikula Core 3
- Genau einen Monat nach der Veröffentlichung von Zikula 3.0.0 ist nun das erste Update erschienen. Zikula 3.0.1 bringt wichtige Korrekturen und sorgt somit für ein Stück mehr Stabilität in der neuen …
Zikula Framework in Version 3 veröffentlicht
- Heute haben wir das finale Release von Zikula Core 3.0.0 veröffentlicht. Es basiert auf Symfony 5.1 sowie Twig 3 und verwendet unter anderem Bootstrap 4 und Font Awesome 5. Einen grundlegenden …