SPC-AdiProg - Daten bunkern mit Modula-2

Die Datenbank-Software ADIMENS ist für die verschiedensten Rechnersysteme erhältlich. Zur Entwicklung von Anwenderprogrammen gibt es zusätzlich eine Programmierschnittstelle namens AdiProg, mit der die Datenbankfunktionen in selbstprogrammierte Applikationen eingebunden werden können. Nach ST-Versionen für Mark-Williams-C und Turbo-C gibt es das System jetzt auch passend für Modula-Programmierer mit dem SPC-System von Advanced Applications Viczena (AAV).

Die ADIMENS-Implementierung für den ATARI ST ist schon eine Weile auf dem Markt und wurde in ST-Computer 1/87 vorgestellt. Einen Test der PROG-Schnittstelle für C finden Sie in Heft 11/88. ADIMENS ist eine relationale Datenbank, die Daten werden also in Tabellen-form gespeichert, und einzelne Felder können als Schlüssel z.B. zum Sortieren verwendet werden. Zwischen mehreren Tabellen bzw. Dateien können Verbindungen über Felder existieren, in zwei oder mehr Dateien identisch Vorkommen. Sind solche Verbindungen, die Relationen über mehrere Dateien, möglich, haben wir eine relationale Datenbank. Eine kleine Serie zur Programmierung solcher Datenbanken finden Sie in ST-Computer 4-6/88, allerdings dort auf dBASE Kompatible bezogen.

Dieser Test soll sich nur mit der AAV-Implementierung beschäftigen und nicht in die Datenbanktheorie einsteigen. Am Anfang der Arbeit mit einem Software-Produkt steht immer die Installation. Und die gestaltet sich bei SPC-AdiProg einfach.

SPC-Modula wird durch eine - in der aktuellen Version grafische - Shell gesteuert. in der Suchpfade für das gesamte System verwaltet werden. Die Installation beschränkt sich also auf das Kopieren sämtlicher Dateien von der doppelseitigen Lieferdiskette und Setzen der Suchpfade mit dem SPC-Utility PATHS. Weitere Schritte sind nicht notwendig.

Zur Definition einer Datenbank wird das Originalprogramm INIT Version 2.3 von ADIMENS mitgeliefert. Es erlaubt auf komfortable Weise GEM-gestützt die Erstellung einer Datenbank mit Feld- und Maskendefinitionen. Auch Verzweigungen zwischen Dateien können ediert werden. Das zweite Originalprogramm, REORG (Version 2.23) muß von Zeit zu Zeit auf die Datenbank angesetzt werden, um auftretende Löcher in der Indexdatei zu entfernen.

Die Modulsammlung ist aufgeteilt in die eigentliche ADl-Schnittstelle samt Hilfsmodulen. einen Listen- und einen Maskengenerator sowie die Wordplus-Schnittstelle WPProg. Zur Vereinfachung der Programmierung gibt es zusätzlich das Modul EasyPROG.

Die ADI-Schnittstelle

Für den Programmierer laufen die eigentlichen Aufrufe der AdiProg-Funktionen über das Modul AdiInterface. Hier finden sich die Routinen z.B. zum Öffnen einer Datenbank oder zum Einlesen eines Datensatzes. Diese Funktionen sind der Kern des Datenbanksystems und erlauben für den Programmierer den Zugriff auf die Datenbank, die darin enthaltenen Dateien und die eigentlichen Datensätze und deren Felder. Mit Find, Look und Next kann der Dateizeiger entsprechend einem Suchmuster positioniert werden. Die Anzahl der Kernroutinen ist gering und bei allen AdiProg-Impiementierungen identisch.

Von ADIMENS ist inzwischen eine netzwerkfähige Version erhältlich, die mit eLAN, Bionet und Rhonet arbeitet. AAV plant für die Netzwerkunterstützung wohl eine eigene Lösung. Diese Situation ist nicht weiter verwunderlich, da auch die Anbieter von Netzwerken momentan Software-Unterstützung zunächst für C-Systeme anbieten.

Zur Arbeit mit den eingelesenen Daten dient AdiUtilities. Die bereitgestellten Funktionen konvertieren z.B. Daten von Zeichenketten in die ADI-interne Darstellung und umgekehrt und bieten einige Routinen zur Manipulation des Datensatz-Puffers. Auch finden sich hier Routinen zur Verarbeitung der Mengen von Adimens (512 Elemente, 64 Bytes) und die Funktionen zur Datumsdarstellung, wobei vier landesspezifische Parametersätze implementiert sind.

