Datenbank-Programmierung mit Turbo-BASIC XL


Datenbank-Programmierung mit Turbo-BASIC XL

von Soeren » Sa 20. Okt 2018, 14:35
Hallo,

zuerst wünsche ich heute allen Beteiligten und dem Club eine erfolgreiche JHV. :)

An die, die mitlesen, ich habe weniger eine Frage, sondern würde gerne einen Erfahrungsaustausch in Sachen Daten auf Diskette speichern mit Turbo-Basic starten. In den letzten Wochen habe ich mich intensiver damit beschäftigt, welche Funktionen dafür geeignet sind

Ganz klassisch kann man eine Datei mit OPEN #1,8,0,"D:TEST.DAT" zum schreiben öffnen. Doch wie speichert man effektiv Daten dort ab? Wenn man normale Zahlenvariablen nimmt, dann kostet das pro Eintrag 6 Byte. Sparsamer ist es Daten als String abzuspeichern. Aber nicht mit PRINT #1,STRING$ sondern mit PRINT #1;STRING$. Den Fehler hab ich zuerst gemacht. Allerdings sollte man folgendes beachten, man kann beliebig lange Strings mit dem PRINT-Befehl speichern, aber nicht mit INPUT einlesen. Dort gibt es eine Längenbegrenzung von 255 (oder 256?) Bytes.

Ein weiterer Punkt ist wichtig, Strings werden im RAM und auf Diskette als Zeichenkette gespeichert. Aber im RAM wird die Länge des Strings abgelegt, auf der Diskette wird ein String mit dem End of Line=Return-Zeichen beendet - CHR$(155). Und das kann ein Problem sein. Wenn man Daten als 8Bit-Zeichen auf Diskette ablegen will, dann ist die 155 tabu. D.h. man müsste in der Vor- und Nachbearbeitung in Turbo-Basic das Zeichen ersetzen, oder nur 7 Bit-Charakters abspeichern (womit 1/8 an Speicher verloren geht).

Man kann sich auch überlegen, ob man mit BGET und BPUT die Daten direkt in einen RAM-Speicherbereich schreibt, und schaut, wie man diese weiter verarbeitet, habe damit aber keine weitere Erfahrung.

Ich schreibe gerade an einem Turbo-Basic Programm, was automatisch die Namen und Sektorenanzahl auf einer Diskette liest und in eine Datenbank separat ablegt und Suchanfragen starten kann. Dabei habe ich wieder einiges gelernt. Wer ähnliche Erfahrungen gesammelt hat, darf sie gerne hier teilen.

Gruss
Sören

Re: Datenbank-Programmierung mit Turbo-BASIC XL

von Soeren » Mo 22. Okt 2018, 11:45
Eine Frage hätte ich doch noch. Für eine unkomplizierte Indexberechnung (für die Setzung des Schreib-/Lesekopfs mittels POINT-Befehls in Turbo-BASIC) darf die Datei nicht fragmentiert sein. Da bei DOS 2.5 und anderen DOSs die Einträge zur Verzeichnisstruktur und Dateinamen irgendwo bei den 300er-Sketoren stehen, kann eine Zerteilung einer großen Datei leicht passieren. Ich behelfe mich damit, dass ich auf einer leeren Diskette (mit den beiden DOS-Dateien) zuerst eine große Dummy-Datei schreibe, um die Sektoren bis zur 400 zu blockieren. Danach schreibe ich meine eigentliche Datei, die dann unfragmentiert in den hohen Sektorenzahlen liegt und lösche anschließend wieder die Dummy-Datei. Auf einem realen Diskettenlaufwerk ohne Speedy ist das recht langwierig. Gibt es eine einfachere Art, Dateien auf Sektoren der eigenen Wahl abzulegen?

Re: Datenbank-Programmierung mit Turbo-BASIC XL

von slx » Mo 22. Okt 2018, 13:48
Soeren hat geschrieben:Eine Frage hätte ich doch noch. Für eine unkomplizierte Indexberechnung (für die Setzung des Schreib-/Lesekopfs mittels POINT-Befehls in Turbo-BASIC) darf die Datei nicht fragmentiert sein.


Ich dachte immer, POINT sei relativ zum Dateibeginn, weil unter Atari-DOS Dateien wegen der Verkettung der einzelnen Sektoren nur sequentiell eingelesen werden können. Da sollte es eigentlich egal sein, wie die Sektoren au f der Diskette verteilt sind. (Damit ist es leider auch mit Index nicht möglich, schnell auf einen bestimmten Record zuzugreifen, weil DOS die Sektoren eben nur von vorne nach hinten lesen kann.

Re: Datenbank-Programmierung mit Turbo-BASIC XL

von Soeren » Mo 22. Okt 2018, 19:10
Nein, leider nicht. POINT und NOTE setzen und lesen den Lese-/Schreibkopf bezüglich der Diskettenposition aus, und nicht nach der logischen Position, innerhalb der Datei. Man kann das selber gerne testen (mit einer schreibfähigen Diskette):

10 OPEN #1,8,0,"D:DUMMY.TMP"
20 NOTE #1,PSECT,PBYTE
30 PRINT "SECTOR: ";PSECT;", BYTE: ";PBYTE
40 CLOSE #1
50 DELETE "D:DUMMY.TMP"

In der Tat wäre es für Anwender einfacher, mit den Positionierungen innerhalb einer Datei zu arbeiten. Aber ich vermute mal, dass es im BASIC-Interpreter einfacher war, über die DOS-Routinen die absolute Position des Lese-/Schreibkopfs zu setzen und zu lesen. Aber wir Programmierer sind es schon gewöhnt, ein bissel mehr Gehirnschmalz in die eigene Arbeit mit dem Interpreter zu stecken. ;)

