
Home
Benchmarks
Historie
Forum
Download
Helpware
Insider
Dokumentation
Kurs
Provider-Infos
Impressum
|
tdbengine-news vom 19.11.2003
Seit der letzten News ist viel Zeit vergangen. Das liegt aber
mitnichten daran, dass sich bei der tdbengine nichts mehr tut, genau das
Gegenteil ist der Fall: Es gibt eine neue Version 6.2.9 mit einer
ganzen Reihe neuer Features und Möglichkeiten, die weiter unten
beschrieben werden.
CGI-Anwendungen ohne
Apache-Konfiguration
Bereits in der der Version 6.2.8 (Linux und FreeBSD) war die Option
eingebaut, mit direct_scripting direkt ausführbare CGI-Scripten
erzeugen zu können. Leider sind die Möglichkeiten, die sich
daraus ergeben, nicht klar genug herausgestellt worden: Jetzt kann die
tdbengine bei allen Providern eingesetzt werden, die Ihnen Webspace mit
freien CGI's zur Verfügung stellen ( Strato, 1und1, PureTec...). Es
ist keine Konfiguration des Web-Servers notwendig! Die Sache ist sehr
einfach:
1. Legen Sie unterhalb Ihres CGI-Verzeichnisses ein Verzeichnis
"tdbengine" an.
2. Kopieren Sie in dieses Verzeichnis alle Dateien der tdbengine
3. Sorgen Sie dafür, dass folgende Dateien ausführbar sind:
tdbengine, pdk.prg, scanfile.prg
Das war's auch schon. Wenn Ihre Domain beispielsweise
"www.meinedomain.de" heisst ind Ihr CGI-Verzeichnis "cgi-bin", dann
sollte jetzt der Aufruf von
"http://www.meinedomain.de/cgi-bin/tdbengine/test.prg" das bekannte
"Hello world!" in die Browser-Anzeige zaubern.
Hier noch ein Hinweis für Windows-Anwender: Das einfache Kopieren
der Datein mittels FTP reicht nicht aus, da in den meisten Fällen
derart transpotierte Dateien für alle anderen Anwender ausser dem
User selbst nur lesbar sind. Aber nahezu alle bekannten FTP-Klienten
können die Zugriffrechte ändern.
Das tdbSQL-Projekt
Thomas Friebel, ein Mitarbeiter der TDB-GmbH, hat das Projekt eines auf
der tdbengine basierenden SQL-Servers initiiert und hurtig
vorangetrieben. Unter http://tdbsql.sourceforge.net
können Sie den aktuellen Stand des Projekt sehen. Mitarbeiter
sind stets willkommen. Besonders spannend an diesem Projekt werden die
Schnittstellen zu PHP, Perl und Java sein (gerade hier ist kompetente
Mitarbeit gefragt).
Neue Möglichkeiten in der Konfiguration
Die Konfigurationsdatei wird (auf Unix-Systemen) nun in folgenden
Verzeichnissen gesucht:
1. Im Verzeichnis, in dem sich das auszuführende Programm befindet
2. Im Verzeichnis, in dem sich die (ausführbare) tdbengine befindet
3. Im Verzeichnis /etc/tdbengine
Auf Windows-Systemen entfällt 3.
errorlog
In der tdbengine.ini kann nun auch der Pfad zur Fehler-Logdatei
eingestellt werden:
[globals]
errorlog=/var/log/tdbengine/error_log
cdmode
Mit cdmode=1 in der Abteilung [globals] der tdbengine.ini kann
festgelegt werden, dass sämtliche Tabellen im R/O-Modus
geöffnet werden, auch wenn im Programm etwas anderes angegeben ist.
Textdateien, die zum Schreiben geöffnet werden, werden automatisch
zu Ramtexten.
Programminterne Kommunikation
über Environment-Variablen
Es gibt nun zusätzlich zum Environment, das vom Betriebssystem zur
Verfügung gestellt wird, zwei weitere Variablen, auf die innerhalb
eines EASY-Programms zugegriffen werden kann:
TDB_VERSION
Die tdbengine liefert hier String der Form "6.2.9"
TDB_OS
Da gibt es derzeit zwei Antworten:
"unix" für FreeBSD und Linux
"win32" für Windows
Mit einer (bislang undokumentierten) Spezialform der Funktion GetEnv)
kann man auch Variablen für das interne Environment der tdbengine
setzen:
GetEnv('set:Varibale=Wert')
Beispiel: GetEnv('set:MEIN_NAME=Hans Mustermann')
In der Folge liefert GetEnv('MEIN_NAME') den String 'Hans Mustermann'.
Diese Variable dann solange gültig, bis sie entweder umdefiniert
oder aber die tdbengine beendet wird.
Zwei selbstdefinierte Environment-Variablen werden von der tdbengine
selbst ausgewertet:
HTTP_PROXY
Der Inhalt dieser Variablen wird verwendet, wenn ein Template von einem
entfernten Rechner via http geladen wird, also bei
LoadTemplate('http://...')
Ist die Variable HTTP_PROXY auf die IP-Adresse (oder bekannten
Rechnernamen) gesetzt, so wird die Anfrage an diesen geleitet. Der
Zugriff eines Web-Servers auf des Web über einen Proxy ist ein
gängiges Verfahren, Sicherheitsrisiken zu minimieren.
TDB_SUBST
Diese Variable wird dann ausgewertet, wenn die tdbengine als Server
läuft, also die Funktion SERVER aktiv ist. In diesem Fall wird die
Funktion CGIWRITETEMPLATE so erweitert, dass vor der Ausgabe des
Templates sämtliche Ersetzungen durchgeführt werden, die in
der Datei stehen, auf die TDB_SUBST verweist. Diese Datei ist
zeilenweise so aufgebaut:
Target;Ersetzung
Statt langer Erklärungen hier ein Beispiel:
Angebommen wir haben folgendes Template:
<html>
<head>
<base href="http://www.tdb-engine.de/">
</head>
<body>
<img src="http://www-tdb-engine.de/pics/einbild.jpg">
<h3>Herzlich Willkommen</h3>
<a href="/scripts/anfang.prg">Zur
Einleitung</a><br>
<a href="/scripts/ende.prg">Zum Ende</a><hr>
</body>
</html> |
im aktuellen Verzeichnis gibt es eine Text-Datei 'local' mit folgendem
Inhalt:
www.tdb-engine.de;localhost:3444
/scripts/;/cgi-tdb/local/
/anfang.prg";anfang.prg?query=start"
|
Nach GetEnv('set:HTTP_SUBST=local') gibt die tdbengine das obige
Template (mit CGIWriteTemplate) so aus:
<html>
<head>
<base href="http://localhost:3444/">
</head>
<body>
<img src="http://localhost:3444/pics/einbild.jpg">
<h3>Herzlich Willkommen</h3>
<a href="/cgi-tdb/local/anfang.prg?query=start">Zur
Einleitung</a><br>
<a href="/cgi-tdb/local/ende.prg">Zum
Ende</a><hr>
</body>
</html> |
Alles klar? Zugegeben, es ist kompliziert. Aber die Möglichkeit,
die sich aus diesem Feature erschließt, ist einfach
überwältigend: Sie können einen bestehenden
Internetauftritt (mit dynamischen Inhalten, sonst wäre es ja
langweilig) mit ganz wenigen Handgriffen so auf eine CD brennen, dass
dieser ohne eine Änderung an den Programmen oder HTML-Seiten sofort
von dieser CD läuft. Machen Sie das mal mit irgendeinem anderen
Programm (PHP/MySQL, Perl ... )
Neue Funktionen
ReOpenDB
Es gilt ja die Regel, dass man eine Tabelle nur mit den unbedingt
benötigten Rechten öffnen sollte. Manchmal kommt es aber vor,
dass man ein Tabelle zum Lesen geöffnet hat, und nun will man in
diese Tabelle schreiben. Also CloseDB mit anschließendem OpenDB?
Diese Lösung hat den Nachteil, dass nach dem CloseDB der alte
Tabellenhandle nicht mehr gültig ist und der neu (nach OpenDB)
nicht mehr mit dem alten übereinstimmen muss. Um das zu herhindern
gibt es nun die Funktion ReOpenDB, das den Tabellenhandle bewahrt und
die Tabelle mit neuen Rechten wiederöffnet.
ReOpenDB(db : INTEGER; accessmode : INTEGER) : INTEGER
Zu den zulässigen accesmodes siehe OpenDB.
Ramtext
Ramtext(Filename : STRING; InitSize : INTEGER)
Normalerweise werden Ramtexte mit 16 KByte initialisiert (ausser wenn
Sie bei der Erzeugung schon mehr Platz benötigen). Sie wachsen dann
bei Bedarf ebenfalls in 16 KByte-Schritten. Mit dieser Funktion kann das
geändert werden. Die Initialisierungsgröße kann z.B.
gleich wesentlich größer eingestellt werden, damit die
automatischen Inkremenierungsschritte unterbleiben, die bei sehr
großen Ramtexten zu einem enormen Bedarf an Arbeitsspeicher
führen können.
SetAlias
SetAlias(db : INTEGER; Alias : STRING) : INTEGER
Erzeugt einen weiteren Handle für eine bereits geöffnete
Tabelle. Die Tabelle kann in Subreports etc. uner dem Alias-Namen
angesprochen werden. Die Alias-Tabelle hat einen eigenen Satzpuffer,
eine eigene Markierungsliste und eine eigene Zugriffsverwaltung.
f_pos
Liefert die aktuelle Position in einem Stream:
f_pos(hdl : INTEGER) : INTEGER
Beispiel:
VAR hdl : INTEGER = f_open('./test.prg',0)
VAR buf : BYTE[1000]
...
IF hdl>0 THEN
f_read(hdl,buf[0],10)
cgiwriteln(str(f_pos(hdl)) // ergibt 10
END
Unix-Timestamps
Unter einem Unix-Timestamp versteht man die Anzahl der Sekunden, die
seit Beginn der Unix-Epoche am 1.1.1970 vergangen sind. Werden diese in
einer 32-Bit Variablen gespeichert, so ist damit der Bereich von 1970
bis etwa Anfang 2038 abgedeckt. Unix-Timestamps eignen sich sehr gut,
Update-Zeiten für Datensätze festzuhalten, wenn eine
sekundengenaue Auflösung ausreicht (was in den meisten Fällen
wohl zutrifft).
Konstanten vom Typ Unix-Timestamp werden in der Form
DD.MM.YYYY_hh:mm:ss
angegeben (DD = Tag, MM = Monat, YYYY = Jahr, hh = Stunden, mm =
Minuten, ss = Sekunden). Wichtig ist hierbei der Unterstrich zwischen
Datums- und Zeitangabe.
Folgende Funktionen stehen für Unix-Timestamps zur Verfügung:
UNIX_NOW
|
Liefert die aktuelle Systemzeit
als Unix-Timestamp, also als Anzahl der Sekunden seit dem 1.1.1970
|
DATETIME_TO_UNIX
|
Berechnet den Unix-Tmestamp
für eine Datums- und Uhrzeitkombination im TDB-Format
|
UNIX_DATE
|
Liefert das Datum (im
TDB-Format) aus einem Unix-Timestamp
|
UNIX_TIME
|
Liefert die Zeit (im TDB-Format)
aus einem Unix-Timestamp
|
UNIXTIME_TO_STR
|
Konvertiert einen Unix-Timestamp
in einen String
|
STR_TO_UNIXTIME
|
Konvertiert einen String in
einen Unix-Timestamp
|
Zum Speichern von Unix-Timestamps gibt es den neuen Datentyp "UTIME",
der eine 32-Bit-Zahl speichert. GetField und SetField konvertieren
derartige Inhalte automatisch:
SetField(db,'edit_date','18.11.2003_14:12:52')
GetField(db,'edit_date') -> "18.11.2003_14:12:52"
Scheller wird es freilich, wenn auf Unix-Timestamps mit den Funktionen
SetRField und GetRField zugegriffen wird.
SetRField(db,'edit_date',UNIX_NOW)
IF UNIX_NOW-getrfield(db,'edit_date')<3600 THEN ...
// Datensatz wurde innerhalb der letzten Stunde editiert...
Erweiterungen bereits bekannter Funktionen
LoadTemplate via Proxy
Diese interne Erweiterung wurde bereits oben bei HTTP_PROXY
erläutert.
f_open
Bisher wurden Streams (untypisierte Daten) immer im R/W-Modus
geöffnet. Das kann manchmal lästig sein, in vielen Fällen
ist es aber unnötig. Deshalb gibt es jetzt einen (optionalen)
zusätzlichen Parameter, mit dem der Modus festgelegt wird.
Näheres siehe in der Supportdatenbank.
Socket- und Streamfunktionen mit
direkter Pufferindizierung
Die Funktionen f_read, f_write, getsock und putsock wurden so
erweitert, dass beim Übertragungspuffer nun auch ein Feldindex
angegeben werden kann:
VAR buf : CHAR[10000]
f_read(hdl,buf[x],n) : INTEGER
f_read(hdl,buf,n) = f_read(hdl,buf[0],n) // wie bisher
Das Server-Projekt
Die Funktion "server" ist nun auch in der Windows-Version
verfügbar, allerdings hier nur als Single-Process-Server. Das
sollte aber für die allermeisten Anwendungen keine gravierende
Rolle spielen. Und weil diese Variante auch für Linux von Interesse
sein kann, ist sie auch hier verfügbar:
server(Port,Prozess,Maxconnections[,Modus]) : INTEGER
Port: TCP-Port für eingehende Verbindungen
Prozess : parameterlose EASY-Prozedur
Maxconnections : maximale Anzahl von Verbindungen (Sockets) für
den Server
Modus : 0 (Vorgabe) -> Single-Process, 1 (nur Linux/FreeBSD) ->
Multi-Process (forked)
Die Funktion liefert nur dann ein Ergebnis, wenn sie terminiert, was
sie eigentlich nicht machen sollte. In diesem Fall ist das
Funktionsergebnis der Fehlercode des betriebssystems:
13: Öffnen des privilegierten Ports verboten
98: Port bereits belegt
Die Arbeitsweise:
Wenn "server" ausgeführt wird, wartet die tdbenine auf eingehende
TCP-Verbindungen am angegeben Port. Wird eine Verbindung aufgebaut, so
wird die angegebene Prozedur ausgeführt. Innerhalb dieser Prozedur
sind zwei Handles verfügbar:
TextHandle 128
SocketHandle 128
Beide Handles können zur Kommunikation mit dem Klienten verwendet
werden. Allerdings sollte man darauf achten, dass für das Lesen und
Schreiben (bzw. Empfangen und Senden) nur jeweils eines der beiden
Handles verwendet wird, vorzugsweise das Socket-Handle (weil
Textoperationen immer gepuffert werden).
Ist die Funktion server aktiv, so werden alle CGI-Ausgaben (CGIWrite,
CGIWriteln, CGIWriteTemplate) auf dem Server-Socket ausgeführt.
Wenn die Prozedur beendet wird, wird die Verbindung zum Klienten
beendet und das ganze Spiel beginnt von vorne.
Was kann man damit machen?
Ein Beispiel: Mini-Web-Server für Einzelplatz- und
CD-Applikationen
Hierzu gibt es in Kürze eine eigene Beschreibung im Doku-Bereich.
Viel Erfolg mit der tdbengine wünscht
Ulrich Kern
|
Newsletter
Anmeldung zum Newsletter:
|