Bild 1: Die Bildschirmdarstellung mit dem Listengenerator

Ebenfalls in AdiUtilities sind einige Routinen für die interne Speicherverwaltung des Datenbankkerns vorhanden. Von ihrer Benutzung wird dringend abgeraten, vielleicht hätten sie in ein extra Modul gehört.

Der gesamte Kern von ADIMENS ist in C programmiert und liegt als ADI.PRG vor. Bei der Initialisierung der ADI-Schnittstelle aus dem Modula-Programm heraus wird dieser cirka 65 kByte grobe Kern von Disk oder Platte während der Laufzeit nachgeladen und dabei einmalig der Zugriffspfad in einer Environment-Variablen vermerkt. Zwei weitere interne Module übernehmen das Laden und Ermitteln der C-Routinen automatisch. Da der direkte Start von ADI.PRG vom Desktop keinen Sinn macht, wäre hier vielleicht ein Umbenennen, z.B. ADLIMG, wünschenswert.

Zur Abrundung der eigentlichen ADI-Schnittstelle sind im Modul Utilities weitere Hilfsroutinen vorhanden. Datensätze können in Strings für eine Listenausgabe oder in 24*79 Zeichen Bildschirm-Puffer konvertiert werden. Auch sind hier die Feldnamen abfragbar. Zur Verwendung der Struktur der Datenbank kann auf das nächste Schlüsselfeld geschaltet und die in INIT definierten Verzweigungen zwischen Dateien benutzt werden.

Dieser Kern der AdiProg-Routinen enthält gegenüber der C-Version nicht die Routinen, die beispielsweise das Datei-Handling, Directory-Operationen oder den Umgang mit Druckern bereitstellen. Dies ist auch nicht nötig, da solche Funktionen schon zum Standardumfang von SPC-Modula gehören.

Listengenerator

In der C-Version von AdiProg sind GEM-Routinen vorhanden, die eine Programmierung einer Benutzeroberfläche ähnlich dem original Abfrageprogramm EXEC ermöglichen (in der Library GEM-PROG). AAV hat diesen dort sehr umfangreichen Teil weggelassen und stattdessen zwei Module implementiert, die basierend auf dem SPC-Fenstersystem SSWiS Bildschirmdarstellungen unterstützen.

Der Listengenerator verwaltet die Ausgabe von Listen in einem Textfenster. Die Bestandteile der Listen sind natürlich die aus der Datenbank gewonnenen Felder.

Das Modul ListLib kann Listenfenster öffnen und verwalten. Eine Redraw-Routine erhält zum Neuzeichnen des Fensterinhalts eine Anfangs- und Endzeile und kann die Daten mit der speziellen Write-Field-Routine ausgeben.

Der Clou ist, daß der Benutzer in diesen Fenstern einzelne Zeilen und Felder per Maus selektieren kann. Welche Listenteile ausgewählt wurden, kann mit Abfrageroutinen einfach ermittelt werden. Was mit diesen Feldern geschieht, ist dann natürlich Sache der Applikation. Entsprechend der Konzeption von SSWiS erhält jedes Listenfenster eine eigene Menüzeile, die wiederum mit Funktionen aus der ListLib erstellt wird.

Bild 1 zeigt drei mit dem Listengenerator programmierte Listenfenster, die Daten einer Beispieldatenbank enthalten. Das oberste Fenster enthält die Namen der Dateien in einer horizontalen Liste, wobei das Anklicken einer Datei ein neues Listenfenster für den Inhalt der Datei öffnet. Im Hintergrund sehen Sie zwei solche Fenster.

Maskengenerator

Wie oben genannt, befindet sich in dem Modul Utilities eine Routine, die einen Datensatz nach der Maskendefinition in ein Feld aus Zeichenketten umwandeln kann. Jedoch geht diese Routine von einem herkömmlichen Textbildschirm aus. AAV hat einen Maskengenerator implementiert, der mit dem Fenstersystem SSWiS zusammenarbeitet und erheblich mehr GEM-Elemente erlaubt (Bild 2).

Bild 2: Eine Bildschirmmaske in einem SSWiS-Fenster

