# Beispiele aus dem Lehrbuchteil des gedruckten Handbuchs # "COHERENT /rdb Relational Database Manager" (coherent.pdf, Kapitel 1-16). # # Aufbau: # @ ordner die folgenden Befehle laufen in diesem Unterordner # ## text Überschrift mit Seitenangabe (Buchseite) # $ befehl wird mit sh ausgeführt; die Zeilen darunter sind die Ausgabe laut Buch # ! text das Programm weicht hier vom Buch ab (Grund im Text); nicht verglichen # # text Kommentar, z. B. ein Druckfehler im Buch, der in der Ausgabe korrigiert ist # # Verglichen wird ohne Leerraum: Spalten dürfen mit Tabulator oder Leerzeichen # getrennt sein, Strichzeilen dürfen verschieden lang sein, Leerzeilen zählen nicht. # Der Test test/handbuch_test.rb führt alles in einer Kopie dieses Ordners aus. @ kap02 ## S. 12: column Amount Description < expenses # Druckfehler im Buch: dort steht nur "column Amount". $ column Amount Description < expenses Amount Description ------ ---------------------------- 67.00 plane ticket 12.00 meal with client 150.00 hotel bill ## S. 12-13: row 'Amount > 50' < expenses $ row 'Amount > 50' < expenses Date Amount Account Description ------ ------ ------- ----------- 850125 67.00 4120 plane ticket 850127 150.00 4120 hotel bill ## S. 13: column und row in einer Pipe $ column Amount Description < expenses | row 'Amount > 50' Amount Description ------ ----------- 67.00 plane ticket 150.00 hotel bill ## S. 18: justify < mlist $ justify < mlist name address city st ---- ------- ---- -- Evan Main St. Santa Cruz CA Rod Broadway Ithaca NY ## S. 18: column st name < mlist | sorttable | jointable - states $ column st name < mlist | sorttable | jointable - states st name state -- ---- ----- CA Evan California NY Rod New York @ kap03 ## S. 25-26: column Item Cost Amount < inventory $ column Item Cost Amount < inventory Item Cost Amount ---- ---- ------ 1 50 3 2 5 100 3 80 5 4 19 23 5 24 99 6 147 89 7 175 5 ## S. 26: row 'Cost > 50' < inventory $ row 'Cost > 50' < inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 3 5 80 400 clamps 6 89 147 13083 bunsen burners 7 5 175 875 scales ## S. 26: column Item Cost Value < inventory | row 'Cost > 50' # Druckfehler im Buch: die dritte Spalte heißt dort Amount (mit den Werten von Amount). $ column Item Cost Value < inventory | row 'Cost > 50' Item Cost Value ---- ---- ----- 3 80 400 6 147 13083 7 175 875 ## S. 26: ... | mean -l Value # Druckfehler im Buch: Kopf und Werte der dritten Spalte wie oben; der Mittelwert 4786 stimmt. $ column Item Cost Value < inventory | row 'Cost > 50' | mean -l Value Item Cost Value ---- ---- ----- 3 80 400 6 147 13083 7 175 875 ---- ---- ----- 4786 ## S. 27: compute 'Value = Onhand * Cost' < stock # Im Buch heißt die Tabelle inventory; hier stock, weil S. 25 eine andere inventory zeigt. $ compute 'Value = Onhand * Cost' < stock Item Onhand Cost Value Description ---- ------ ---- ----- ----------- 1 3 5 15 rubber gloves 2 100 1 100 test tubes 3 5 8 40 clamps 4 23 2 46 plates 5 99 3 297 cleaning cloth 6 89 18 1602 bunsen burners 7 5 175 875 scales ## S. 27: compute mit if, über zwei Zeilen $ compute 'if (Item == 4) \ Cost += 5; Value = Onhand * Cost' < stock Item Onhand Cost Value Description ---- ------ ---- ----- ----------- 1 3 5 15 rubber gloves 2 100 1 100 test tubes 3 5 8 40 clamps 4 23 7 161 plates 5 99 3 297 cleaning cloth 6 89 18 1602 bunsen burners 7 5 175 875 scales ## S. 28: justify Onhand Value Cost < stock $ justify Onhand Value Cost < stock Item Onhand Cost Value Description ---- ------ ---- ----- ----------- 1 3 5 15 rubber gloves 2 100 1 100 test tubes 3 5 8 40 clamps 4 23 2 46 plates 5 99 3 297 cleaning cloth 6 89 18 1602 bunsen burners 7 5 175 875 scales ## S. 28: column Description Item Onhand Cost Value < stock # Druckfehler im Buch: bei plates steht dort Value 51 statt 46. $ column Description Item Onhand Cost Value < stock Description Item Onhand Cost Value ----------- ---- ------ ---- ----- rubber gloves 1 3 5 15 test tubes 2 100 1 100 clamps 3 5 8 40 plates 4 23 2 46 cleaning cloth 5 99 3 297 bunsen burners 6 89 18 1602 scales 7 5 175 875 ## S. 29: total < stock # Druckfehler im Buch: 2980 (mit Value 51 für plates, siehe oben); richtig ist 2975. $ total < stock Item Onhand Cost Value Description ---- ------ ---- ----- ----------- 28 324 212 2975 ## S. 29: total -l Value < stock # Druckfehler im Buch wie oben: Value 51 und Summe 2980. $ total -l Value < stock Item Onhand Cost Value Description ---- ------ ---- ----- ----------- 1 3 5 15 rubber gloves 2 100 1 100 test tubes 3 5 8 40 clamps 4 23 2 46 plates 5 99 3 297 cleaning cloth 6 89 18 1602 bunsen burners 7 5 175 875 scales ---- ------ ---- ----- ----------- 2975 ## S. 30: subtotal -l Account Debit Credit < ledger ! Das Buch zeigt die Kontonummern als 101.0 und 130.0 und schreibt 0, wo eine Summe null ist; wir lassen das Feld leer und behalten 101. $ subtotal -l Account Debit Credit < ledger Account Date Debit Credit ------- ------ ----- ------ 101.0 820102 25000 101.0 820103 5000 101.0 820104 15000 ------- ------ ----- ----- 101.0 25000 20000 130.0 820104 30000 ------- ------ ----- ----- 130.0 30000 0 150.1 820103 10000 ------- ------ ----- ----- 150.1 10000 0 211.1 820104 15000 211.1 820102 25000 211.1 820103 5000 ------- ------ ----- ----- 211.1 0 45000 ## S. 30-31: subtotal Account Debit Credit < ledger ! Wie oben: 101.0 statt 101 und 0 statt leer. $ subtotal Account Debit Credit < ledger Account Date Debit Credit ------- ---- ----- ------ 101.0 25000 20000 130.0 30000 0 150.1 10000 0 211.1 0 45000 ## S. 31-32: row 'Value > 100' < stock | column Description Value | sorttable $ row 'Value > 100' < stock | column Description Value | sorttable Description Value ----------- ----- bunsen burners 1602 cleaning cloth 297 scales 875 ## S. 34: das Skript fix $ compute 'Value = Onhand * Cost' < stock | justify Item Onhand Cost Value Description ---- ------ ---- ----- ----------- 1 3 5 15 rubber gloves 2 100 1 100 test tubes 3 5 8 40 clamps 4 23 2 46 plates 5 99 3 297 cleaning cloth 6 89 18 1602 bunsen burners 7 5 175 875 scales @ kap06 ## S. 73-74: jointable employee child $ jointable employee child Id First Last Birth Sex Name -- ----- ---- ----- --- ---- 1 Howard Ho 450503 Male Sally 1 Howard Ho 450503 Male Lynn ## S. 74-75: jointable course course.student $ jointable course course.student Course Credit Room Day Time Student ------ ------ ---- --- ---- ------- art-1a 3 RB-8 MWF 10am 1 chem-1 4 HA-18 TTh 2pm 1 chem-1 4 HA-18 TTh 2pm 2 ## S. 75: jointable -j Student student course.student $ jointable -j Student student course.student Student First Last Year Course ------- ----- ---- ---- ------ 1 Jim Clark 2 art-1a 1 Jim Clark 2 chem-1 2 Mary Witte 1 chem-1 ## S. 75: zwei Verbunde hintereinander $ jointable -j Student student course.student | \ jointable -j Course - course Student First Last Year Course Credit Room Day Time ------- ----- ---- ---- ------ ------ ---- --- ---- 1 Jim Clark 2 art-1a 3 RB-8 MWF 10am 1 Jim Clark 2 chem-1 4 HA-18 TTh 2pm 2 Mary Witte 1 chem-1 4 HA-18 TTh 2pm ## S. 76: Raumgröße je Kurs (room.size) # Im Buch heißt die Kurstabelle course; hier courses, weil S. 74 eine andere course zeigt. $ sorttable Room < courses | jointable -j Room - room | column Course Room Size > room.size $ cat room.size Course Room Size ------ ---- ---- cs-101 DB-1 250 chem-1 HA-18 17 his-10 HA-18 17 art-1a RB-8 23 econ-1 RB-8 23 ## S. 80: column Course Student Grade Teacher Title < universe $ column Course Student Grade Teacher Title < universe Course Student Grade Teacher Title ------ ------- ----- ------- ----- chem-1 1 3 1 Assist. chem-1 2 2 1 Assist. chem-1 3 2 1 Assist. cs-101 2 1 2 Prof. cs-101 4 4 2 Prof. econ-1 1 3 2 Prof. econ-1 2 3 2 Prof. econ-1 3 2 2 Prof. his-10 1 3 3 Assoc. ## S. 81: column Course Teacher Title < universe > course.teacher $ column Course Teacher Title < universe > course.teacher $ cat course.teacher Course Teacher Title ------ ------- ----- chem-1 1 Assist. chem-1 1 Assist. chem-1 1 Assist. cs-101 2 Prof. cs-101 2 Prof. econ-1 2 Prof. econ-1 2 Prof. econ-1 2 Prof. his-10 3 Assoc. ## S. 81: column Course Student Grade < universe > grade $ column Course Student Grade < universe > grade $ cat grade Course Student Grade ------ ------- ----- chem-1 1 3 chem-1 2 2 chem-1 3 2 cs-101 2 1 cs-101 4 4 econ-1 1 3 econ-1 2 3 econ-1 3 2 his-10 1 3 ## S. 81: uniq < course.teacher $ uniq < course.teacher Course Teacher Title ------ ------- ----- chem-1 1 Assist. cs-101 2 Prof. econ-1 2 Prof. his-10 3 Assoc. ## S. 82: column Teacher Title < course.teacher | uniq > teacher $ column Teacher Title < course.teacher | uniq > teacher $ cat teacher Teacher Title ------- ----- 1 Assist. 2 Prof. 3 Assoc. ## S. 82: column Course Teacher < course.teacher # Laut Buch ist course.teacher hier schon mit uniq bereinigt. $ uniq < course.teacher | column Course Teacher Course Teacher ------ ------- chem-1 1 cs-101 2 econ-1 2 his-10 3 @ kap06-telefonbuch # S. 82-85: Das Buch zeigt die Tabellen teacher, teacher.course, course.student # und student nicht, nur das Ergebnis. Sie sind daraus und aus der Tabelle grade # (S. 79) zurückgerechnet; Namen und Nummern der anderen Lehrer sind erfunden. ## S. 83-84: tmp1, die Lehrernummer von Joy Xi $ row 'First == "Joy" && Last == "Xi" ' < teacher | column Teacher Teacher ------- 2 ## S. 84: tmp2, ihre Kurse $ row 'First == "Joy" && Last == "Xi" ' < teacher | column Teacher | jointable - teacher.course | column Course | sorttable Course ------ cs-101 econ-1 ## S. 84: tmp3, die Studenten in diesen Kursen $ row 'First == "Joy" && Last == "Xi" ' < teacher | column Teacher | jointable - teacher.course | column Course | sorttable | jointable - course.student | column Student Course | sorttable -n Student Course ------- ------ 1 econ-1 2 cs-101 2 econ-1 3 econ-1 4 cs-101 ## S. 83-85: das ganze Telefonbuch # Druckfehler im Buch: die Ausgabe zeigt zusätzlich die Spalte Year, obwohl nur # Course Last First Phone projiziert werden. $ row 'First == "Joy" && Last == "Xi" ' < teacher | column Teacher | tee tmp1 | jointable - teacher.course | column Course | sorttable | tee tmp2 | jointable - course.student | column Student Course | sorttable -n | tee tmp3 | jointable - student | column Course Last First Phone | sorttable > phonebook $ cat phonebook Course Last First Phone ------ ---- ----- ----- cs-101 Dunce Boris 765-4321 cs-101 Early Mary 123-4567 econ-1 Early Mary 123-4567 econ-1 Farkel Freddy 123-1234 econ-1 Knott Why 123-7654 @ kap07 ## S. 90: eine Tabelle Zeile für Zeile in der Shell lesen $ exec 0< inventory; read HEAD; set $HEAD; echo "The first field is $1 and the fifth field is $5." The first field is Item and the fifth field is Description. ## S. 91-92: das Skript onhand $ sh onhand 2 < inventory We have 100 test tubes on hand. ## S. 93: listtosh < mail.list ! Das Buch schützt den Apostroph als 'McDonald\'s'; in der Shell wirkt der Backslash in '...' aber nicht. Wir schreiben 'McDonald'\''s', das eval richtig liest. $ listtosh < mail.list Number='1' Name='Ronald McDonald' Company='McDonald\'s' Street='123 Mac Attack' City='Menphis' State='TENN' ZIP='30000' Phone='(111) 222-3333' ## S. 93: column Name Phone < mail.list | listtosh ! Hier zeigt das Buch beide Zuweisungen in einer Zeile, eine Seite vorher und in der Man-Page steht jede auf einer eigenen. Wir schreiben eine je Zeile; für eval ist das gleich. $ column Name Phone < mail.list | listtosh Name='Ronald McDonald' Phone='(111) 222-3333' ## S. 94: eval mit listtosh $ eval `column Name Phone < mail.list | listtosh`; echo "$Name's phone number is $Phone." Ronald McDonald's phone number is (111) 222-3333. ## S. 94: ein Satz als Shell-Variablen $ echo `row 'Item == 3' < inventory | tabletolist | listtosh`; eval `row 'Item == 3' < inventory | tabletolist | listtosh`; echo "We have $Amount $Description." Item='3' Amount='5' Cost='80' Value='400' Description='clamps' We have 5 clamps. ## S. 94-95: der Lohnbericht (UNIX World) # column legt die noch fehlende Spalte total leer an, compute füllt sie. $ jointable hours employee | sorttable code | jointable -j1 code -j2 number - task | sorttable number | column number fname lname code hours rate total | compute 'total = hours * rate' | justify > tmp ! Bei Anne Rowan (3) steht im Buch code 2 vor code 1. sorttable im Original sortiert gleiche Schlüssel nach der ganzen Zeile (wie sort), unser sorttable lässt ihre Reihenfolge. $ subtotal -l number hours total < tmp number fname lname code hours rate total ------ ----- ----- ---- ----- ---- ----- 1 John Wilson 2 3 75 225 1 John Wilson 2 4 75 300 ------ ----- ----- ---- ----- ---- ----- 1 7 525 2 Fred Jackson 1 4 85 340 2 Fred Jackson 2 5 85 425 ------ ----- ----- ---- ----- ---- ----- 2 9 765 3 Anne Rowan 2 5 75 375 3 Anne Rowan 1 6 75 450 ------ ----- ----- ---- ----- ---- ----- 3 11 825 ## S. 95: die Gesamtsumme $ total total < tmp | justify | tail -1 2115 @ kap10 ## S. 103/107: index -mh mailtable Name ! Das Buch hat 2n+1 = 5 Plätze und rechnet die Summe der Zeichen (ohne Leerzeichen) modulo 5; wir nehmen 2n = 4 Plätze. $ index -mh mailtable Name $ cat mailtable.h Offset -------- 0 156 0 104 0 ## S. 104: echo "Ronald McDonald" | search -mh mailtable Name $ echo "Ronald McDonald" | search -mh mailtable Name Number Name Company Phone ------ --------------- ------------- -------------- 1 Ronald McDonald McDonald's (111) 222-3333 ## S. 105: search -mh mailtable < name $ search -mh mailtable < name Number Name Company Phone ------ --------------- ------------- -------------- 1 Ronald McDonald McDonald's (111) 222-3333 2 Chiquita Banana United Brands 1234 ## S. 105: cat name | search -mh mailtable $ cat name | search -mh mailtable Number Name Company Phone ------ --------------- ------------- -------------- 1 Ronald McDonald McDonald's (111) 222-3333 2 Chiquita Banana United Brands 1234 ## S. 106: index -mr mailtable $ index -mr mailtable $ cat mailtable.r Offset --------- 104 156 ## S. 108: index -mi mailtable Name ! Das Buch schreibt die Spalten in der Reihenfolge Offset Name; bei uns steht der Schlüssel vorn (Name Offset). $ index -mi mailtable Name $ cat mailtable.i Offset Name ------ ------- 156 Chiquita Banana 104 Ronald McDonald ## S. 109: search -mi -x mailtable Name (Teiltreffer) $ echo Ron | search -mi -x mailtable Name Number Name Company Phone ------ --------------- ---------- -------------- 1 Ronald McDonald McDonald's (111) 222-3333 ## S. 107: index -mb mailtable Name sortiert die Tabelle $ index -mb mailtable Name $ cat mailtable Number Name Company Phone ------ --------------- ------------- -------------- 2 Chiquita Banana United Brands 1234 1 Ronald McDonald McDonald's (111) 222-3333 @ kap11 ## S. 111-112: seek, blank und replace löschen Satz 5 ! Das Buch nennt als Ort "207 245 0 9"; das hängt davon ab, wie die Tabelle mit Leerzeichen aufgefüllt war. $ echo 5 | seek -mb -o tmp inventory Item ## S. 112: blank < tmp | replace -mb inventory $LOCATION $ LOCATION=`echo 5 | seek -mb -o tmp inventory Item`; blank < tmp | replace -mb inventory $LOCATION $ cat inventory Item Amount Cost Value Description ---- ------ ---- ----- ----------- 1 3 50 150 rubber gloves 2 100 5 500 test tubes 3 5 80 400 clamps 4 23 19 437 plates 6 89 147 13083 bunsen burners 7 5 175 875 scales ## S. 113: julian Date < project > tmp ! Das Buch rechnet 890601 als 1752623; die Man-Page von gregorian rechnet 861222 als 1752827, also einen früheren Tag mit einer größeren Zahl. Wir folgen der Man-Page. Die Abstände (30, 31, 31, 30 Tage) stimmen. $ julian Date < project > tmp; cat tmp Date Description ------- ----------- 1752623 Start project 1752653 Project crises 1752684 Abandon project 1752715 Coverup blame 1752745 Write off losses ## S. 113-114: 45 Tage später $ compute 'Date += 45' < tmp > tmp1; gregorian Date < tmp1 > project; cat project Date Description ------ ----------- 890716 Start project 890815 Project crises 890915 Abandon project 891016 Coverup blame 891115 Write off losses ## S. 114: Tage zwischen zwei Daten $ julian Start Stop < house | compute 'Days = Stop - Start' | gregorian Start Stop > tmp; mv tmp house; cat house Start Stop Days Step ------ ------ ---- ---- 890101 890118 17 Lay concrete 890121 890212 22 Setup frame 890215 890302 15 Build walls 890305 890401 27 Install fixtures 890408 890425 17 Sell at a loss ## S. 115: Datum im US-Format # Das Buch rechnet hier mit dem ursprünglichen project (vor den 45 Tagen). $ printf 'Date\tDescription\n----\t-----------\n890601\tStart project\n890701\tProject crises\n890801\tAbandon project\n890901\tCoverup blame\n891001\tWrite off losses\n' > project; julian Date < project | gregorian -u Date | justify Date Date Description -------- ---------------- 6/01/89 Start project 7/01/89 Project crises 8/01/89 Abandon project 9/01/89 Coverup blame 10/01/89 Write off losses ## S. 116: union journalcash journalloan journaladjust > journal $ union journalcash journalloan journaladjust > journal; cat journal Date Account Debit Credit Description ------ ------- ----- ------ ----------- 891222 101 25000 cash from loan 891223 101 5000 cash payment 891224 101 15000 cash payment to CCPSC for parts 891222 211.1 25000 loan number #378-14 Bank Amerigold 891223 211.2 5000 note payable to Zarkoff Equipment 891224 130 30000 inventory - parts from CCPSC ## S. 117: difference journal journalloan $ difference journal journalloan Date Account Debit Credit Description ------ ------- ----- ------ ----------- 891222 101 25000 cash from loan 891223 101 5000 cash payment 891224 101 15000 cash payment to CCPSC for parts 891224 130 30000 inventory - parts from CCPSC ## S. 117: intersect journal journaladjust $ intersect journal journaladjust Date Account Debit Credit Description ------ ------- ----- ------ ----------- 891224 130 30000 inventory - parts from CCPSC @ kap15 ## S. 131-132: tabletofact female male parent isa > fact $ tabletofact female male parent isa > fact; cat fact female(michele). female(beth). female(sandy). female(jan). male(kirk). male(rod). male(shawn). male(durk). parent(michele,rod). parent(kirk,rod). isa(rod,human). isa(human,mammal). isa(mammal,animal). isa(animal,lifeform). ## S. 132: tabletorule ruletable > rule $ tabletorule ruletable > rule; cat rule mother(X,Y) :- female(X) , parent(X,Y). father(X,Y) :- male(X) , parent(X,Y). son(X,Y) :- male(X) , parent(Y,X). isa(X,Y) :- isa(X,Z) , isa(Z,Y).