Programmiererhandbuch (Auswerte- und Exportmodul)

Entwicklungskonfiguration

Betriebssystem

SuSE Linux Professional, Kernel 2.4

Pseudo-XML-Parser

xml2html (keine Versionsnr. verfügbar, Dateigröße: 107185 Bytes)

Datenbanksystem

Mysql 3.23 Distrib 3.23.30-gamma, for suse-linux (i686)

Webserver-Software

Server version: Apache/1.3.14 (Unix) (SuSE/Linux)

Hardware

CPU: AMD K7-600, Festplatte: 3GB Linux-Partition auf 10 GB Seagate-IDE-HDD, RAM: 256 MB RAM, Grafikkarte: ATI Rage Fury Pro, Monitor: 19“ Iiyama Vision Master 450 bei 100Hz

Serverseitige Skriptsprache

TCL, Shell 8.3



Problemanalyse und Realisation

Die folgenden Abschnitte sind völlig unabhängig von der verwendeten Programmiersprache gehalten, es wird lediglich die konzeptionelle Umsetzung der jeweiligen Module geschildert. Die hier verwendeten Variablennamen stimmen nicht notwendigerweise mit den Variablenbezeichnern aus der konkreten Implementierung überein und dienen nur der Umgehung umständlicher Begriffsformulierungen.

Aus formalen Gründen erfolgt dieser Abschnitt noch vor der Darlegung des verwendeten Datenbankschemas. Die Kenntnis des Datenbankschemas ist allerdings Vorraussetzung, um diesen Abschnitt zu verstehen. Lesen Sie ggf. zunächst den Abschnitt über das Datenbankschema, bevor Sie hier weiterlesen.

Auswertemodul

Von der Einstiegsseite aus wird das Auswertemodul aufgerufen. Übergeben werden die formid des Fragebogens, das Passwort sowie ein Delta-Wert. Wenn der Delta-Wert leer ist, was immer der Fall ist, wenn das Auswertemodul von der Einstiegsseite aus aufgerufen wird, wird ein Formular angezeigt, in dem der Delta-Wert eingegeben werden kann. Nach Eingabe des Delta-Wertes wird wieder über die Einstiegsseite das Auswertemodul aufgerufen, diesmal allerdings mit dem eben eingegebenen Delta-Wert.

Da der Delta-Wert jetzt nicht mehr leer ist, kann der Auswerteprozeß beginnen. Zunächst wird überprüft, ob das für den Fragebogen übergebene Passwort korrekt ist. Ist dies nicht der Fall, erscheint eine Fehlermeldung.

Falls die Passwortprüfung erfolgreich ausfällt, wird die Plausibilitätsprüfung mit dem eingegebenen Delta-Wert durchgeführt (s. Abschnitt weiter unten).

Nachdem durch die Plausibilitätsprüfung ggf. diverse Tupel aus der results-Tabelle als ungültig markiert wurden, beginnt nun der eigentliche Auswertevorgang. Zunächst wird die Anzahl der Fragen für den gewählten Fragebogen ermittelt. Der Fragebogen wird immer anhand der formid identifiziert (Primärschlüssel in der formdata-Tabelle, Fremdschlüssel in der results-Tabelle). Wenn keine Fragen exisitieren, erscheint eine entsprechende Fehlermeldung.

Existieren Fragen, wird eine Liste onl der zu den jeweiligen Fragen gehörenden orderno-Werte erstellt. onl wird durchlaufen. Für jedes Element o aus onl wird der Typ der zugehörigen Frage ermittelt. Je nachdem, um welchen Fragetyp es sich handelt (Auswahlfrage, Blockfrage, Textfrage), wird eine auf diesen Fragetyp zugeschnittene Auswertefunktion aufgerufen, die bereits das Ergebnis der Auswertung als Pseudo-XML-Code zurückliefert. Diese Resultate der einzelnen Frageauswertungen werden während des Durchlaufens von onl akkumuliert und stellen zum Schluß das endgültige Auswertungsergebnis als Pseudo-XML-Code dar, welcher dann später durch einen Pseudo-XML-Parser bearbeitet wird, um das endgültige Erscheinungsbild des Resultats festzulegen.

Die folgenden Abschnitte erläutern kurz die allgemeine Vorgehensweise bei der Auswertung der einzelnen Fragetypen.

Auswertung von Auswahlfragen

Zunächst wird eine Liste stat_list ermittelt, welche die Bezeichner der Auswahloptionen für diese Frage, sowie die absoluten und die relativen Häufigkeiten, mit denen die jeweiligen Optionen gewählt wurden, enthält. stat_list wird dann in Pseudo-XML-Code transformiert, damit die Bezeichner der Auswahloptionen und die statistischen Häufigkeiten in einem bestimmten Format dargestellt werden können.

Zuletzt wird der Ausfüllstatus (s. Benutzerhandbuch) für die Frage ermittelt und als Pseudo-XML-Tag an das Resultat angehängt.

Auswertung von Blockfragen

Die Auswertung von Blockfragen gestaltet sich etwas komplizierter als die Auswertung von Auswahlfragen, da eine Blockfrage aus mehreren Unterfragen besteht, die wiederum Auswahlfragen sind und alle die gleiche Menge von Auswahloptionen besitzen.