Zunächst müssen dazu die mit INIT erstellten Masken mit dem Modul Read-Decl eingelesen und danach mit Mask-Heap Speicherplatz für die Masken angefordert werden. Zusätzlich wird man die Maskenbeschreibung aus ReadDecl umbauen müssen, da der Maskengenerator andere Datenstrukturen verwendet. Hier wäre vielleicht ein kleines Set an Konvertierungsroutinen angebracht.

Das Programm baut dann eine Maske durch mehrfachen Aufruf von DefElem auf. Für jeden Maskenbestandteil muß eine Beschreibung übergeben werden, in der z.B. die Bildschirmposition und der Text von Buttons steht. Mögliche Elementtypen sind Title für Texte, Button für GEM-Knöpfe, Content für die von GEM-Dialogen her bekannten edierbaren Felder und schließlich UserDef für selbstprogrammierte Objekttypen.

Für alle Elemente lassen sich Eigenschaften setzen, die auch vom GEM-Dialog-manager her bekannt sind. Teile können wählbar oder z.B. ausgeschaltet sein, Texte können formatiert werden, und Buttons sind mit verschieden starker Umrandung darstellbar. Bei edierbaren Feldern wird ein Maskenstring festgelegt, der bestimmt, welche Zeichen an welcher Stelle zur Eingabe erlaubt sind.

Über die Einführung von programmierbaren Objekten ist es z.B. auch möglich, Grafiken darzustellen. Im Bild 3 (aus einem Beispielprogramm) ist dies natürlich eine Spielerei, die Darstellung eines gescannten Formulars im Hintergrund macht eine Maske allerdings spürbar anwenderfreundlicher.

Eine Reihe von Service-Funktionen erlaubt das Verändern der Attribute von Elementen, so z.B. das Setzen von Strings oder das Einfügen von einzelnen Zeichen in ein edierbares Maskenelement.

Um die Maske nun aktiv zu machen, wird ein SSWiS-Fenster eröffnet und darin die Maske dargestellt. Benutzereingaben werden dann mit der Routine SSWiS.PollEvents abgefragt und automatisch vom Fenstersystem an den für jede Maske zu programmierenden Eventhandler weitergeleitet. Dieser erhält dann z.B. die Mitteilung, daß eine Cursor-Taste gedrückt wurde, und muß dann mit der Routine MoveCursor des Maskenmanagers reagieren. Auch die Redraw-Events werden von SSWiS geliefert und können mit weiteren Service-Routinen in Funktionen von MaskManager befriedigt werden.

Der MaskManager ist also eine Sammlung von Funktionen, die die Maskenprogrammierung unterstützen. Vergleicht man die Masken mit den Standard-GEM-Formularen, so liegen seine Fähigkeiten etwa auf der Ebene des Form-Managers von GEM. Zur Verarbeitung von Benutzereingaben muß der Programmierer die SSWiS-Ebene benutzen und wird dabei sinnvoll von einigen Service-Routinen unterstützt. Für eine konkrete Anwendung wird man sich noch einige kleinere Funktionen hinzuprogrammieren müssen oder Prozedurrahmen aus den mitgelieferten Beispielprogrammen übernehmen.

Allerdings bietet das Angebot aus MaskManager natürlich auch eine große Flexibilität: Während des Ausfüllens einer Maske könnten Felder aus der Datenbank nachgeladen werden. Bei einem Rechnungsformular könnte nach dem Ausfüllen des Namensfelds in der Datenbank nachgeschaut werden, ob die Adresse vielleicht schon vollständig in einer Kundendatei vorliegt. Wäre dies nicht der Fall, müßte der Benutzer weiter ausfüllen. Das Programm könnte aber sofort dann, wenn alle Adressenfelder ausgefüllt sind, die Kundendatei erweitern. Läge die Adresse vor. könnten die entsprechenden Felder schon während der Datenerfassung in der Maske ergänzt werden.

Easy-PROG

EasyPROG ist eine Erweiterung bzw. Vereinfachung der ADI -Schnittstelle. Die dortigen Routinen arbeiten mit Puffern, die im Speicher dynamisch angelegt werden müssen. Zum Bearbeiten eines Datenfeldes muß das Programm dessen Adresse im Puffer mit diversen Funktionen ermitteln. Weiterhin sind einige Parameter - z.B. die Dateinummer - bei jedem Funktionsaufruf zu übergeben, obwohl sie in einer realen Anwendung nicht ständig wechseln werden.

