Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5020d7e982 | ||
|
|
d6733e737e | ||
|
|
158ce5dee2 | ||
|
|
c2ea36c6d6 | ||
|
|
1c489f6994 | ||
|
|
75c2424307 | ||
|
|
9f6c450492 | ||
|
|
df8bcdfaf1 | ||
|
|
a38311021d | ||
|
|
140b521493 | ||
|
|
7872307583 | ||
|
|
80941b6f03 | ||
|
|
a02e5cb109 | ||
|
|
a9f3c0b255 | ||
|
|
2e03c0a440 | ||
|
|
6b9810b075 | ||
|
|
b11e3da453 | ||
|
|
1c66773ff4 | ||
|
|
e1bdb6c703 | ||
|
|
777a3b56e2 | ||
|
|
d5286c3600 | ||
|
|
f83d1bd6f8 | ||
|
|
6c0d675c5d |
@@ -0,0 +1,3 @@
|
|||||||
|
/bin/*
|
||||||
|
!/bin/rdb
|
||||||
|
/coherent.pdf
|
||||||
+64
-1
@@ -5,7 +5,70 @@ Alle wichtigen Änderungen stehen hier. Das Format folgt
|
|||||||
folgen [Semantic Versioning](https://semver.org/lang/de/). Die Version steht in
|
folgen [Semantic Versioning](https://semver.org/lang/de/). Die Version steht in
|
||||||
`lib/rdb/version.rb`; `rdb --version` zeigt sie an.
|
`lib/rdb/version.rb`; `rdb --version` zeigt sie an.
|
||||||
|
|
||||||
## [Unveröffentlicht]
|
## [0.8.0] - 2026-10-30
|
||||||
|
|
||||||
|
**Beim Umstieg:** Hashindizes (`.h`) und mit `index -x` gebaute Indizes (`.i`) neu bauen.
|
||||||
|
|
||||||
|
### Hinzugefügt
|
||||||
|
- `doc/handbuch.txt`: der Text des gedruckten Handbuchs „COHERENT /rdb Relational Database Manager“ (346 Seiten), per OCR aus dem Scan, mit PDF- und Buchseiten.
|
||||||
|
- `demo/handbuch/`: die Beispiele aus dem Lehrbuchteil (Kapitel 2, 3, 6, 7, 10, 11, 15) mit ihren Tabellen. `beispiele.txt` hält Befehl und gedruckte Ausgabe, `test/handbuch_test.rb` vergleicht sie; `mise run test` führt ihn mit aus. Druckfehler des Buchs und Stellen, an denen wir abweichen, sind dort vermerkt.
|
||||||
|
|
||||||
|
### Geändert
|
||||||
|
- `testall` und die Tests setzen `EDITOR=true`, damit kein echter Editor startet.
|
||||||
|
- `search` und `seek` ohne Schlüsselspalte nehmen die Spaltennamen aus dem Kopf einer Schlüsseltabelle auf der Standardeingabe (`search -mh mailtable < name`, Handbuch S. 105). Vorher galt immer die erste Spalte der Datentabelle.
|
||||||
|
- `gregorian -u` schreibt den Monat ohne führende Null (`6/01/89`), wie im Handbuch.
|
||||||
|
- `mean` schreibt einen ganzzahligen Mittelwert ohne `.00` (`4786`, Handbuch S. 26).
|
||||||
|
|
||||||
|
### Verbessert
|
||||||
|
- Schnellzugriff: `search`, `seek`, `delete` und `update.rdb` lesen bei `-mh`, `-mi` und `-mr` nur noch den Indexeintrag und den einen Satz (Seek auf Byte-Positionen, bei `.i` Halbierung über die Datei), nicht mehr Tabelle und Index vollständig. `Data` liest die Zeilen erst, wenn eine Methode alle braucht.
|
||||||
|
- Die Hashfunktion ist FNV-1a statt der Bytesumme. Vorher fielen 3000 fünfstellige Nummern in 30 Plätze (größter Eimer 223), jetzt liegt der größte Eimer bei etwa 4. **Hashindizes (`.h`) müssen neu gebaut werden** (`index -mh`).
|
||||||
|
- `total`, `mean`, `subtotal` und die /act-Befehle rechnen exakt mit `Rational` statt `Float`: `0.1 + 0.2 + 0.7` ergibt `1.0`, Beträge summieren sich auf den Rappen genau, und es wird kaufmännisch gerundet (halb auf).
|
||||||
|
|
||||||
|
- `bin/rdb` startet mit `ruby --disable-gems`: jeder Befehl ist in etwa doppelt so schnell gestartet (ca. 85 statt 170 ms), weil RubyGems nicht geladen wird. `rdb` braucht nur die Standardbibliothek.
|
||||||
|
- Die Tests laufen parallel (`parallelize_me!`; `MT_CPU=1` für nacheinander). Zusammen mit dem schnelleren Start dauert die Suite 21 statt 70 Sekunden.
|
||||||
|
- Intern: Hilfsfunktionen der Befehlsdateien liegen in `Rdb::Helpers` statt auf `Object`, die Konstanten (`STATS`, `TERM_CAPS` ...) in `Rdb`. Kopf- und Strichzeile entstehen an einer Stelle (`Table.head_text`, `dash_cells`, `headed?`), `awk` baut auf `awk_text` auf.
|
||||||
|
|
||||||
|
### Sicherheit
|
||||||
|
- `report`: Spaltenwerte in `<!befehl <Spalte>!>` wurden unmaskiert in einen Shell-Aufruf eingesetzt, eine Zelle konnte so Befehle ausführen. Sie werden jetzt mit `Shellwords.escape` eingesetzt.
|
||||||
|
- `screen`: Spaltennamen, die keine gültigen Shell-Variablennamen sind, brechen mit einer Meldung ab, statt ins erzeugte Skript zu gelangen.
|
||||||
|
- `lock`/`unlock`: Sperrdateien liegen in `/tmp/rdb-locks-<UID>/` (Modus 0700, Besitzer und Symlinks geprüft) statt lose in `/tmp`; Lesen und Schreiben laufen unter `flock`.
|
||||||
|
- `vilock`: die Sperre wird atomar über einen Hardlink genommen (vorher `exist?` und `rename` mit Lücke dazwischen).
|
||||||
|
|
||||||
|
### Behoben
|
||||||
|
- `EDITOR` mit Argumenten (`nvim -f`) in `vilock` und `update.rdb` wurde als ein Programmname behandelt; der Editor startete nie. Scheitert der Editor, meldet `update.rdb` das, statt „record replaced“ zu schreiben.
|
||||||
|
- `update.rdb e`: Der Satz blieb leer, wenn der Editor scheiterte oder abgebrochen wurde. Er wird jetzt in jedem Fall zurückgeschrieben.
|
||||||
|
- Spaltennamen mit Umlauten (`row 'Über > 3'`) scheiterten mit einem awk-Fehler. Der Ausdrucksumsetzer kennt jetzt Unicode-Buchstaben.
|
||||||
|
- Dateien, die kein UTF-8 sind (Latin-1 aus COHERENT-Zeiten), brachen mit `invalid byte sequence` ab. Sie werden als Latin-1 gelesen und als UTF-8 ausgegeben.
|
||||||
|
- Fehler wie ungültige Regex, ungültiges Datum oder Ein-/Ausgabefehler endeten mit einem Ruby-Backtrace. Jetzt eine Zeile; `RDB_DEBUG=1` zeigt den Backtrace. Ein geschlossenes Pipe-Ende (`| head`) und Ctrl-C beenden still.
|
||||||
|
- `append`, `enter`, `replace` und `ve` schrieben Werte mit Tab oder Zeilenumbruch und machten die Tabelle kaputt. Sie lehnen solche Werte jetzt ab.
|
||||||
|
- Tabellen, Indexdateien und `substitute` werden über eine temporäre Datei mit `rename` geschrieben; ein Abbruch lässt die alte Datei statt einer halben neuen.
|
||||||
|
- `index -mb` und `-mi` sortieren nach dem Schlüssel ohne umgebende Leerzeichen, so wie `search` vergleicht.
|
||||||
|
- `sorttable -r` kehrte auch die Reihenfolge gleicher Schlüssel um; sie bleibt jetzt erhalten.
|
||||||
|
- `index -x` vermerkt die Faltung im Kopf der `.i`-Datei (`Offset-x`). `search` bisektiert in der Ordnung des Index: ohne `-x` in einem gefalteten Index wurden Sätze übersehen, mit `-x` in einem ungefalteten ebenso (dort und bei `-mb` liest die Teilsuche jetzt alle Einträge). `append` hält einen gefalteten Index in seiner Ordnung.
|
||||||
|
- `jointable -n` wurde stillschweigend ignoriert. Wie in der Man-Page vergleicht es die Schlüssel jetzt als Zahlen (`01`, `1` und ` 1.0` passen zusammen).
|
||||||
|
- Spaltennamen, die `justify` mit Leerzeichen aufgefüllt hat, wurden nicht mehr gefunden: `column Name` lieferte eine leere Spalte, `index` brach ab. Leerraum um die Namen im Kopf zählt jetzt nicht mehr.
|
||||||
|
|
||||||
|
## [0.7.0] - 2026-10-12
|
||||||
|
|
||||||
|
### Hinzugefügt
|
||||||
|
- `column -d Spalte ...` (und `project -d`) löscht Spalten: alle anderen bleiben in ihrer Reihenfolge. Fehler bei unbekannter Spalte oder wenn alle gelöscht würden. Dazu Abschnitt in `man/column.man`, Beispiel in `testall.cmds` und Tests.
|
||||||
|
- Kantonstarife 2026 für `tax`: `demo/taxCH_AI2026`, `taxCH_AR2026`, `taxCH_SG2026`, `taxCH_GR2026` (Präfix `taxCH_` für die Schweiz; einfache Staatssteuer für Alleinstehende, vor Steuerfuss, Gemeinde und Kirche), erzeugt mit `tools/gen_tax_tables.rb`. Mit Tests, Beispiel in `testall.cmds` und Erklärung zum Steuerfuss im README.
|
||||||
|
|
||||||
|
### Behoben
|
||||||
|
- `rdb man dashline` (und `headline`, `backup`, `dbase`, `accounting_ter`) zeigte als Überschrift eine Makrozeile (`dashline -- .PP`). Themen-Seiten ohne Beschreibung nehmen jetzt den Titel aus der `.TH`-Zeile.
|
||||||
|
- `splittable -0` und mehr als 676 Stücke endeten mit einem Ruby-Abbruch (im zweiten Fall nach 676 geschriebenen Dateien). Jetzt eine Fehlermeldung, und es wird vorher geprüft, damit nichts halb geschrieben wird.
|
||||||
|
|
||||||
|
## [0.6.0] - 2026-10-11
|
||||||
|
|
||||||
|
### Hinzugefügt
|
||||||
|
- Steuertabellen 2026 für `tax`: `demo/taxDE2026`, `taxAT2026`, `taxCH2026` (nur Bundessteuer), `taxLI2026` (nur Landessteuer), erzeugt mit `tools/gen_tax_tables.rb`, mit Tests.
|
||||||
|
|
||||||
|
### Geändert
|
||||||
|
- `record`: 0 und 1 sind die erste Zeile, negative Zahlen zählen vom Ende (`-1` letzte, `-2` vorletzte ...). Außerhalb der Tabelle kommt eine leere Tabelle, Text und Dezimalzahlen sind ein Fehler. (Vorher lieferten 0, -1 und Text ungewollt Zeilen vom Ende.) `testall.cmds` und `man/record.man` zeigen es.
|
||||||
|
- README und `man/row.man` erklären, warum `select` in bash/zsh/ksh einen Syntaxfehler gibt und wie man es trotzdem aufruft.
|
||||||
|
|
||||||
|
### Behoben
|
||||||
|
- `rdb man` zeigte `\\select` in den Man-Pages als `\elect`: ein doppelter Backslash wird jetzt zuerst geschützt.
|
||||||
|
|
||||||
## [0.5.0] - 2026-10-11
|
## [0.5.0] - 2026-10-11
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,21 @@ sind nach dem Handbuch neu geschrieben.
|
|||||||
## Einrichten
|
## Einrichten
|
||||||
|
|
||||||
```
|
```
|
||||||
|
mise trust # einmal nach dem Clone: mise.toml freigeben
|
||||||
mise install # Ruby 3.4
|
mise install # Ruby 3.4
|
||||||
mise run install # legt die Symlinks row, column, total ... in bin/ an
|
mise run install # legt die Symlinks row, column, total ... in bin/ an
|
||||||
mise run test # 76 Tests
|
mise run test # 136 Tests und die Beispiele aus dem Handbuch
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Ohne `mise trust` brechen in einem frisch geklonten Ordner alle `mise`-Befehle ab.
|
||||||
|
|
||||||
|
> **Wichtig: Nach jedem Clone zuerst die Symlinks anlegen.**
|
||||||
|
> Im Repository liegt nur `bin/rdb`. Die Befehle `row`, `column`, `total` ...
|
||||||
|
> sind Symlinks darauf und werden **nicht** mit eingecheckt (`.gitignore`).
|
||||||
|
> Ohne `mise run install` (oder ohne mise: `bin/rdb install`) gibt es sie nicht,
|
||||||
|
> und Aufrufe wie `row ...` enden mit `command not found`. Auch `testall` und
|
||||||
|
> die Tests brauchen sie. Nach neuen Befehlen den Schritt wiederholen.
|
||||||
|
|
||||||
Danach steht `bin/` im PATH, solange man im Projektordner ist (`mise.toml`).
|
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
|
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`.
|
tun ist. Es geht auch ohne Symlinks: `rdb row 'Cost > 5' < demo/inventory`.
|
||||||
@@ -40,6 +50,8 @@ Dasselbe gilt für **Listen** (ein Datensatz als `Spalte<Tab>Wert`-Zeilen, die
|
|||||||
Datei beginnt mit einer Leerzeile). `tabletolist` und `listtotable` wandeln um,
|
Datei beginnt mit einer Leerzeile). `tabletolist` und `listtotable` wandeln um,
|
||||||
die meisten Befehle lesen beides.
|
die meisten Befehle lesen beides.
|
||||||
|
|
||||||
|
`column -d Spalte ...` löscht Spalten (alle anderen bleiben), `column Spalte ...` wählt sie aus.
|
||||||
|
|
||||||
`row`, `compute` und `validate` übergeben ihren Ausdruck an awk, nachdem sie
|
`row`, `compute` und `validate` übergeben ihren Ausdruck an awk, nachdem sie
|
||||||
Spaltennamen durch `$N` ersetzt haben. Es gilt also awk-Syntax.
|
Spaltennamen durch `$N` ersetzt haben. Es gilt also awk-Syntax.
|
||||||
|
|
||||||
@@ -77,6 +89,28 @@ Eine Zeile mit `##` erscheint als Überschrift in der Ausgabe, eine mit `#` ist
|
|||||||
ein stiller Kommentar. Neue Befehle brauchen hier ein Beispiel, sonst schlägt der Test
|
ein stiller Kommentar. Neue Befehle brauchen hier ein Beispiel, sonst schlägt der Test
|
||||||
`test_testall_mentions_every_command` fehl.
|
`test_testall_mentions_every_command` fehl.
|
||||||
|
|
||||||
|
## Beispiele aus dem gedruckten Handbuch
|
||||||
|
|
||||||
|
`doc/handbuch.txt` ist der Text des gedruckten Handbuchs „COHERENT /rdb Relational
|
||||||
|
Database Manager“ (Mark Williams, 346 Seiten), per OCR aus dem Scan `coherent.pdf`.
|
||||||
|
Er ist nicht korrigiert: Tabulatoren fehlen, Tabellen können verrutscht sein. Jede
|
||||||
|
Seite ist mit PDF- und Buchseite markiert (Buchseite = PDF-Seite − 10). Kapitel 1–16
|
||||||
|
sind ein Lehrbuch, Kapitel 17 enthält dieselben Man-Pages wie `man/`.
|
||||||
|
|
||||||
|
`demo/handbuch/` enthält die Beispiele aus dem Lehrbuch mit ihren Tabellen, ein
|
||||||
|
Unterordner je Kapitel. `beispiele.txt` hält zu jedem Beispiel den Befehl und die
|
||||||
|
Ausgabe, wie sie im Buch steht; `test/handbuch_test.rb` führt alles aus und vergleicht
|
||||||
|
(ohne Leerraum, das Buch richtet mit Leerzeichen aus). In der Datei bedeutet:
|
||||||
|
|
||||||
|
```
|
||||||
|
@ kap03 die folgenden Befehle laufen in diesem Unterordner
|
||||||
|
## S. 26 ... Überschrift mit Buchseite
|
||||||
|
$ befehl darunter die Ausgabe laut Buch
|
||||||
|
# ... Kommentar, z. B. ein Druckfehler des Buchs (die Ausgabe ist korrigiert)
|
||||||
|
! ... hier weichen wir bewusst ab; nicht verglichen, der Test meldet aber,
|
||||||
|
wenn die Ausgabe doch wieder zum Buch passt
|
||||||
|
```
|
||||||
|
|
||||||
## Vorlagen: `form` und `entry`
|
## Vorlagen: `form` und `entry`
|
||||||
|
|
||||||
- `demo/form` ist eine Vorlage für `report` und `letter`: sie setzt Spaltenwerte in einen Text ein.
|
- `demo/form` ist eine Vorlage für `report` und `letter`: sie setzt Spaltenwerte in einen Text ein.
|
||||||
@@ -117,6 +151,48 @@ pick -m -k 'down space down enter' < inventory Tasten aus einem String (Skrip
|
|||||||
Pfeile, Bild auf/ab, Pos1/Ende scrollen; `/` filtert (Enter behält den Filter, Esc löscht ihn); Enter wählt;
|
Pfeile, Bild auf/ab, Pos1/Ende scrollen; `/` filtert (Enter behält den Filter, Esc löscht ihn); Enter wählt;
|
||||||
Esc bricht ab (Status 1, keine Ausgabe). Ohne Markierung gilt die Zeile unter dem Cursor.
|
Esc bricht ab (Status 1, keine Ausgabe). Ohne Markierung gilt die Zeile unter dem Cursor.
|
||||||
|
|
||||||
|
## Steuertabellen 2026 für `tax`
|
||||||
|
|
||||||
|
`demo/` enthält vier Tarife für das Steuerjahr 2026 im Format von `tax` (income, tax, percent), jeweils für
|
||||||
|
Alleinstehende (Grundtarif). Erzeugt mit `ruby tools/gen_tax_tables.rb`.
|
||||||
|
|
||||||
|
| Datei | Land | Quelle | Genauigkeit |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `taxDE2026` | Deutschland, Einkommensteuer | § 32a EStG (Grundfreibetrag 12 348 €) | Kurvenstücke durch Geraden genähert, Abweichung unter 0,15 € (die Formel rundet ab, `tax` auf) |
|
||||||
|
| `taxAT2026` | Österreich, Einkommensteuer | § 33 EStG (0 % bis 13 539 €, dann 20/30/40/48/50/55 %) | exakt, vor Absetzbeträgen |
|
||||||
|
| `taxCH2026` | Schweiz, **nur direkte Bundessteuer** | Art. 36 DBG, ESTV-Rundschreiben 2-215-D-2025 | Stufen exakt, das Gesetz rechnet in 100-Franken-Schritten |
|
||||||
|
| `taxLI2026` | Liechtenstein, **nur Landessteuer** | Art. 19 SteG (LR 640.0, Fassung 01.07.2026) | exakt |
|
||||||
|
| `taxCH_AI2026` | Kanton Appenzell I.Rh., einfache Staatssteuer | Art. 38 StG (ESTV-Kantonsblatt) | exakt |
|
||||||
|
| `taxCH_AR2026` | Kanton Appenzell A.Rh., einfache Staatssteuer (Alleinstehendentarif) | Art. 39 StG, Beträge ab 2024 | exakt |
|
||||||
|
| `taxCH_SG2026` | Kanton St. Gallen, einfache Staatssteuer | Art. 50 StG, Beträge ab 2026 | exakt |
|
||||||
|
| `taxCH_GR2026` | Kanton Graubünden, einfache Kantonssteuer | Art. 39 StG, indexierte Beträge ab 2025 | exakt |
|
||||||
|
|
||||||
|
```
|
||||||
|
tax 60000 < demo/taxDE2026 14233
|
||||||
|
tax 60000 < demo/taxAT2026 15447
|
||||||
|
tax 60000 < demo/taxCH2026 671
|
||||||
|
tax 60000 < demo/taxLI2026 1396 (mal 1 + Gemeindezuschlag, 150 % bis 250 %)
|
||||||
|
```
|
||||||
|
|
||||||
|
Der Betrag ist die Steuer auf das **zu versteuernde** Einkommen. Abzüge, Sozialversicherung, Absetzbeträge,
|
||||||
|
Kirchensteuer und Soli sind nicht enthalten. Für die Schweiz kommen Kanton und Gemeinde dazu (sie sind meist
|
||||||
|
höher als der Bund), für Liechtenstein der Gemeindezuschlag: gesamt = Landessteuer × (1 + Zuschlag/100).
|
||||||
|
Ehepaar- und Alleinerziehendentarife fehlen. Das ist keine Steuerberatung.
|
||||||
|
|
||||||
|
**Kantone (AI, AR, SG, GR):** Die Dateien tragen den Präfix `taxCH_` (Schweiz) vor dem Kantonskürzel; `taxCH2026` ist die Bundessteuer. Die Tabellen geben die *einfache Steuer* wieder. Sie wird mit dem Steuerfuss multipliziert,
|
||||||
|
und Gemeinde und Kirche kommen dazu. Der Kanton setzt den Steuerfuss pro Jahr fest:
|
||||||
|
|
||||||
|
| Kanton | Steuerfuss Kanton 2026 | Quelle |
|
||||||
|
|---|---|---|
|
||||||
|
| AI | 96 % | Kantonsblatt AI (Grossratsbeschluss 1.12.2025) |
|
||||||
|
| SG | 105 % | Budgetbeschluss des Kantonsrats (Websuche, nicht im Kantonsblatt) |
|
||||||
|
| GR | 92 % | Grosser Rat, Budget 2026 (Websuche) |
|
||||||
|
| AR | nicht ermittelt | AR rechnet in Steuereinheiten, die Zahl für 2026 habe ich nicht gefunden |
|
||||||
|
|
||||||
|
Beispiel AI bei 60 000: `tax 60000 < demo/taxCH_AI2026` = 3770, mal 0,96 = 3619 (Kantonssteuer, ohne Bezirk, Gemeinde und Kirche).
|
||||||
|
Oberhalb einer Grenze gilt bei allen vier Kantonen ein fester Satz auf das *ganze* Einkommen (AI ab 200 000 mit 8 %,
|
||||||
|
AR ab 260 800 mit 2,6 %, SG ab 264 500 mit 8,5 %, GR ab 780 440 mit 11 %); in der Tabelle ist das die letzte Zeile.
|
||||||
|
|
||||||
## Befehle
|
## Befehle
|
||||||
|
|
||||||
| Gruppe | Befehle |
|
| Gruppe | Befehle |
|
||||||
@@ -163,10 +239,30 @@ er nicht mehr passt (außer mit `-a`). Beide halten die Indizes aktuell.
|
|||||||
## Unterschiede zum Original
|
## Unterschiede zum Original
|
||||||
|
|
||||||
- Es gibt kein COHERENT-Programmmaterial, daher sind die **Ausgaben nur anhand der
|
- 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
|
Man-Pages und dem gedruckten Handbuch geprüft**, nicht gegen das echte /rdb. Die
|
||||||
Handbuch sind als Tests enthalten (`test/rdb_test.rb`).
|
Beispiele aus den Man-Pages sind als Tests enthalten (`test/rdb_test.rb`), die aus
|
||||||
- Die Indexdateien haben ein eigenes, einfaches Format (das Original ist nicht
|
dem Lehrbuch in `demo/handbuch/` (`test/handbuch_test.rb`).
|
||||||
dokumentiert). Sie sind nicht mit alten /rdb-Dateien austauschbar.
|
- Die Indexdateien sind dem Original nachgebaut, aber nicht gleich (Handbuch S. 103–108):
|
||||||
|
die Hashtabelle `.h` hat 2n statt 2n+1 Plätze (Hashfunktion FNV-1a), und in `.i` steht der
|
||||||
|
Schlüssel vor dem Offset statt dahinter. Ein mit `index -x` gebauter `.i`
|
||||||
|
heißt in der zweiten Spalte `Offset-x`. Alte /rdb-Indizes sowie `.h`- und mit `-x` gebaute
|
||||||
|
`.i`-Dateien von Versionen vor 0.8.0 muss man neu bauen.
|
||||||
|
- Summen, Mittelwerte und /act-Beträge sind Dezimalzahlen (`Rational`), gerundet wird halb auf.
|
||||||
|
- Dateien, die kein UTF-8 sind, liest `rdb` als Latin-1 und schreibt sie als UTF-8. Fehler
|
||||||
|
erscheinen als eine Zeile; mit `RDB_DEBUG=1` kommt der Ruby-Backtrace. Werte mit Tab oder
|
||||||
|
Zeilenumbruch lehnen `append`, `enter`, `replace` und `ve` ab.
|
||||||
|
- `lock`/`unlock` legen ihre Sperrdateien in `/tmp/rdb-locks-<UID>/` ab (Modus 0700, `flock`),
|
||||||
|
nicht als `/tmp/L<Tabelle>` wie in den Man-Pages. Eine Sperre eines abgestürzten Prozesses
|
||||||
|
wird nicht erkannt; `unlock` hebt sie auf.
|
||||||
|
- `vilock` sperrt atomar über einen Hardlink; `EDITOR` darf Argumente haben (`nvim -f`).
|
||||||
|
Nach `kill -9` bleibt `LOCK<Tabelle>` liegen und muss von Hand zurückbenannt werden.
|
||||||
|
- `report`: Spaltenwerte in `<!befehl <Spalte>!>` werden für die Shell maskiert und kommen
|
||||||
|
als ein Wort an; nicht in Anführungszeichen setzen. `screen` verlangt Spaltennamen, die
|
||||||
|
gültige Shell-Variablennamen sind (Buchstaben, Ziffern, `_`).
|
||||||
|
- `sorttable` lässt Zeilen mit gleichem Schlüssel in ihrer Reihenfolge; das Original
|
||||||
|
ordnet sie nach der ganzen Zeile, wie `sort` (Handbuch S. 94).
|
||||||
|
- `subtotal` schreibt bei einer Summe von null ein leeres Feld; das Handbuch zeigt
|
||||||
|
`0` und die Kontonummern als `101.0` (S. 30).
|
||||||
- Spaltennamen unterscheiden wie im Original Groß- und Kleinschreibung. Mit
|
- Spaltennamen unterscheiden wie im Original Groß- und Kleinschreibung. Mit
|
||||||
`RDB_ICASE=1` (z. B. in `mise.toml` unter `[env]`) wird sie ignoriert:
|
`RDB_ICASE=1` (z. B. in `mise.toml` unter `[env]`) wird sie ignoriert:
|
||||||
ein exakter Treffer gewinnt, mehrere ähnliche sind ein Fehler. In
|
ein exakter Treffer gewinnt, mehrere ähnliche sind ein Fehler. In
|
||||||
@@ -175,6 +271,10 @@ er nicht mehr passt (außer mit `-a`). Beide halten die Indizes aktuell.
|
|||||||
`row`, `compute`, `column`, `sorttable`, `jointable`, `rename`, `validate` und
|
`row`, `compute`, `column`, `sorttable`, `jointable`, `rename`, `validate` und
|
||||||
`rdb` haben dazu den Abschnitt „Case of Column Names“; er ist die einzige
|
`rdb` haben dazu den Abschnitt „Case of Column Names“; er ist die einzige
|
||||||
Ergänzung gegenüber den Original-Seiten.
|
Ergänzung gegenüber den Original-Seiten.
|
||||||
|
- `select` ist in bash, zsh und ksh ein reserviertes Wort. `select 'Cost > 5' < inventory` endet dort
|
||||||
|
mit `syntax error near unexpected token '<'`, weil die Shell das Schlüsselwort vor dem `PATH` auswertet.
|
||||||
|
Es gibt dasselbe unter dem Namen `row`. Außerdem gehen `\select ...`, `command select ...` und
|
||||||
|
`rdb select ...`.
|
||||||
- `jointable` braucht keine vorsortierten Tabellen.
|
- `jointable` braucht keine vorsortierten Tabellen.
|
||||||
- `ve` ist ein zeilenorientierter Editor, kein Bildschirmeditor.
|
- `ve` ist ein zeilenorientierter Editor, kein Bildschirmeditor.
|
||||||
- `soundex` nutzt den Standard-Algorithmus. Die Beispielwerte im Handbuch
|
- `soundex` nutzt den Standard-Algorithmus. Die Beispielwerte im Handbuch
|
||||||
@@ -187,13 +287,15 @@ er nicht mehr passt (außer mit `-a`). Beide halten die Indizes aktuell.
|
|||||||
## Aufbau
|
## Aufbau
|
||||||
|
|
||||||
```
|
```
|
||||||
bin/rdb das eine Programm (und die Symlinks darauf)
|
bin/rdb das eine Programm (die Symlinks darauf legt `rdb install` an, nicht im Repo)
|
||||||
lib/rdb.rb Registry der Befehle
|
lib/rdb.rb Registry der Befehle
|
||||||
lib/rdb/table.rb Tabellen und Listen lesen und schreiben
|
lib/rdb/table.rb Tabellen und Listen lesen und schreiben
|
||||||
lib/rdb/fast.rb Schnellzugriff über Byte-Offsets
|
lib/rdb/fast.rb Schnellzugriff über Byte-Offsets
|
||||||
lib/rdb/cmd/*.rb die Befehle, nach Gruppen
|
lib/rdb/cmd/*.rb die Befehle, nach Gruppen
|
||||||
man/ Man-Pages (troff-Quellen aus den MWC-Archiven)
|
man/ Man-Pages (troff-Quellen aus den MWC-Archiven)
|
||||||
demo/ Beispieltabellen; testall.cmds = je ein Beispiel pro Befehl, testall.old = letzter Lauf
|
demo/ Beispieltabellen; testall.cmds = je ein Beispiel pro Befehl, testall.old = letzter Lauf
|
||||||
|
demo/handbuch/ die Beispiele aus dem gedruckten Handbuch, je Kapitel ein Ordner
|
||||||
|
doc/handbuch.txt Text des gedruckten Handbuchs (OCR)
|
||||||
test/ Tests
|
test/ Tests
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env -S ruby --disable-gems
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# rdb -- every /rdb command is this one program, looking at the name it was
|
# rdb -- every /rdb command is this one program, looking at the name it was
|
||||||
# called by. `row`, `column`, `total` ... are symlinks to it (`rdb install`).
|
# called by. `row`, `column`, `total` ... are symlinks to it (`rdb install`).
|
||||||
|
# --disable-gems: rdb needs only the standard library, and skipping RubyGems
|
||||||
|
# makes each command start about twice as fast.
|
||||||
|
|
||||||
require_relative '../lib/rdb'
|
require_relative '../lib/rdb'
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/home/wkh/Development/Coherent/rdb/bin/rdb
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user