Die
Klassenbibliothek ist eine Entwicklung, die für den Umgang mit dem allegro-Konzept
drei Ebenen eröffnet:
- Entwicklungsarbeit: ein
plattformunabhängiges Kernsystem in objektorientierter
Methodik.
Hier könnte man z.B. neue Satz- und Indexstrukturen und -funktionen in C++ entwickeln oder diese erweitern und verbessern.
- Anwendungsprogrammierung:
ein
Entwicklungssystem
(Programmierschnittstelle), aufbauend auf dem Kernsystem, für
die
Gestaltung neuer Anwendungen auf der Basis von allegro-Datenbanken. Beispiele: a99/alcarta, acon
- Anwendung: mehr Komfort
durch
Einbindung in graphische Benutzeroberflächen nach
gängigen Standards. Beispiele: Web-Schnittstellen mit PHP, Perl
o.a., FLEX-Funktionspakete für a99/alcarta, RIA-Programme wie z.B.
a30 und a35 .
Mit FLEX wird die Klassenbibliothek auf höherer Ebene indirekt genutzt.
Das Kernsystem
in C++ enthält nur die folgenden
fünf Klassen (= Objektbeschreibungen):
- KONFIG
- Konfiguration. Nimmt praktisch den Inhalt
einer Konfigurationsdatei (.cfg) auf.
Diese Klasse enthält "Methoden" (auch "Memberfunktionen"
genannt),
um Datenfelder zu überprüfen, d.h. anhand der
Kategorieliste
ihre formale Korrektheit festzustellen: ist es eine zulässige
Kategorie, enthält sie unerlaubte Teilfelder?, usw.
- RECORD [Hier ist als Beispiel der Quelltext record.hpp zu sehen]
- Datensatz. Dient zur Darstellung von
Sätzen aus der Datenbank im Arbeitsspeicher.
Wichtige Methoden sind das Ändern von Feldern und das Einordnen neuer Datenfelder in den
Datensatz, auch das Löschen von Kategorien und
hierarchischen Untersätzen. Mit einem Aufruf Satz->Ins(field) ordnet man z.B. eine Zeichenfolge field in einen RECORD-Objekt Satz
ein. (Die Zeichenfolge muß mit einer Kategorienummer
beginnen, z.B. #20. Ist dieses Feld schon im Satz vorhanden, wird es
überschrieben.)
- EXET
- Export-Set.
Nimmt eine Export-Parameterdatei auf, die eine genaue Vorschrift
für das Exportieren von Datensätzen enthält, formuliert
in der sog. Exportsprache. Alle Outputs und auch die Indexeinträge werden mit dieser Sprache parametriert.
Die wichtigste Methode ist die Funktion Exp(),
die den Export
eines Satzes vorschriftsgemäß ausführt. Man übergibt also dieser
Funktion mit dem Aufruf Exp(Satz)
ein
Objekt der Klasse RECORD, um diesen Datensatz exportieren zu lassen.
- INDEX
- Indexdatei. Diese Klasse erweitert die
EXET-Klasse. Ein Objekt dieser Klasse
stellt den Index einer Datenbank dar.
Es gibt eine Anzahl Methoden (Funktionen), die den Zugriff auf die
Register ermöglichen, aber auch die Berechnung aller
Schlüssel eines Datensatzes sowie das Ausführen von
einfachen und trunkierten Suchbefehlen.
- Auf einer tieferen Ebene liegen
die elementaren Funktionen für den Umgang mit der Indexdatei
und den Schlüsseln. Diese Funktionen braucht der Programmierer
nicht zu kennen, sie sind auf der Klassenebene
unsichtbar. Die Quellen liegen vor in einem Paket aindex, das zu einer Library kompiliert wird.
- ABASE
- allegro-Datenbank.
Diese Klasse erweitert die INDEX-Klasse.
Hier gibt es Methoden, um Sätze zu laden, zu löschen, und
bearbeitete
Sätze zurückzuspeichern, einschließlich
aller
Indexveränderungen:
Mit dem einfachen Befehl Put(Satz)
wird das RECORD-Objekt Satz gespeichert, mit Del(satznummer) wird er gelöscht.
-
Diese Klassen
bilden zusammen ein "Application Programmer Interface" (API)
für die Sprache C++. Die Klassen sind
genauestens
beschrieben in Dateien mit den Namen KONFIG.HPP, RECORD.HPP usw. Der
Programmierer kann daraus alle Strukturen und Methoden ersehen, die in
einem C++-Programm verwendet werden
können. Diese
Dateien sind also zugleich die API-Dokumentation. Da
diese Klassen keine interaktiven Teile enthalten (d.h. keine Tastatur-
und Bildschirmprozeduren), sind sie mit beliebigen Klassenbibliotheken
für GUI-Gestaltungen, aber vor allem für
Client/Server-Anwendungen, kombinierbar. Das allegro-Datenbanksystem
wird damit auf Programmierebene zu einem absolut offenen System.
Hinsichtlich
der Datenstrukturen und der Funktionen auf Satz- und Indexebene sind
die Klassen kompatibel mit den älteren DOS-Programmen. Daher
können
auch alte Datenbanken ohne irgendeine Umwandlung von neuen Programmen
benutzt und verarbeitet werden.
Beispiel
für ein objektorientiertes Programm
Es folgt nun ein
kleines
Musterprogramm auf Basis der Klassenbibliothek, welches nur
zeigen soll, wie die
genannten
Klassen eingesetzt werden.
Das Programm test.cpp macht folgendes:
- es sucht über Register 3 alle
Datensätze,
die ein mit "biochem" beginnendes Stichwort enthalten,
- ordnet ein neues Feld #30a mit Inhalt "BTC" in diese
Sätze ein,
- exportiert sie mittels einer Parameterdatei
D-SHOW.APR auf
den Bildschirm,
- und speichert sie wieder zurück (wobei die
Indexbearbeitung automatisch erfolgt).
Empfehlung:
Zum praktischen Ausprobieren wird test.cpp nicht
empfohlen. Dazu gibt es ein etwas größeres, das flexibler
ist und damit auch praktisch nützlich sein kann: osdp.cpp. Man findet die Quelldatei im SVN. Es enthält einige Kommentare, markiert mit ++++, die den
individuellen Ausbau erleichtern sollen. So kommt man am schnellsten zu einem eigenen Konsolprogramm mit Zugriff auf allegro-Datenbanken.
Um die Lesbarkeit
zu
verbessern, sind hier Kommentare kursiv gesetzt, der eigentliche
Programmtext fett.
Das Programm ist in
der Sprache C++ geschrieben.
Das Symbol // leitet Kommentare ein, d.h. der Rest der Zeile wird vom
Compiler ignoriert.
// Musterprogramm test.cpp
// Allgemeine Vorbereitungen: // Klassenbeschreibungen:
// die Datei abase.hpp enthält alle Beschreibungen
#include "abase.hpp"
// Hier beginnt das Programm:
int Amain() { if(!uifRead('e')) A_EXIT(10); // Lies die Datei uifeger, Abbruch falls Fehler
// Zuerst wird $a.CFG geladen, und zwar vom Verzeichnis c:\allegro\demo2 : // (Wenn $a.cfg nicht existiert, wird a.cfg gesucht. Dies geht auf V13 zurück) // (eine Konfiguration wird immer gebraucht)
KONFIG *kfg=new KONFIG("a","c:\\allegro\\demo2\\");
if(*Aerror) { printf("%s\n",Aerror); A_EXIT(10); } // Fehler in a.cfg?
// Fehlermeldungen solcher Funktionen stehen immer in der Variablen Aerror // if(*Aerror) bedeutet: steht etwas in Aerror? Wenn ja, wird die // nachfolgende Klammer ausgeführt // A_EXIT(10) heisst: Programm wird mit Fehlercode 10 beendet
// Im folgenden wird jeweils die Konfiguration kfg benutzt, um Objekte // zu erzeugen, d.h. kfg ist ein Objekt der Klasse KONFIG
// Exportparameter d-show.apr werden geladen in ein Objekt der Klasse EXET, // welches den Namen Expo bekommt:
EXET *Expo=new EXET("d-show",kfg,0, "c:\\allegro\\demo2\\");
if(*Aerror) { printf("Aerror=%s\n",Aerror); A_EXIT(10); }
// zum Ausgeben soll die Funktion putchar() dienen, d.h. Ausgabe auf Bildschirm;
// deshalb wird die Adresse dieser Funktion an das Objekt Expo uebergeben:
Expo->Outfunc(putchar);
// Ein Objekt RECORD (Datensatz) wird geschaffen, es beruht gleichfalls auf kfg:
RECORD *Satz=new RECORD(kfg);
// Die Datenbank cat auf c:\allegro\demo2 wird geoeffnet: // (d.h. ein Objekt der Klasse ABASE wird angelegt) // Dafür wird kfg verwendet, d.h. man koennte auch eine andere Version der CFG nehmen
ABASE *Bank=new ABASE("c:\\allegro\\demo2\\","cat", kfg,1);
// und wieder: wenn in Aerror was steht, hat es nicht geklappt
if(*Aerror) { printf("Fehler beim Öffnen der Datenbank: %s\n",Aerror); A_EXIT(10); }
// Jetzt wird mit den erstellten Objekten einiges angestellt. // ein paar Variablen werden gebraucht:
CHAR txt[256]; // soll den Text einer Kurztitelzeile aufnehmen long results[10000]; // Ergebnismenge: bis zu 10000 Satznummern long rs; // Anzahl der Ergebnisse
// Im Register 3 wird nach Eintraegen gesucht, die mit "biochem" anfangen: // Die Satznummern werden in results eingetragen:
rs=Bank->ADXget(3,"biochem",results,1); // Die Ziffer 1 schaltet den Modus "trunkierte Suche" ein
// Der Wert rs ist 0, wenn nichts gefunden wurde, -1, wenn ein Fehler auftrat // (ein Fehlerhinweis steht dann in Aerror)
if(rs==0) { printf("Nichts gefunden\n"); return 0; }
if(rs<0) { printf("Fehler: %s\n",Aerror); EXIT(10); }
// Am Bildschirm wird angezeigt, wieviele Ergebnisse (rs) es waren:
cout << endl << "Ergebnisse : " << rs << endl;
// "endl" heisst "end of line" und erzeugt einen Zeilenvorschub // Alle Saetze der Ergebnismenge werden jetzt als Kurztitel (entnommen // aus der .STL-Datei) angezeigt, dann geladen und mit dem // Exportobjekt Expo exportiert (gleichfalls auf den Bildschirm)
long i=0; // Variable fuer die laufende Nummer while(i<rs) { cout << results[i] ; // Interne Satznummer anzeigen
// Kurztitelzeile holen, in txt zwischenspeichern:
k=Bank->STLget(results[i],txt);
// und dann anzeigen: (die C-Funktion printf() wird benutzt)
printf(", Kurztitel: %s\n",txt);
// Datensatz in das Objekt Satz holen:
Bank->Get(results[i++],Satz,0);
// Kategorie #30a mit Inhalt BTC in den Satz einordnen:
Satz->Ins("#30aBTC");
// und dann den Satz mittels Expo exportieren: // (ein Objekt der Klasse EXET hat eine "Memberfunktion" Exp(), die den // eigentlichen Export ausfuehrt, d.h. die Parameter abarbeitet)
Expo->Exp(Satz); // Alternativ, wenn V14-Aufloesungen noetig sind: // Bank->ExpV14(Satz,Expo);
// Datensatz speichern (Indexbearbeitung erfolgt dabei automatisch) Bank->Put(Satz);
if(*Aerror) { printf("Speicherung gescheitert: %s\n",Aerror); A_EXIT(10); }
} // Ende der while()-Schleife
return 1; // zurueck zu main(), Beendigung des Programms
}
|