EasyPROG liegt nun in der Modulhierarchie über der ADI-Schnittstelle und bietet deren Dienste in komfortablerer Weise an. Das zweite der genannten Probleme umgeht EasyPROG dadurch, daß nur einmal z.B. die Datei per ln() auszuwählen ist, die dann bei jedem Funktionsaufruf automatisch an die ADI-Schnittstelle weitergeleitet wird.

Um das umständliche Hantieren mit dem Puffer zu vermeiden, gibt es die Connect...-Routinen. Mit ihnen kann ein Feld an eine Modula-Variable gebunden werden. Nach ConnectInt-(anzahl,1) gilt das erste Feld eines Datensatzes in der aktuellen Datei als an die INTEGER-Variable anzahl gebunden. Beim Einlesen eines Feldes mit Access kopiert EasyPROG automatisch den Pufferinhalt in die Variable, mit der dann weitergearbeitet werden kann.

Listing 1 zeigt einen Programmausschnitt, in dem mit EasyPROG alle Datenfelder der Datenbank adr in der Datei 1 ausgegeben werden. Vorteil ist. daß das Speichermanagement für den Puffer entfällt und zudem das Anwendungsprogramm weniger mit Zeigervariablen umgehen muß. Insgesamt also ein Hilfsmodul, das die Arbeit deutlich vereinfacht und schließlich auch sicherer macht.

Bild 3: Eine Maske mit Grafik

...
VAR name, vorname, strasse,
    ort:ARRAY[0..22] OF CHAR; 
    i, nummer, plz : INTEGER;
