Files
rdb/README.md
T

147 lines
6.8 KiB
Markdown

# rdb
Ein Nachbau von **/rdb**, dem relationalen Datenbanksystem der Mark Williams
Company für COHERENT (um 1991), in Ruby. Das Original-Handbuch und die
Man-Pages stammen aus den freigegebenen MWC-Quellen
([nesssoftware.com/home/mwc/source.php](https://www.nesssoftware.com/home/mwc/source.php)).
Der Programmcode von /rdb selbst war darin nicht enthalten. Alle Befehle hier
sind nach dem Handbuch neu geschrieben.
## Einrichten
```
mise install # Ruby 3.4
mise run install # legt die Symlinks row, column, total ... in bin/ an
mise run test # 76 Tests
```
Danach steht `bin/` im PATH, solange man im Projektordner ist (`mise.toml`).
Jeder Befehl ist ein Symlink auf `bin/rdb`, das am Aufrufnamen erkennt, was zu
tun ist. Es geht auch ohne Symlinks: `rdb row 'Cost > 5' < demo/inventory`.
Vier Namen verdecken im Projektordner Systembefehle: `column`, `rename`,
`display` und `whatis`.
## Das Prinzip
Eine **Tabelle** ist eine Textdatei: Kopfzeile mit Spaltennamen, Strichzeile,
dann eine Zeile pro Datensatz, Spalten durch Tabulator getrennt. Jeder Befehl
liest eine Tabelle von stdin und schreibt eine Tabelle nach stdout. Befehle
lassen sich mit Pipes kombinieren.
```
cd demo
row 'Cost > 5' < inventory | column Description Cost | sorttable -nr Cost
compute 'Value = Cost * Amount' < inventory | total Value
jointable inventory owners
```
Dasselbe gilt für **Listen** (ein Datensatz als `Spalte<Tab>Wert`-Zeilen, die
Datei beginnt mit einer Leerzeile). `tabletolist` und `listtotable` wandeln um,
die meisten Befehle lesen beides.
`row`, `compute` und `validate` übergeben ihren Ausdruck an awk, nachdem sie
Spaltennamen durch `$N` ersetzt haben. Es gilt also awk-Syntax.
Spaltennamen unterscheiden Groß- und Kleinschreibung. Mit `RDB_ICASE=1` wird
sie ignoriert (Details unter „Unterschiede zum Original“):
```
RDB_ICASE=1 compute 'wert = cost * amount' < inventory
```
## Hilfe
```
rdb alle Befehle
rdb man search die Original-Man-Page als Text (auch Themen: backup, dbase, dashline ...)
rdb --version Versionsnummer (Änderungen siehe CHANGELOG.md)
rdb man -g search dieselbe Seite mit groff formatiert (Beispiele sauber eingerückt)
whatis column Beschreibung und Syntax
whatwill total Befehle, die zu einem Stichwort passen
commands Tabelle aller Befehle
```
## Befehle
| Gruppe | Befehle |
|---|---|
| Auswahl | `row` `select` `column` `project` `sorttable` `record` `number` `Number` |
| Spalten | `compute` `addcol` `rename` |
| Mengen, Verbund | `jointable` `union` `intersect` `difference` `paste.rdb` `splittable` |
| Auswertung | `total` `mean` `maximum` `minimum` `subtotal` `width` `widest` `precision` `datatype` `schema` `dbdict` |
| Schnellzugriff | `index` `search` `seek` `append` `delete` `replace` `enter` `lock` `unlock` `vilock` `update.rdb` `ve` `vindex` |
| Prüfen | `check.rdb` `domain` `validate` `fd` `searchtree` `tableorlist` |
| Format | `justify` `trim` `compresss` `pad` `rmblank` `blank` `headon` `headoff` `insertdash` `display` `see` |
| Text | `cap` `uppercase` `lowercase` `substitute` `trimblank` `padstring` `length` `filesize` `ascii` `chr` `word` `prompt` `not` `path` |
| Umwandeln | `tabletolist` `listtotable` `listtosh` `tabletofix` `fixtotable` `tabletostruct` `tabletotbl` `tabletofact` `tabletorule` `tabletom4` `tabletosed` `translate` `uniondict` |
| Datum, Namen | `julian` `gregorian` `computedate` `todaysdate` `soundex` `like` `hashkey` |
| Berichte | `report` `reportwriter` `screen` `label` `letter` |
| Terminal, Hilfe | `termput` `tset` `clear.rdb` `cursor` `menu` `rdb` `commands` `helpme` `whatis` `whatwill` `howmany` `man` |
| Betrieb | `testall` `testsearch` `timesearch` `rmcore` `cpdir.rdb` |
| Buchhaltung (/act) | `act` `chartdup` `foot` `adjust` `balance` `close` `consolidate` `getjournal` `fillform` `calculate` `tax` `cashflow` `calcpay` `w2` `bom` `explode` `sale` `invoice` `cstate` `update.inv` |
## Schnellzugriff
Wie im Original sucht `search` über Byte-Offsets. Indizes bauen:
| Option | Methode | Datei |
|---|---|---|
| `-ms` | sequentiell (Vorgabe) | keine |
| `-mb` | binär: `index` sortiert die Tabelle selbst | keine |
| `-mr` | Datensatznummer | `tabelle.r` |
| `-mi` | invertiert (Schlüssel und Offset, sortiert) | `tabelle.i` |
| `-mh` | Hash, doppelt so viele Plätze wie Zeilen | `tabelle.h` |
```
index -mi inventory Description
echo scales | search -mi inventory Description
echo cl | search -mi -x inventory Description # Teiltreffer, Groß/klein egal
echo 5 | seek -mi inventory Item # von bis xvon xbis
```
`delete` überschreibt einen Satz mit Leerzeichen, ohne die Datei zu verschieben.
`replace` schreibt an dieselbe Stelle zurück und hängt den Satz hinten an, wenn
er nicht mehr passt (außer mit `-a`). Beide halten die Indizes aktuell.
`rmblank` räumt später auf.
## Unterschiede zum Original
- Es gibt kein COHERENT-Programmmaterial, daher sind die **Ausgaben nur anhand der
Man-Pages geprüft**, nicht gegen das echte /rdb. Die Beispiele aus dem
Handbuch sind als Tests enthalten (`test/rdb_test.rb`).
- Die Indexdateien haben ein eigenes, einfaches Format (das Original ist nicht
dokumentiert). Sie sind nicht mit alten /rdb-Dateien austauschbar.
- Spaltennamen unterscheiden wie im Original Groß- und Kleinschreibung. Mit
`RDB_ICASE=1` (z. B. in `mise.toml` unter `[env]`) wird sie ignoriert:
ein exakter Treffer gewinnt, mehrere ähnliche sind ein Fehler. In
`row`/`compute`/`validate` bleiben awk-Wörter und Funktionsaufrufe unberührt
(eine Spalte `Length` verdeckt also nicht `length()`). Die Man-Pages von
`row`, `compute`, `column`, `sorttable`, `jointable`, `rename`, `validate` und
`rdb` haben dazu den Abschnitt „Case of Column Names“; er ist die einzige
Ergänzung gegenüber den Original-Seiten.
- `jointable` braucht keine vorsortierten Tabellen.
- `ve` ist ein zeilenorientierter Editor, kein Bildschirmeditor.
- `soundex` nutzt den Standard-Algorithmus. Die Beispielwerte im Handbuch
weichen davon ab.
- Die /act-Befehle arbeiten auf Tabellen im aktuellen Ordner. Welche das sind
und welche Spalten sie brauchen, steht jeweils in der Man-Page. Das Paket ist
wie im Original nur ein Beispiel für Datenbankprogrammierung. Die Befehle, zu
denen das Handbuch nichts sagt (`post`, `purchase`, `ship` ...), fehlen.
## Aufbau
```
bin/rdb das eine Programm (und die Symlinks darauf)
lib/rdb.rb Registry der Befehle
lib/rdb/table.rb Tabellen und Listen lesen und schreiben
lib/rdb/fast.rb Schnellzugriff über Byte-Offsets
lib/rdb/cmd/*.rb die Befehle, nach Gruppen
man/ Man-Pages (troff-Quellen aus den MWC-Archiven)
demo/ Beispieltabellen, testall.cmds und testall.old
test/ Tests
```
Die Man-Pages und die Beispieltabellen stammen aus den MWC-Quellen. Lizenz der
Originale: BSD, Copyright 1977-1995 Robert Swartz.