Inhalt
Mai 2011
Beitrag1492
BeitragGeburtstagsstress
April 2011
Beitrag61147 Nummer 2: Zusammenführen, Mischen, Verbinden
BeitragMühle
BeitragDie Entwickler-Ecke und Spamlisten
März 2011
BeitragServerupdate
Februar 2011
Beitrag61147 Nummer 1: jQuery
Beitrag61147 oder: Wir leben noch!
Dezember 2009
BeitragAGS 2009 - Behind the Scenes
August 2009
BeitragSturmfrei - EE-Teamtreffen
April 2009
BeitragRoadmap für die Forensoftware
Januar 2009
BeitragProfil-Sucht
September 2008
BeitragUpdates: Mehr, aber kleiner
Juli 2008
BeitragErster! Oder: In fünf Monaten ist Weihnachten.
Mai 2008
BeitragKinder, wie die Zeit vergeht...
April 2008
BeitragDer Serverumzug und das liebe Geld...
März 2008
BeitragVon "Hey, wo ist meine Änderung geblieben?" zu Subversion
BeitragMono, Baby, Mono!
Dezember 2007
Beitrag172800000
November 2007
BeitragAdventsgewinnspiel 2007
Juli 2007
BeitragDas Jubiläumsgewinnspiel
BeitragStatusbericht zum neuen Server
Juni 2007
Beitrag8 Std. Downtime heute nacht
BeitragOh Gott, bitte nicht noch ein Browser ...
BeitragAb jetzt haben wir eine Projektverwaltung :-)
Mai 2007
BeitragDowntime am Freitag Abend
April 2007
BeitragDelphi Tage 2007
BeitragVorspiel
BeitragVorfreude
März 2007
BeitragPolitik im Off Topic
Beitragein sehr leeres Forum...
BeitragDie Jagd auf Spammer
Januar 2007
BeitragBackporting
Dezember 2006
BeitragDas Adventsgewinnspiel 2006
BeitragDie nächste Auskopplung
 
Sitemap
Ein Blog-Eintrag von Christian S. (Di 01.12.09 23:48)
Views: 1139866
Hallo!

Einleitung
Wie Ihr hoffentlich bemerkt habt, gibt es auch dieses Jahr wieder ein Adventsgewinnspiel. Vorher wurde - in einigen Monaten mehr, in mehreren Monaten weniger - die Software überarbeitet. Nach außen hin tatsächlich eher weniger als mehr.

Doch diese Überarbeitung der Gewinnspielsoftware ist viel mehr. Sie dient mir als Test für gleich zwei große Umstellungen, die nach und nach die gesamte EE-Software erreichen werden:

1. Die Umstellung von mysql auf mysqli.
2. Die Umstellung der Software auf einen objektorientierten Ansatz.

Die Quiz-Software ist der ideale "Spielplatz", um Patterns zu entwickeln, wie beide Ansätze am Besten in der Forensoftware genutzt werden. Zum einen ist die Gewinnspielsoftware ein fast abgeschlossenes System, sodass ich nicht direkt Klassen für so ziemlich alles anlegen muss und sie ist kein kritisches System der Forensoftware. Zum anderen bietet die Gewinnspielsoftware aber eine große Menge an miteinander verbundenen Tabellen, womit ich auch testen konnte, wie man komplexe Anfragen in einer OOP-Umgebung umsetzt.


Das Problem Okay, eines der Probleme
Mein Ziel ist es, dass außerhalb der Klassen keine SQL-Abfragen mehr in den Dateien vorkommen. Alle Abfragen an die Datenbank werden aus den Klassen über Prepared Statements durchgeführt und geben Instanzen dieser Klasse zurück.

Ist dies bei einfachen Abfragen noch gut zu realiseren, z.B. mit einem einfachen
ausblenden Quelltext
1:
$quiz =& Quiz::FromID($id);					

, wird es bei SQL-Statements wie dem Folgenden schon kniffliger, das performant umzusetzen:
ausblenden SQL-Anweisung
1:
SELECT * FROM prizes, products WHERE quiz_prize_quiz_id = 20 AND quiz_prize_product_id = quiz_product_id ORDER BY quiz_product_id DESC					

Man könnte jetzt natürlich in der Prize- oder der Product-Klasse eine entsprechende Methode anlegen, welche dann das gwünschte Ergebnis liefert. Aber irgendwie "schmeckte es komisch", für jeden Spezialfall eine Methode anzulegen.