...

    IF InitBase('E:\spc\user\','adr') THEN 
        ConnectText(name,1);
        ConnactTaxt(vorname,2);
        ConnectText(strasse, 3);
        ConnectInt(nummer 4);
        ConnectInt(plz,5);
        ConnectText(ort,6); 
        In(1)
        Reset;
        UseKey(1);
        SetTextKey('?');
        IF Find() THEN 
            REPEAT 
                Access;
                WriteString(nama)   WriteLn
                WriteString(vorname)    WriteLn
                WriteString(strasse); WriteLn; 
                WriteInt(nummer,5); WriteLn;
                WriteInt(plz,5);    WriteLn;
                WriteString(ort);   WriteLn;
            UNTIL -Lock()
        END;
    ExitBase;

Listing 1

WPProg

Bild 4: Eine Vorlage für Serienbriefe für WPMail

Um die Verbindung zwischen Datenbank und Textverarbeitung zu ermöglichen, stellt SPC-AdiProg eine Schnittstelle zu Wordplus in dem Modul WPProg bereit. Es läßt sich übrigens auch unabhängig von den ADIMENS-Routinen benutzen. Vielleicht sollte AAV dieses Modul auch einzeln anbieten.

Sechs Module bieten auf verschiedenen Ebenen ihre Dienste an. WPCode enthält die diversen Typ-Definitionen - z.B. für Formatzeilen - und Grundfunktionen, um zwischen diesen Typen und der Wordplus-Darstellung in ASCII-Zeilen zu wandeln.

WPParam stellt Routinen zum Setzen der Parameter eines Wordplus-Dokuments bereit, also Dinge wie Seitenlänge, Fußnotenlinie oder die Lineallänge. Die Routinen erhalten als Parameter einen zu ändernden Record vom Typ WPFormat, in dem das Dokumentenformat gehalten wird, und überprüfen die Korrektheit der neuen Werte.

WPPrint erlaubt die Verarbeitung von Wordplus-Dokumenten auf dem Massenspeicher. Hier finden sich die Routinen zum Lesen und Schreiben einzelner Zeilen aus und in eine Datei. Es können bei der Ausgabe alle Wordplus-Bestandteile wie Seitenumbrüche oder Fußnoten erzeugt werden. Auch die verschiedenen Schriftarten lassen sich verwenden. Für das Programm werden alle Textzeilen als ARRAY OF CHAR behandelt; die verschiedenen Codes - z.B. für Fettschrift - hängen entsprechende Funktionen an. Übrigens lassen sich auch Bilder verarbeiten.

Die verschiedenen Formatierungsroutinen für Textzeilen sind in WPFStr zusammengefaßt. Hier werden die Zeichenfelder z.B. links- oder rechtsbündig formatiert und in einem weiteren String zurückgeliefert. Das Formatieren berücksichtigt natürlich die Wordplus-Steuerzeichen.

WPConv stellt Konvertierungsroutinen zwischen Wordplus-Dokumenten auf Disk bereit. Hier kann z.B. zwischen ASCII- und Wordplus oder zwischen der Wordplus-Version 2 und 3 gewandelt werden. Auch kann WPConv z.B. automatisch ein Inhaltsverzeichnis erstellen.

Das letzte Modul MPMail erlaubt es schließlich, Serienbriefe zu erstellen. Hier wird automatisch ein Wordplus-Dokument, das Platzhalter enthält (Beispiel in Bild 4), mit einer Ersetzungstabelle gemischt und schließlich der neue Text auf Disk geschrieben. Bei der Arbeit mit AdiProg extrahiert man dann die Ersetzungstexte natürlich jeweils aus der Datenbank.

00? - Lizenz zum Verkaufen

Als Vertreiber von mit AdiProg hergestellter Software hat man aufgrund der Lizenzbedingungen bestimmte Verpflichtungen gegenüber dem eigentlichen Hersteller ADI Software. Verlangt werden Belegexemplare, ein Hinweis auf ADI Software im Programm, und schließlich darf das Produkt nicht mit AdiProg oder ADIMENS konkurrieren. Es sind zwei Vertriebsformen gestattet, und zwar entweder ohne INIT und REORG, aber mit dem Hinweis, daß diese nachträglich erworben werden müssen, oder als Komplettpaket mit einer anteilig berechneten Lizenz durch ADI Software.

Die Höhe der Lizenz muß jeweils individuell vereinbart werden, von einem Festpreis, wie bei früheren AdiProg-Versionen, ist ADI Software inzwischen abgerückt.

Handbuch

Das Handbuch umfaßt fast 320 Seiten und wird in einem Ringordner geliefert. Der Update-Service von Advanced Applications für das Modula-System arbeitet sehr konsequent auch mit Handbuchergänzungen; die Ringordner-Lösung hat sich dabei sehr gut bewährt.

Das Manual besteht aus vier Teilen. Im ersten wird die Programmierung mit der Schnittstelle und den zusätzlichen Modulen in einer Art Tutorial sehr übersichtlich erläutert. Die abgedruckten Programmbeispiele geben einen Rahmen für wiederkehrende Aufgaben vor.

Der Referenzteil geht die einzelnen Module Funktion für Funktion durch. Am Seitenrand ist jeweils der Prozedurname aufgeführt, so daß ein Nachschlagen erleichtert wird. Die verwendeten, oftmals recht umfangreichen Datentypen finden sich in der Nähe der beschriebenen Funktion, so daß großes Blättern erspart bleibt. Erfreulich auch ein System von Querverweisen auf mit der dargestellten zusammenhängende Funktionen.

Die Beschreibung der Programme INIT und REORG wurde direkt aus dem Adi-Prog-C-Handbuch übernommen. Vielleicht hätten auch noch die einleitenden Kapitel über das Konzept der ADI-Datenbank aus dem Original übernommen werden sollen. Die bei Modula übliche Listung aller Definitionsmodule bildet den Abschluß des Handbuchs, das zwar noch ein Register verdient hätte, aber insgesamt gelungen ist.

Als Ergänzung zum Handbuch sind auch die mitgelieferten Beispielprogramme zu sehen. Ein Programm, ExecNeu, zeigt in der Praxis, wie man mit einer Datenbank beliebigen Formats umgeht. In einer konkreten Anwendung wird man wahrscheinlich Teile daraus in sein eigenes Programm übernehmen.

Fazit

SPC-AdiProg ist eine saubere Implementierung der ADIMENS-Schnittstelle. Sie fügt sich sehr gut in das Modula-Entwicklungspaket ein und enthält sinnvolle und leistungsfähige Erweiterungen. Die Funktionssammlung ist hervorragend strukturiert und eine konsequente Erweiterung des Produktangebots für SPC-Modula. SPC-AdiProg kostet DM 249,- und kann bezogen werden bei

Advanced Applications Viczena GmbH
Sperlingweg 19
7500 Karlsruhe 31



Links

Copyright-Bestimmungen: siehe Über diese Seite
Classic Computer Magazines
[ Join Now | Ring Hub | Random | << Prev | Next >> ]