Zunächst wird eine Liste options der Auswahloptionen, die für jede Unterfrage gilt, ermittelt. Auch wird eine Liste subq_ids ermittelt, welche die in der Tabelle results in der Spalte questionno gebrauchten Bezeichner für die Unterfragen enthält. Hat eine Blockfrage z.B. in der Tabelle formdata für das Attribut qstno den Wert '3', so werden alle in results vorhandenen Unterfragen von Frage '3' ermittelt. Da festgelegt wurde, daß das Feld questionno in results immer das Format 'qstN' hat (N entspricht QstNumber aus formdata), und die Ergebnisse zu Unterfragen von Blockfragen immer im Format 'qstN[suff]' hat (N sei die QstNumber der Blockfrage, [suff] sei ein Suffix, welches die Antworten zu den einzelnen Unterfragen identifiziert), also z.B. 'qst3-2' für die zweite Unterfrage von Frage '3', gehören alle Antworten, bei denen questionno das Format 'qstN[suff]' besitzt ([suff] nicht leer), zu der Blockfrage mit der QstNumber N.

Nun stellt sich das Problem, daß man aufgrund der Liste der questionno-Attribute eine Zuordnung zum Fragetext der Unterfrage treffen können muß, da man diesen ja in die Auswertung der jew. Unterfrage einbringen möchte. Die Unterfragen selbst sind im Feld InpSelBlockValues kodiert vorhanden, und zwar bildet eine Zeile, die durch \n abgeschlossen wird, eine Unterfrage. Das Problem wurde so gelöst, daß die Suffixe der Antworten zu den Unterfragen sich in results in einer lexikographischen Ordnung befinden müssen. Die Selektion der Antworten zu einer bestimmten Frage erfolgt dann nach lexikographisch aufsteigender Ordnung. So können die Texte der Unterfragen den questionno der Antworten in results zugeordnet werden.

Für die Auswertung wird nun subq_ids durchlaufen und jede Unterfrage (z.B. qst2-0, qst2-1, qst3-...) als Auswahlfrage behandelt. Für jede Unterfrage wird also eine Liste mit absoluten und relativen Häufigkeiten erstellt, ebenso werden die Texte der Unterfragen sowie der Ausfüllstatus für jede Frage in eigenen Listen festgehalten.

Zum Schluß besitzt man alle benötigten Informationen über alle Fragen. Diese werden dann mit Pseudo-XML-Tags aufbereitet.

Auswertung von Textfragen

Es werden aus der Datenbank alle Textantworten selektiert und mit Pseudo-XML-Tags aufbereitet. Ein Ausfüllstatus ergänzt das Ergebnis.

Exportmodul

Wie auch beim Auswertemodul (s.o.) erfolgt zunächst die Eingabe eines Delta-Wertes, dann wird das übergebene Passwort überprüft und anschließend eine Plausibilitätsprüfung durchgeführt, bei der bestimmte Datensätze für die Dauer des Exports als ungültig markiert werden.

Auch hier wird anschließend die Anzahl der Fragen ermittelt, wenn keine Fragen exisitieren, wird eine Fehlermeldung ausgegeben.

Nun wird eine interne Liste qst_meta_infos erstellt, die für jede Frage des Fragebogens bestimmte Meta-Daten speichert, z.B. um was für eine Frage es sich handelt, ob Mehrfachauswahl erlaubt ist, wie die Auswahloptionen heißen und wie der Fragetext lautet. Eine solche Struktur ist notwendig, da während des gesamten Exports bestimmte Informationen über die Fragen benötigt werden, denn hiervon hängt das Ausgabeformat ab. Bei Fragen mit Einfachauswahl z.B. wird der Code der gewählten Auswahloption exportiert, bei Fragen mit Mehrfachauswahl jedoch muß für jede Option eine eigene Frage generiert werden, die Werte „1“ und „0“ geben dann an, ob die jeweilige Option ausgewählt wurde oder nicht.

Ist qst_meta_infos erstellt, beginnt der eigentliche Exportvorgang. Anhand von qst_meta_infos wird eine erste Zeile exportiert, die die Spalteüberschriften enthält, bzw. die einzelnen Fragen. Jede Unterfrage bei Blockfragen ist eine eigene Frage, ebenso gibt es eine eigene Frage für jede Option bei Auswahl- und Blockfragen mit Mehrfachauswahl.

Es werden alle Antworten für den jew. Fragebogen selektiert, geordnet nach der SessionID. In einer Schleife werden für jede SessionID (=jede Sitzung bzw. jeden ausgefüllten Fragebogen) die gegebenen Antworten ermittelt. Da die Reihenfolge der Antworten in der Datenbank nicht der Reihenfolge der Fragen im Fragebogen entsprechen muß, müssen die Antworten zunächst intern in einer Liste answers gespeichert werden, die Zuordnung zu den Fragen, und damit die Einhaltung der Reihenfolge der Felder beim Export erfolgt später, beim Erstellen einer neuen Zeile.