Wie also weiter machen? Meine erste Version war die folgende:
ausblenden Quelltext
1:
2:
3:
$prizes =& Prize::FromQuizId(20);
$productIds = ArrayHelper::Select($prizes, "GetProductID");
$products =& Product::FromIds(productIds);


Das ist natürlich zum einen nicht so gut lesbar (und die Sortierung ist noch nicht mal drin!), zum anderen verdoppelt es die Anzahl der nötigen SQL-Anfragen. Während das bei der Quizsoftware noch näherungsweise wurscht ist, wäre eine Verdopplung der SQL-Anfragen bei der viewtopic.php schon ziemlich übel gewesen.


Die (wahrscheinlich nicht endgültige) Lösung
Kurzzeitig habe ich mich mit der Verwendung eines fertigen ORM-Systems wie Doctrine auseinander gesetzt (dank an user profile iconKha für den Tipp), fand das dann aber doch irgendwie überdimensioniert und, für die Produktivität ein Desaster, IntelliSense für die Daten-Klassen war damit nicht möglich (zumindest, soweit ich gesucht habe, vielleicht gibt's da ja doch was).

Die aktuelle Lösung sieht nun so aus, dass ich eine eigene kleine Klasse geschrieben hat, mit der ich Abfragen an die Datenbank abwickeln kann. Man baut sich über diese Klasse das Query zusammen und nach Ausführung gibt die Klasse dann Instanzen der Datenklassen zurück. Hier mal das Beispiel von oben:

ausblenden Quelltext
1:
2:
3:
4:
5:
$rows = $query
        ->Select("Prize")->Where("Prize::QuizIDColumn", array("i", 20)) //der zweite Parameter (rechte Seite eines Vergleichs) ist ein Array, wird also als Parameter an das prepared statement gebunden
        ->Select("Product")->Where("Product::IDColumn", "Prize::ProductIDColumn")
        ->OrderBy("Product::IDColumn", "DESC")
        ->Execute();


Das resultierende Array sieht dann so aus, dass für jede Ergebniszeile, die MySQL ausspuckt, eine Zeile in $rows angelegt wird. Innerhalb dieser Zeile kann ich auf die dem Ergebnis entsprechenden Instanzen zugreifen: $rows[0]["Product"]->GetName(). Der Vorteil dieser Klasse ist, dass ich beliebige Queries an die Datenbank senden kann und typensicher wieder Instanzen der Datenklasse zurück bekomme.

Die Klasse ist natürlich ein "work in progress". Es gibt vieles, was sie noch nicht kann. Die Where-Statements sind aktuell auf Prüfung auf Gleichheit beschränkt, jede Klasse darf nur einmal vorkommen, usw. Aber sie ist bereits jetzt eine sehr große Hilfe.


Schlusswort
Die Quiz-Software hat sich als sinnvolles Testfeld für eine weitreichende Umstellung der Forensoftware erwiesen. Die Komplexität des Systems lässt es zu, Probleme, die auch später auftreten würden, jetzt schon zu erkennen, während die geringere Größe (= Anzahl der Klassen) es möglich macht, auch grundlegende Änderungen der Herangehensweise noch ohne allzu großen Aufwand umzusetzen.

Ich hoffe, dass mir die Quiz-Software in dieser Hinsicht noch gute Dienste leisten wird.

Grüße,
Christian
BeitragKommentar von elundril (Di 01.12.09 23:58)
Respekt, da hast du dir einiges vorgenommen! :zustimm:
BeitragKommentar von BenBE (Mi 02.12.09 00:11)
Auf jeden Fall netter Ansatz für den Bau von Statements. Da hat einer zu viel C# programmiert ;-)

Dieser Kommentar endet in gestern :mrgreen:
BeitragKommentar von jfheins (Sa 05.12.09 11:57)
Hab nen kleinen Bug gefunden ^^

Wenn man das Spiel ausgewählt hat (da wo man nochmal auf "spielen" klicken muss) steht oben:
"Teilnahme möglich vom 01.12.2009 00:00 Uhr bis 06.12.2009 23:55 Uhr (Endet in Gestern)"
BeitragKommentar von Christian S. (Sa 05.12.09 12:25)
Bugmledungen bitte weiterhin über die passenden Sparten erstellen! :-)

Ich habe den Bug (genau wie den Bug "Beginnt in gestern") unter Artenschutz gestellt. Bei "Beginnt in gestern" hatte ich sogar einen entsprechenden Hinweis hinterlassen, den gibt's jetzt bei dem Bug auch.