Wer häufig Programrme mit anderen Entwicklern austauscht, ärgert sich bisweilen darüber, dass eingebundene Bibliotheken nicht auf Anhieb gefiunden werden.
so muss der Linuxanwender die Verzeichnisangabe ändern. Aus diesem Grund ist jetzt möglich, in die Konfigurationsdatei tdbengine.ini unter der Abteilung [globals] in dem Eintrag »libpath« eine Pfadangabe vorzunehmen, in dem dann die via USES eingebundenen Module gesucht werden.
REAL gibt es jetzt die nachgestelten Inkrement- und Dekrement-Operatoren:
VARDEF i : REAL
i++ steht für i:=i+1
i-- steht für i:=i-1
+ + + + + + + + + + + + + + + + + + + + +
Zusätzliche Kommentarzeichen
Statt der zwei aufeinanderfolgenden Punkte kann jetzt auch der Doppel-Slash als Kommentarzeichen benutzt werden:
// Das ist ein Kommentar.
+ + + + + + + + + + + + + + + + + + + + +
Neue Funktion InitArray
Mit dieser Funktion können zur Laufzeit Felder re-dimensioniert werden. Damit sind dynamisch dimensionierte Felder in EASY möglich.
Beispiel:
VARDEF vektor : REAL[]
...
high(1,vektor) // ergibt 0
initarray(vektor[10000]
high(1,vektor) // ergibt 10000
+ + + + + + + + + + + + + + + + + + + + +
Erweiterte Syntax
Bei folgenden Anweisungen wurde die strenge Zeileneinteilung aufgehoben:
IF bool THEN ... {ELSIF bool THEN ...} [ELSE ...] END
WHILE bool DO ... END
REPEAT ... UNTIL bool
RETURN [exp]
»bool« steht für einen logischen Ausdruck, »...« steht für beliebige Anweisungen
Die einzige Bedingung, die hier noch gilt, lautet: Ausdrücke dürfen nicht auf mehrere Zeilen verteilt werden.
Um Abwärtkompatibilität zu gewährleisten, gelten noch folgende Zusatzregeln:
»THEN« kann am Zeilenende weggelassen werden
»DO« kann am Zeilenende (oder wenn keine Anweisungen vorliegen) weggelassen werden
Damit können trotz der Syntaxerweiterung alle früheren Programme compiliert werden.
Beispiele für den Einsatz der erweiterten Snytax:
IF n=0 THEN cgiwriteln('Kein Treffer') ELSE cgiwriteln(str(n)+' Treffer') END
WHILE subst('#target#',paramstr(0)) END
IF x=y THEN i:=10; REPEAT cgiwriteln(str(i)) UNTIL i--=0 END
+ + + + + + + + + + + + + + + + + + + + +
Das System-Modul
Jetzt sind alle Standardfunktionen in dem Modul »system« zusammengefasst. Dieses Modul wird automatisch in jedes Programm importiert, und zwar vor allen anderen Importen. Damit können alle Bezeichner aus diesem Modul umdefiniert werden. Nach einer Redefinition kann der Modulbezeichner »system« verwendet werden, um auf den Bezeichner der Standardbibliothek zurückzugreifen.
Beispiel:
VARDEF indname, dbname : STRING
...
indname:=system.indname(db,1)
dbname:=dbdir(db)+system.dbname(db)
Da es bisher nicht möglich war, Bezeichner aus der Standardbibliothek in eigenen Programmen zu verwenden, ist dieses Feature voll abwärtskompatibel.
+ + + + + + + + + + + + + + + + + + + + +
Kein Leerzeichen mehr vor Minus
Die Version 6.2.3 macht Schluss mit der EASY-Eigenart, dass zwischen einem Bezeichner und einem Minus-Zeichen ein Leerzeichen eingefügt werden musste. Der Compiler löst Konflikte selbständig auf.
Die Markierung von Datensätzen
Die übliche Vorgehensweise, wenn es darum geht, Datensätze aus einer Tabelle auszuwählen, besteht bei EASY darin, diese Datensätze zu markieren. Jede geöffnete Tabelle hat eine (anfangs leere) Markierungsliste, die mit folgenden Funktionen der Standardbibliothek manipuliert werden kann:
delmarks(db) löscht die gesamte Markierungsliste
setmark(db,r) fügt den Datensatz mit der physikalischen Satznummer r hinzu
delmark(db,r) entfernt den Datensatz mit der Satznummer r aus der Liste
Das folgende Programmfragment liest eine gesamte Tabelle und markiert diejenigen Datensätze, auf die eine bestimmte Bedingung zutrifft:
VARDEF db, i, fs : REAL
VARDEF PLZ_gesucht : STRING
PLZ_gesucht:='80*'
IF db:=opendb('database/adressen.dat') THEN
i:=0; fs:=filesize(db)
WHILE i++<=fs DO
readrec(db,i)
IF getfield(db,'PLZ') like PLZ_gesucht THEN setmark(db,i) END
END
END
Selbstverständlich ist das keine optimale Strategie, denn das Lesen einer gesamten Tabelle dauert recht lange. Wesentlich besser wäre beispielsweise hier eine indizierte Suche. Da es aber nur um das Prinzip geht, wollen wir an dieser Stelle darauf verzichten.
Die Größe der Markierungsliste einer Tabelle liefert die Funktion »nmarks«:
nmarks(db) -> Anzahl der markierten Datensätze
Als nächsten Schritt wollen wir die gefundenen Datensätze nach Name und Vorname sortieren. Dafür bietet EASY die Funktion »sortmark«
sortmark(db,'Name,Vorname') ->0 alles in Ordnung, sonst Fehlercode
Selbstverständlich muss es sich bei »Name« und »Vorname« um gültige Feldbezeichner der Tabelle »db« handeln.
Mit der Funktion »revmarks« kann die aktuelle Ordnung der Markierungsliste einer Tabelle umgedreht werden
revmarks(db) -> Anzahl der markierten Datensätze
Jetzt wollen wir die Treffer ausgeben. Dazu greifen wir auf die Funktionen »firstmark« und »nextmark« zurück.
firstmark(db) -> erster Satznummer der Markierungsliste
nextmark(db,x) -> nächste Satznummer der Markierungsliste bzgl. x
VARDEF x : REAL
x:=firstmark(db)
WHILE x>0 DO
cgiwrite(getfield(db,'Name')+',')
cgiwriteln(getfield(db,'Vorname')+'<br>')
x:=nextmark(db,x)
END
In manchen Fällen kommt es vor, dass man die Markierungsliste zwischenpeichern muss, weil z.B. kurzfristig eine weitere Selektion auf die Tabelle vorgenommen werden muss. Zu diesem Zweck bietet EASY die Funktionen »getmarks« und »putmarks«. Diese Funktionen können mit unterschiedlichen Argumenten aufgerufen werden:
VARDEF marks : MARKS
getmarks(db,marks) sichert die Markierungsliste von db in marks
putmarks(db,marks) speichert die gesicherte Markierungsliste zurück
Hinweis: putmarks überschreibt die aktuelle Markierungsliste von db.
Der Datentyp MARKS kann nur mit diesen beiden Funktionen verwendet werden. Der große Vorteil, eine Variable vom Typ MARKS einzusetzen, besteht darin, dass
- nur der wirklich benötigte Speicherplatz verwendet wird
- die Sortierung innerhalb der Markierungslist erhalten bleibt
Die Markierungsliste kann aber auch auf in einem REAL-Array gespeichert werden. Hier muss der Programmierer dafür sorgen, dass das REAL-Array genügend Elemente enthält, um die gesamte Liste speichern zu können:
VARDEF marks : REAL[]
...
initarray(marks[nmarks(db)])
getmarks(db,marks)
putmarks(db,marks)
Nach »getmarks(db,marks)« liegen in »marks« die physikalischen Satznummern der Markierungsliste vor. Hier eine Prozedur, in der die Markierungsiste in einer externen Textdatei gespeichert wird:
PROCEDURE SaveMarks(db : REAL)
VARDEF text,i : REAL
VARDEF marks : REAL[]
initarray(marks[nmarks(db)])
getmarks(db,marks)
IF text:=rewrite('marks_save') THEN
nloop(i,high(1,marks)-1,writeln(text,marks[i]))
close(text)
END
ENDPROC
Auch der Einsatz von »getmarks« und »putmarks« mit einem REAL-Array ist ordnungserhaltend. Der Vorteil liegt darin, dass die Satznummern unmittelbar greif- und manipulierbar vorliegen.
Schließlich gibt es noch die Möglichkeit, eine Variable vom Type TBITS zu verwenden. Um richtig zu arbeiten, muss dieses Feld so dimensioniert werden, dass es die gesamte Tabelle abbilden kann:
VARDEF marks : TBITS[]
... initarray(marks[filesize(db)])
getmarks(db,marks)
putmarks(db,marks)
Hier gilt nach »getmarks(db,marks)«, dass
marks[x]=1 wenn der Datensatz mit der Satznummer x in der Markierungsiste ist
marks[x]=0 andernfalls
»marks« ist somit ein Abbild der Teilmenge der Tabelle, die durch die Markierungsliste festgelegt ist. Und wie bei jeder Menge, geht hier die Ordnung verloren! Der Vorteil der Verwendung von TBITS liegt vor allem darin, dass mit den Funktionen
bitand(b_feld1,b_feld2)
bitor(b_feld1,b_feld2)
bitandnot(b_feld1,b_feld2)
die wichtigsten Mengenoperationen sehr effizient durchgeführt werden können. Alle drei Funktionen liefern liefern die Cardinalität (Anzahl der Einsen) von »b_feld_1« nach der jeweiligen Operation.
bitand: b_feld1 := b_feld1 geschnitten mit b_feld2
bitor: b_feld1 := b_feld1 vereinigt mit b_feld2
bitandnot: b_feld1 := b_feld1 geschnitten mit dem Komliment von b_feld2 (Mengendifferenz)
Die Arbeit mit dem Datentyp TBITS ist so effizient, dass beispielsweise die Volltextsuche grundsätzlich darauf zurückgreift (»markbits«). Man wird sie immer dann einsetzen, wenn mehrere - logisch verknüpfte - Selektionen auf eine Tabelle ausgeführt werden.