Re: Datenbank-Programmierung mit Turbo-BASIC XL

von atarixle » Mo 22. Okt 2018, 19:15
Wenn du in BASIC Zahlen mit PRINT #1;ZAHL in eine Datei schreibst, dann kommt auch diese als String auf der Diskette an, ohne sie vorher in einen solchen umzuwandeln.

6 Byte nimmt die Zahl nur dann an, wenn du sie mit %PUT #1,ZAHL speicherst.

Du kannst Daten auch sparsam speichern, wenn du den zu erwartenden Wertebereich kennst.

Weißt du schon vorher, dass die Zahl nur Werte zwischen einschließlich 0 und 255 sein kann (z.B. die Koordinaten von Pixeln auf einem GR.15 Bildschirm), so speicherst du auf der Disk eben nur als ein einziges Byte ab:
Code: Alles auswählen
PUT #1,ZAHL

das ist äquivalent zu
Code: Alles auswählen
PRINT #1;CHR$(ZAHL);


Etwas komplizierter wird es bei Zahlen in 16 Bit, hier musst du Low- und Highbyte ausrechnen:
Code: Alles auswählen
PUT #1,ZAHL-INT(ZAHL/256)*256, INT(ZAHL/256)

Das geht auch eleganter mit
Code: Alles auswählen
DPOKE ADR(ZAHL$),ZAHL:BPUT #1,ADR(ZAHL$),2

(Die Hilfsvariable ZAHL$ muss mit 2 Stellen als String DIMensioniert werden.

Willst du einen längen String abspeichern, so geht das z.B. mit
Code: Alles auswählen
DPOKE ADR(ZAHL$),LEN(STRING$):REM die Laenge des Strings als 16 Bit Wert in ZAHL$ speichern
BPUT #1,ADR(ZAHL$),2:REM die 16 Bit Zahl auf Diskette speichern
BPUT #1,ADR(STRING$),LEN(STRING$):REM die eigentlichen Daten speichern


Gelesen werden kann das dann mit
Code: Alles auswählen
GET#1,Z1:GET#1,Z2:ZAHL=Z1+Z2*256
BGET#1,ADR(STRING$),ZAHL


Nun musst du halt entscheiden, ob du einen längeren Programm-Code oder mehr Platz auf Diskette verwenden möchtest.

POINT kann auch mit fragmentierten Dateien verwendet werden. Mann muss dann vorher eben den Index erstellen, in dem man Datensatz für Datensatz einliest und vor je einem Datensatz seinen Index auf der Diskette mit NOTE abfragt. Dieser Index ist nur für diese Datei auf diesem Datenträger gültig. Mit BGET kannst du die Datei recht schnell einlesen, auch dann, wenn die Datei aus großen Datensätzen besteht.

Re: Datenbank-Programmierung mit Turbo-BASIC XL

von GoodByteXL » Mo 22. Okt 2018, 20:03
Soeren hat geschrieben:Nein, leider nicht. POINT und NOTE setzen und lesen den Lese-/Schreibkopf bezüglich der Diskettenposition aus, und nicht nach der logischen Position, innerhalb der Datei. Man kann das selber gerne testen (mit einer schreibfähigen Diskette):

10 OPEN #1,8,0,"D:DUMMY.TMP"
20 NOTE #1,PSECT,PBYTE
30 PRINT "SECTOR: ";PSECT;", BYTE: ";PBYTE
40 CLOSE #1
50 DELETE "D:DUMMY.TMP"

In der Tat wäre es für Anwender einfacher, mit den Positionierungen innerhalb einer Datei zu arbeiten. Aber ich vermute mal, dass es im BASIC-Interpreter einfacher war, über die DOS-Routinen die absolute Position des Lese-/Schreibkopfs zu setzen und zu lesen. Aber wir Programmierer sind es schon gewöhnt, ein bissel mehr Gehirnschmalz in die eigene Arbeit mit dem Interpreter zu stecken. ;)

Die Problematik mit der sequentiellen Vorgehensweise trifft nur auf ATAR-DOS und dazu kompatible zu. Deswegen findet man auch keine brauchbare Software dieser Art für DOS 2.x & Co. Für zügiges Arbeiten muss man erst die Datenbank auf RAMDisk kopieren, damit arbeiten und dann zurückkopieren ...

Mit SpartaDOS und kompatiblen DOS gibt es dieses Problem nicht. Die Disk-Versionen können max. 8 MiB wahlfrei adressieren, die Cartridge-Version 32 MiB.

Als Beispiel dafür bietet sich die Betrachtung von "WASEO DICTIONARY++" von MiP an. Wettbewerbsbeitrag 2009, vorgestellt in Clubmagazin #98. U.a. zu finden auf der DVD 30 Jahre ABBUC.

Nachtrag: Sondermagazin 42, B-Seite. MiP hat davon eine XXL-Version mit großem Wörterbuch. Ggf. fragen, er managed die PDs.