Neue Capability isam-datenbank mit 9 Anforderungen und 25 Szenarien: Tabellenbindung an eine Dateinummer, Indexverwaltung, Cursorbewegung, Schluesselsuche, Satzoperationen, Transaktionen mit Ruecknahme, Vergleichsreihenfolge, Pufferverwaltung und das eigene Dateiformat. sprach-frontend um eine Anforderung erweitert: ISAM-Anweisungen und -Funktionen in Grammatik und Signaturpruefung. Die Delta-Spec wurde vor dem Archivieren an die Original-Hilfe angeglichen -- Cursorlage nach SETINDEX und DELETE, Fehlercode der Suche ueber den NULL-Index. Die Change-Notiz umfang-und-signaturen.md haelt Umfangsabgleich, Argumentformen mit Quellenangabe je Themenseite und die Verifikationsbefunde fest. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
8.9 KiB
Umfang und Argumentformen der ISAM-Elemente (Aufgaben 1.1, 1.2)
Quelle. bas7advr.hlp (BASIC 7 Advisor), Themenseiten unter
https://dos-help.soulsphere.org/bas7advr.hlp/ (abgerufen 2026-09-04).
Die Themenliste selbst ist bereits in
openspec/changes/archive/2026-09-04-phase-3-runtime-bildschirm/rohliste-original-hilfe.md
wortgetreu festgehalten; hier kommen die Syntaxzeilen der Einzelthemen
dazu.
1.1 Umfangsabgleich
Der ISAM-Abschnitt der Original-Hilfe führt genau diese Themen (Zeilen der Rohliste in Klammern):
| Thema der Rohliste | Zeile | Elemente |
|---|---|---|
BEGINTRANS Statement |
26 | BEGINTRANS |
BOF Function |
28 | BOF |
COMMITTRANS Statement |
47 | COMMITTRANS |
CREATEINDEX Statement |
51 | CREATEINDEX |
DELETE Statement |
64 | DELETE |
DELETEINDEX Statement |
65 | DELETEINDEX |
DELETETABLE Statement |
66 | DELETETABLE |
GETINDEX$ Function |
99 | GETINDEX$ |
INSERT Statement |
110 | INSERT |
MOVEFIRST, MOVELAST, MOVENEXT, MOVEPREVIOUS Statements |
145 | 4 Elemente |
RETRIEVE Statement |
195 | RETRIEVE |
ROLLBACK, ROLLBACK ALL Statements |
200 | ROLLBACK |
SAVEPOINT Function |
206 | SAVEPOINT |
SEEKGT, SEEKGE, SEEKEQ Statements |
211 | 3 Elemente |
SETINDEX Statement |
213 | SETINDEX |
SETMEM Function |
214 | SETMEM |
UPDATE Statement |
259 | UPDATE |
Das sind 22 Elemente. docs/inventar.md führt in der Gruppe ISAM
genau dieselben 22 Namen, alle mit Status offen. Der Umfang geht damit
nicht über die Aufzählung im Proposal hinaus — die Liste im Proposal
ist deckungsgleich.
Kein eigenes Element: TEXTCOMP kommt in der Themenliste nicht vor
(bestätigt den Befund aus design.md, D4). Ebenso wenig ein Thema für
Sicherungspunkte außer SAVEPOINT oder für Datenbankwartung.
Elemente mit zusätzlichem ISAM-Verhalten, die schon anderweitig
implementiert sind und deshalb keinen eigenen Inventareintrag der Gruppe
ISAM haben: OPEN (Klausel FOR ISAM), CLOSE, EOF, LOF, LOC.
1.2 Argumentformen je Element
Syntaxzeilen wortgetreu aus der jeweiligen Themenseite der Original-Hilfe.
| Element | Syntax (Original-Hilfe) | Themenseite |
|---|---|---|
OPEN … FOR ISAM |
OPEN database$ FOR ISAM tabletype tablename$ AS [#]filenumber% |
x_dot_opfior.html |
CREATEINDEX |
CREATEINDEX [#]filenumber%,indexname$,unique%,columnname$[,columnname$] |
x_dot_CREATEINDEXr.html |
DELETEINDEX |
DELETEINDEX [#]filenumber%,indexname$ |
x_dot_DELETEINDEXr.html |
SETINDEX |
SETINDEX [#]filenumber%[,indexname$] |
x_dot_SETINDEXr.html |
GETINDEX$ |
GETINDEX$ (filenumber%) |
x_dot_GETINDEX$r.html |
INSERT |
INSERT [#]filenumber%,recordvariable |
x_dot_INSERTr.html |
RETRIEVE |
RETRIEVE [#]filenumber%,recordvariable |
x_dot_RETRIEVEr.html |
UPDATE |
UPDATE [#]filenumber%,recordvariable |
x_dot_UPDATEr.html |
DELETE |
DELETE [#]filenumber% |
x_dot_DELETEr.html |
DELETETABLE |
DELETETABLE database$,tablename$ |
x_dot_DELETETABLEr.html |
MOVEFIRST u. a. |
MOVEFIRST [#]filenumber% (ebenso MOVELAST, MOVENEXT, MOVEPREVIOUS) |
x_dot_MOVEFIRSTr.html |
SEEKGT/SEEKGE/SEEKEQ |
SEEKGT [#]filenumber% ,keyvalue [,keyvalue]… |
x_dot_seekisamr.html |
BEGINTRANS |
BEGINTRANS |
x_dot_BEGINTRANSr.html |
COMMITTRANS |
COMMITTRANS |
x_dot_COMMITTRANSr.html |
ROLLBACK |
ROLLBACK [savepoint%] bzw. ROLLBACK ALL |
x_dot_ROLLBACKr.html |
SAVEPOINT |
SAVEPOINT (Funktion, liefert eine ganze Zahl) |
x_dot_SAVEPOINTr.html |
SETMEM |
SETMEM(numeric-expression&) |
x_dot_setmemr.html |
BOF |
BOF(filenumber%) |
x_dot_BOFr.html |
Befund zur offenen Frage aus design.md
Die Spaltenliste bei CREATEINDEX ist keine Zeichenkette mit
Trennzeichen, sondern eine Folge einzelner Stringargumente:
columnname$[,columnname$]…. Die Absenkung übernimmt diese Form
unverändert; CREATEINDEX ist damit variadisch (4 bis 12 Argumente,
also bis zu neun Indexspalten).
Ergänzung über die Original-Hilfe hinaus: absteigende Spalten
Die Original-Hilfe kennt bei CREATEINDEX keine Angabe der
Sortierrichtung — Indizes sind dort immer aufsteigend. Die Anforderung
„Indexverwaltung" dieses Changes verlangt aber auf- und absteigende
Spalten. Gewählte Schreibweise: ein vorangestelltes - am Spaltennamen.
CREATEINDEX #1, "NachPreis", 0, "Nachname", "-Preis"
Sie ist eindeutig und kollisionsfrei, weil ein Feldname einer
TYPE-Anweisung nie mit - beginnen kann; Programme des Vorbilds
bleiben dadurch unverändert gültig. Festgehalten in
docs/sprachreferenz.md und docs/bibliothek.md.
Cursor-Semantik folgt dem Vorbild
Die Delta-Spezifikation schrieb ursprünglich an zwei Stellen eine andere Cursorlage vor, als die Original-Hilfe beschreibt. Entscheidung vom 2026-09-04: bei Semantik und Syntax gewinnt das Vorbild, wo immer das möglich ist. Die Spezifikation wurde daraufhin angeglichen, nicht die Umsetzung:
| Situation | Original-Hilfe (und jetzt auch Terminal Basic) |
|---|---|
nach SETINDEX |
„the current record is the first record according to that index" — der erste Satz der neuen Ordnung ist der aktuelle |
nach DELETE |
„the record following the deleted record becomes the current record"; war der gelöschte der letzte, steht der Cursor am Ende der Tabelle ohne aktuellen Satz |
SETINDEX ohne Indexnamen bzw. mit "" wählt den NULL-Index: „If you
omit the indexname$ argument or specify double quotes for it, the
current index is the NULL index" — er „represents the order in which
records were added to the file".
Präfixsuche: Verhalten je Suchart
Die Original-Hilfe unterscheidet die Sucharten bei zu wenigen Schlüsselwerten ausdrücklich; die Umsetzung übernimmt das:
SEEKEQmit unvollständigem Schlüssel schlägt immer fehl („SEEKEQ with insufficient keyvalues always fails").SEEKGEsucht mit den vorhandenen Werten als Präfix.SEEKGTmit unvollständigem Schlüssel positioniert auf dem ersten passenden Satz — also wieSEEKGE, nicht hinter der Präfixgruppe.
Fehler 87: Auslöser ist die Suche über den NULL-Index
Der Proposal-Abschnitt „ISAM-Fehlersemantik" nennt Code 87 („ISAM -
Invalid operation on NULL index"). Die Themenseite zur SEEK-Familie
schweigt zur Lage ohne aktiven Index — der Fehlerkatalog des Vorbilds
benennt sie aber genau: der NULL-Index führt keine Schlüssel, sondern nur
die Einfügereihenfolge, eine Schlüsselsuche über ihn ist deshalb die
„unzulässige Operation auf dem NULL-Index".
Die Delta-Spezifikation nannte hier zunächst Fehler 83; sie ist mit der
Entscheidung vom 2026-09-04 („bei Semantik gewinnt das Vorbild") auf 87
angeglichen. 83 bleibt dem wirklich unbekannten Indexnamen vorbehalten
und wird von SETINDEX und DELETEINDEX ausgelöst. Damit hat jeder Code
von 81 bis 89 einen Auslöser.
Bewegung über den NULL-Index bleibt zulässig (MOVE-Familie in
Einfügereihenfolge) — die Original-Hilfe beschreibt den NULL-Index
ausdrücklich als Reihenfolge, nicht als Fehlerzustand.
Befunde der Verifikation (2026-09-04)
Vier Befunde aus /opsx:verify, alle umgesetzt.
CLOSE beendet keine Transaktion
Ursprünglich schrieb CLOSE eine laufende Transaktion fest, um Aufgabe 4.5
(„schreibt ausstehende Änderungen fest") zu erfüllen. Das war zu weit
gegriffen und hatte zwei beobachtbare Folgen:
BEGINTRANS : INSERT #1, p : CLOSE #1 ' Satz blieb erhalten
BEGINTRANS : INSERT #1, p : END ' Satz verfiel
und, schlimmer, über Dateinummern hinweg:
OPEN … AS #1 : OPEN … AS #2
BEGINTRANS : INSERT #1, p : CLOSE #2 ' schrieb die Änderung an #1 fest
ROLLBACK ALL ' → Fehler 5, Satz überlebte
Aufgabe 4.5 ist auch ohne diese Festschreibung erfüllt, weil jede Operation
außerhalb einer Transaktion für sich eine Transaktion ist. CLOSE löst
seither nur die Bindung; über das Ende einer Transaktion entscheiden allein
COMMITTRANS und ROLLBACK ALL, und eine beim Programmende offene
Transaktion verfällt — in beiden Wegen gleich. Delta-Spec, Aufgabe 4.5 und
die Referenzen sind angeglichen; zwei Einheitentests halten es fest.
CREATEINDEX ohne Obergrenze der Spaltenzahl
Die Signatur begrenzte den Index auf neun Spalten. Die Original-Hilfe nennt
keine Obergrenze, also darf die Signatur auch keine setzen: die
Spaltenargumente werden jetzt wie bei INSTR gesondert geprüft (ab dem
vierten Argument je ein String), die Argumentzahl ist offen.
Kein Index-Torso nach Fehler 86
Scheiterte CREATEINDEX an der Eindeutigkeit, blieb innerhalb einer
Transaktion eine halb gefüllte Indextabelle zurück, die keine
Indexdefinition mehr nannte. index_anlegen bildet jetzt erst alle
Schlüssel und prüft die Eindeutigkeit, bevor es schreibt — dieselbe
Reihenfolge wie in satz_schreiben.
Toter Klon in RETRIEVE
satz_lesen klonte das Tabellenlayout je Aufruf, ohne es zu benutzen.
Entfernt.