Sind für eine SessionID alle Antworten gesammelt (es gibt keine weiteren Antworten für diese SessionID), so kann eine neue Zeile exportiert werden. Hierzu werden die qst_meta_infos verwendet. Die in dieser Liste enthaltenen Fragen werden durchlaufen. Für jede Frage wird die Antwort aus der Liste answers ermittelt. Da immer nach der Reihenfolge der Fragen in qst_meta_infos vorgegangen wird, wird die richtige Reihenfolge der Antwortfelder sichergestellt.

Nun können die Antworten für die nächste SessionID gesammelt werden, sind alle Antworten für die Sitzung vorhanden, wird wieder eine neue Zeile exportiert usw.

Wenn alle Sitzungen durchlaufen wurden, also alle ausgefüllten Fragebögen“exportiert wurden, erfolgt in einem letzten Schritt die Ausgabe einer Zeile, die eine Legende für die exportierten Daten jeder Spalte (=jeder Frage) beinhaltet.

Modul zur Plausibilitätsprüfung

Die Plausibilitätsprüfung findet für eine bestimmte formid aus der Tabelle results mit einem bestimmten Delta-Wert statt. Ziel ist es, bei Fragebögen (mit der gleichen formid), die innerhalb von delta Sekunden von der gleichen IP-Adresse abgesendet wurden, einen der Fragebögen“temporär als ungültig zu markieren, um damit der Verfälschung des Ergebnisses eines Exports oder einer Auswertung vorzubeugen.

Zu Beginn jeder Plausibilitätsprüfung werden alle in der results-Tabelle als ungültig markierten Datensätze wieder als gültig markiert. Ein Fragebogen wird dadurch als ungültig gekennzeichnet, daß in results der formid ein bestimmtes Präfix, daß aufgrund einer Limitation des Datenbankschemas nur aus einem Zeichen, in diesem Falle '-', bestehen darf, vorangestellt wird. Bei der Ermittlung der Antworten werden diese „markierten“ Datensätze daher nicht berücksichtigt. Ist der Auswerte- bzw. Exportvorgang abgeschlossen, sollte die Markierung wieder rückgängig gemacht werden, das Auswerte- und das Exportmodul greifen hierfür auf eine Routine aus dem Modul zur Plausibilitätsprüfung zurück.

Die eigentliche Plausibilitätsprüfung erfolgt nach folgendem Schema:

In einem ersten Schritt wird eine Menge session_ids aller SessionIDs (also der eine Sitzung identifizierenden Zeitstempel) angelegt, die dem jew. Fragebogen mit der jew. formid zugeorndet sind. Session_ids habe die Kardinalität N.

Nun wird in (1+N² div 2) Durchläufen einer Vergleichsschleife jede SessionID mit allen anderen SessionIDs verglichen. In jedem Vergleich zweier SessionIDs s1 und s2 wird die zeitliche Differenz zwischen den beiden Zeitstempeln verglichen. Ist die Zeitspanne kleiner als delta Sekunden und sind die IP-Adressen ip1 und ip2, die s1 und s2 zugeordnet sind, gleich, so wird die formid in results überall als ungültig markiert (durch Voranstellung eines '-'), wo die SessionID s1 ist (natürlich nur für den Fragebogen formid, da es ja sein kann, daß der Ausfüller innerhalb von delta Sekunden zwei verschiedene Fragebögen ausgefüllt hat).

Zur technischen Realisation der Plausibilitätsprüfung muß hier noch gesagt werden, daß die Wahl zwischen zwei Alternativen bestand:

  1. (temporäres) Markieren bestimmter Fragebögen“in der Ergebnis-Relation als ungültig

  2. Erstellen einer Liste aller nicht zu berücksichtigenden Session-IDs, beim Ermitteln der Antworten wird dann in einer SQL-WHERE-Klausel unterdrückt, daß Antworten mit diesen Session-IDs selektiert werden.

Es wurde sich für den ersten Ansatz entschieden, da der zweite Ansatz den gravierenden Nachteil hat, daß sowohl im Export- als auch im Auswertemodul bei Selektion der Antworten zu einem Fragebogen unter Umständen sehr große SQL-WHERE-Klauseln entstehen können (falls sehr viele Fragebögen je nach Delta-Wert als ungültig betrachtet werden sollen). Auch müßte in einer u.U. Arbeitsspeicher-raubenden internen Struktur festgehalten werden, welche Session-IDs als ungültig betrachtet werden sollen. Diese Liste könnte so umfangreich werden, daß - auch in Hinblick auf die Auswertung der SQL-Anweisung durch das Datenbanksystem - eine sichere Programmausführung nicht möglich wäre.

Der erste Ansatz dagegen benötigt während des Auswerte- oder Exportvorganges keinen zusätzlichen Arbeitsspeicher. Den Nachteil, daß die FORMIDs von ungültigen ausgefüllten Fragebögen in der Ergebnisrelation temporär verändert werden müssen, um die entsprechenden Antworten als ungültig zu markieren, muß man in Kauf nehmen. Außerdem kann dieser Vorgang unkompliziert durch eine mitgelieferte Funktion, die vom Auswerte- und Exortmodul verwendet wird, wieder rückgängig gemacht werden.