Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-03 - decus/20-0078/util/fetch.rno
There is 1 other file named fetch.rno in the archive. Click here to see a list.
.nojustify
.paper size 56,75
.left margin 10
.NOFILL

.skip 6
.center
FETCH  -  ett program f`r laddning av och s`kning i en databas.
.center
===============================================================
.skip 2
.center
av
.skip 2
.center
Kalle M{kil{
.skip 5
INNEH$LL.
========
.skip 2
1.  Inledning.
.skip 1
2.  Laddning av data.
.skip
3.  Sammanl{nkning av poster till set.
.skip
4.  Uts`kning av enskilda poster.
.skip
5.  S`kning genom booleska villkor.
.skip
6.  S`kning via relationer mellan data.
.skip
7.  Skapande av inverterade filer.
.skip
8.  @versikt `ver tillg{ngliga kommandon.
.skip
9.  Beskrivning av programmet SPEC.
.skip
.fill
.page
1.  Inledning.
.break
####=========
.skip
          SIMDBM {r ett programpaket f`r att hantera databaser i SIMULA.
          Man b`rjar med att uppr{tta en specifikation av databasens
          inneh}ll.  Man anger vilka posttyper den skall inneh}lla, och
          vilka dataf{lt varje posttyp skall inneh}lla.  F`r varje f{lt
          anges ett namn och en datatyp.
.SKIP
          Poster kan sedan vara sammanl{nkade s} att man l{tt, givet en
          viss post, kan komma }t andra poster som h`r ihop med den.
          S}dana sammanl{nkningar kallas relationer, eller i
          CODASYL-terminologi SET.  SIMDBM inneh}ller hj{lpmedel f`r att
          hantera SET.
.SKIP
          En specifikation av en databas kan skapas interaktivt med hj{lp
          av programmet SPEC som kortfattat beskrivs i avsnitt 9 i denna
          rapport.
.SKIP
          N{r specifikationen {r klar kan man skriva SIMULA-program som
          arbetar mot databasen t ex lagrar data eller s`ker efter data.
          Dessa program b`r l{mpligen anv{nda som prefix de externa
          SIMULA-klasser som utg`r SIMDBM-systemet.
.SKIP
          FETCH {r ett exempel p} ett s}dant program.  Med FETCH kan man
          lagra data, uppr{tta relationer mellan data och s`ka efter poster
          som uppfyller vissa villkor.
.SKIP
          Relationer mellan poster representeras genom att man fr}n en viss
          post ({garposten) via pekare har tillg}ng till ett antal andra
          poster (medlemsposterna).  Varje medlemspost har ocks} en pekare
          tillbaka till {garposten.  I FETCH finns kommandon f`r att
          definiera namngivna relationer mellan poster av vissa typer
          (DEFINE) och f`r att uppr{tta och ta bort l{nkar mellan enskilda
          postf`rekomster (INSERT och REMOVE).  Det finns ocks} kommandon
          f`r att t ex lista alla data f`r medlemmarna i ett visst set
          (DISPLAY) eller f`r att f`r en viss medlem komma }t data f`r
          {garen (OWNER).  Man kan ocks} g`ra ganska omfattande s`kningar i
          databasen genom att f`lja de relationer som uppr{ttats mellan
          posterna.  Detta beskrivs n{rmare i avsnitt 6.
.SKIP
          Den enklaste formen av uts`kning {r att f} fram enskilda poster
          via deras identifierande begrepp (nyckel), och sedan beg{ra
          utskrift av enskilda dataf{lt inom posten.
          Mera komplexa s`kningar inneb{r att man f`r alla poster av en
          viss typ eller inom ett visst set testar om ett antal villkor {r
          uppfyllda f`r de enskilda dataf{lten, och listar de poster som
          uppfyller villkoren.
          Alternativt kan man spara en lista av pekare till de poster som
          uppfyllde villkoren i databasen (s}ledes uppr{tta ett slags
          inverterad fil) och senare anv{nda denna lista f`r mera
          detaljerade uts`kningar.  Detta slags uts`kningar beskrivs i
          avsnitt 5 (villkorens utseende) och avsnitt 7 (hur man sparar
          resultatet i databasen).  Det finns ocks} m`jlighet att ta ut
          resultatet p} en sekvensiell fil som inneh}ller vissa dataf{lt ur
          posterna, och man kan ocks} utf`ra summering av numeriska f{lt i
          smband med uts`kningen.  Se vidare under kommandot .TABLE i
          avsnitt 8.
.SKIP
.SKIP
          I FETCH promptas man med tecknet _> p} den h`gsta niv}n.
          I stort tillg}r s`kningen s} att man f`rst anger vilken posttyp
          som avses genom kommandot .TYPE,rname.  (Skulle man gl`mma det
          f}r man en p}minnelse f`rsta g}ngen denna information beh`vs)
          D{refter kan man svara antingen med n}got av de kommandon som
          beskrivs nedan, eller med en nyckel f`r en post av aktuell typ.
          Kommandon som kan ges efter promptande _> b`rjar alltid med en
          punkt, och bara de tre f`rsta tecknen i nyckelordet {r
          signifikanta.
.SKIP
          F`r vissa kommandon blir man promptad att ge ytterligare
          information.
.SKIP
          Det som matas in till FETCH kan alltid omfatta flera rader enligt
          f`ljande konvention:
.nofill
.SKIP
      rad som slutar med _& implicerar att
      det finns forts{ttningsrad
      Tecknet _& och blanka i b`rjan och slutet av raderna
      anses inte ing} i den inmatade str{ngen, det `vriga
      konkateneras {nda tills man matar in en rad som
      inte slutar med _&.
.fill
.SKIP
En sammanst{llning av samtliga kommandon finns i avsnitt 8, och
man kan ocks} f} en kortfattad s}dan vid terminalen genom att i
st{llet f`r ett kommando svara med fr}getecken.
.SKIP
Observera att FETCH g`r skillnad mellan stora och sm} bokst{ver i
databasen.  Kommandon inledda med punkt (dvs sj{lva
kommandoordet, inte argumenten) kan dock skrivas med antingen sm}
eller stora bokst{ver.
.skip
F`r de kommandon d{r ytterligare promptningar g`rs kan man
}ngra sig och komma tillbaka till kommandoniv}n genom att
svara med tv} punkter.
.PAGE
.skip 2
.nofill
2.  Laddning av databasen.
    ======================
.SKIP
.fill
Enstaka poster kan laddas genom kommandot .STORE[,recordtype].
Detta medf`r att man blir promptad med f{ltnamnet f`r varje f{lt.
Om man inte anger recordtype antas den vara den som angivits
genom det senaste .TYPE-kommandot.
.SKIP
Element som {r deklarerade som arrayer matas in genom att ange
elementen }tskilda av ett visst specialtecken som man v{ljer n{r
databasen specificeras via programmet SPEC.  (Detta tecken kan
s}ledes inte ing} i de texter som lagras i arrayform.)
.SKIP
Vid inmatningen kontrolleras hela tiden att de inmatade v{rdena
{r av r{tt typ, om icke ges feldiagnos och fr}gan st{lls om.
.SKIP
Att p} detta s{tt mata in m}nga poster skulle bli alltf`r
omst{ndligt och tids`dande.  Det finns i st{llet ett par separata
hj{lpprogram f`r att mata in hela poster:
.SKIP
.nofill
DBLOAD:
=======
.SKIP
Man skapar f`rst en sekvensiell fil ( t ex med en vanlig
texteditor) som har f`ljande format:
.SKIP
rad 1:         inneh}ller bara ett tecken=det tecken som
               sedan anv{nds f`r att avgr{nsa posternas
               f{lt fr}n varandra.
.SKIP
rad 2:         _!_!_!posttypnamn
.SKIP
rad 3 och      en rad per post med f{lten separerade av angivet
f`ljande       specialtecken.    Forts{tter tills ny rad som
               b`rjar med tre utropstecken anger att data
               f`r en ny posttyp b`rjar.
.SKIP
.nofill
EXEMPEL:
=======
.fill
Antag att vi har posttypen FIRMA(NAMN,BRANSH,ANTALANST,PROD)
och vill mata in fyra poster med f{lten avgr{nsade genom
semikolon. Man skapar f`rst f`ljande fil med indata:
.nofill
.SKIP
;
_!_!_!FIRMA
ASEA;METALL;4500;22
L M Ericsson;METALL;3600;48
Algots;TEXTIL;2100;12
ARLA;LIVSMEDEL;800;29
.page
Sedan k`r man programmet DBLOAD, varvid man promptas att
ge namn och imagesize f`r databasen resp indatafilen.
.skip 2
.nofill
LOAD:
====
.SKIP
.fill
Laddar data fr}n en kolumnbunden sekvensiell fil.  Man promptas
f`rst att ange filnamn och blockl{ngd f`r databasen och f`r den
fil som utg`r indata.
.SKIP
Sedan f}r man ange namn p} den posttyp som skall matas in.  Denna
m}ste tidigare ha specificerats via programmet SPEC.  P} grundval
av denna specifikation promptas man sedan att f`r varje f{lt ange
startposition och f{ltl{ngd.
.SKIP
N{r man specificerat alla f{lten s{tter programmet ig}ng att
ladda alla poster.  F`r var 20:e ges en utskrift p} terminalen.
N{r alla {r laddade skrivs totala antalet, sedan upprepas fr}gan
om indatafil.  Om man vill sluta svarar man med return.
.nofill
.SKIP
EXEMPEL:
=======
.fill
.SKIP
Antag att f{lten i posten FIRMA i exemplet
ovan i st{llet ligger kolumnbundet i kolumnerna
1,25,40 och 50. D} kan man ladda med LOAD via f`ljande dialog:
.SKIP
.nofill
Give name of data base file: data.bas
image size: 98
Input file: data.dat
image size: 60
Record type: FIRMA
Give startpos and length for the following fields:
NAMN 1,24
BRANSCH 25,15
ANTALANST 40,10
PROD 50,10
.SKIP
OK, loading started
.PAGE
.nofill
.skip 2
 3.  Sammanl{nkning av poster till set.
     =================================
.SKIP
Vid uppr{ttande av set m}ste man f`rst
deklarera sina set via kommandot .DEFINE:
.SKIP
  .DEFINE,setname,ownertype,membertype
.SKIP
H{r {r
.SKIP
setname   = setets namn
ownertype = typ f`r {garposten
membertype= typ f`r medlemsposterna.
.fill
.SKIP
Tills vidare g{ller begr{nsningen att man med FETCH inte kan
hantera set som har mer {n en typ av medlemsposter.
.SKIP
D{refter kan man anv{nda kommandot .INSERT f`r att s{tta in
poster i ett set:
.nofill
.SKIP
  .INSERT,setname,owner,member1,member2, ...
.SKIP
H{r {r  setname=setets namn (tidigare definierat med .DEFINE)
          owner=nyckel f`r {garposten
          member1, member2  etc= nycklar f`r medlemsposterna.
.skip 2
Det finns ocks} omv{ndningen till INSERT, n{mligen
.skip
_.REMOVE,setname,owner,member1,member2, ...
.skip
f`r att ta bort medlemmar ur en setf`rekomst med angiven
typ och {gare.
.skip
.fill
Om man vill lista vilka SET-typer som finns definierade i
databasen kan man helt enkel s`ka p} post-typen SETSPEC.  F`r
varje .DEFINE-kommando sparas n{mligen en post av denna typ i
databasen inneh}llande f`ljande f{lt:
.SKIP
.nofill
  namn    postens namn (och nyckel f`r posten)
  owner   setets {garposttyp
  members setets medlemsposttyper
.fill
.skip
Set kan representeras internt p} endera av tv} s{tt:
.skip
(a)##Via s{rskilda poster av typen STRUKTUR, det skapas d}
en s}dan f`r varje post som ing}r i n}got set.
.skip
(b)##I f{lt som finns definierade inom respektive posttyper och
som har samma namn som ifr}gavarande set. Dessa f{lt kommer
d} att utnyttjas av SIMDBM f`r lagring av strukturinformation.
Anv{ndaren b`r aldrig sj{lv explicit {ndra i dessa f{lt.
.skip
Vilken representationsform man f}r avg`rs n{r databasen
specificeras via programmet SPEC. Antingen definierar man
extra textf{lt med samma namn som de tillt{nkta set-typerna,
eller ocks} reserverar man en tillr{ckligt stor area f`r
posttypen STRUKTUR. Sedan skall man inte beh`va m{rka vilken
form som anv{nts, utom m`jligen p} prestanda. Representationen
med STRUKTUR-poster blir ju mera ineffektiv och utrymmeskr{vande,
men ger } andra sidan mera flexibilitet.
.skip
Observera dock att DELETE-kommandot (f`r borttagande av poster,
se n{sta kapitel) fungerar olika beroende p} hur seten representeras:
om STRUKTUR-poster anv{nts inneb{r DELETE en automatisk REMOVE ur
alla set d{r posten ing}r, vid representation med vanliga f{lt
g`rs ingen s}dan REMOVE utan anv{ndaren f`ruts{tts g`ra den sj{lv.
.PAGE
.skip 2
.nofill
4.  Uts`kning av enskilda poster.
    =============================
.SKIP
.fill
Man b`r alltid inleda med kommandot .TYPE,rname f`r att ange
vilken typ av poster man vill komma }t.  (Det {r bara vissa
kommandon som kr{ver denna information, och d} dessa ges utan att
avsedd posttyp specificerats, f}r man en p}minnelse att anv{nda
_.TYPE-kommandot.)
.SKIP
D} man promptas med _> kan man direkt ange nyckel f`r n}gon post
av aktuell typ.
Om posten inte finns i databasen f}r man besked om det, annars
f}r man fr}gan "term:".  H{r kan man antingen svara med en punkt
varvid samtliga dataf{lt f`r posten listas, eller med ett namn p}
ett dataf{lt vars v{rde d} skrivs ut ensamt.
Om man svarar med return }terf`rs kontrollen till n{rmast h`gre
niv}, dvs man promptas }ter med _> och kan ge antingen ett
kommando inlett med punkt, eller nyckeln f`r en ny post av
aktuell typ.
Om man vid promptande _> svarar med .exit avslutas exekveringen av
FETCH.
.SKIP
Det finns ocks} m`jlighet att vid fr}gan "term:" {ndra enskilda
dataf{lt genom att svara termname=newvalue, d{r termname {r
namnet p} ett dataf{lt och newvalue dess nya v{rde.
.SKIP
Om man f`r en viss posttyp vill veta vilka dataf{lt som ing}r i
den, kan man anv{nda kommandot:
.SKIP
 .fields,recordtype
.SKIP
eller man kan vid fr}gan "term:" svara med ett fr}getecken,
varvid man f}r utskrivet dataf{ltens namn inom aktuell posttyp.
.skip
Enstaka poster kan tas bort genom kommandot
.skip
_.DELETE,key1,key2, ...
.skip
Observera att innan man g`r DELETE p} poster som ing}r i set
m}ste man ta bort dem ur dessa (se kommandot REMOVE i avsnitt 3).
.PAGE
.nofill
5.  S`kning genom booleska villkor.
    ==============================
.SKIP
.fill
Vid promptning med _> kan man svara med kommandona .AND eller .OR.
Detta medf`r att man blir promptad med * och f`rv{ntas mata in
villkor av formen:
.SKIP
fieldname op value
.SKIP
d{r fieldname {r namnet p} ett dataf{lt inom aktuell posttyp op
{r endera = /= _< _> _<= eller _>= och value {r ett v{rde av den typ
som dataf{ltet har.  Man kan ocks} ange villkor p} de dataf{lt
som h`r till {garposter i de set d{r aktuell post {r medlem.
FIELDNAME skall d} ha formen:
.SKIP
:SETNAME.FIELDNAME
.SKIP
d{r SETNAME {r namnet p} det set som avses och FIELDNAME {r ett
f{ltnamn giltigt f`r {garposttypen.
.SKIP
Varje villkor avslutas med return, och f`ljden av villkor
avslutas med return direkt efter den promptande asterisken.
.SKIP
Om man tidigare givit kommandot .INVERT, skrivs inga poster ut
direkt, utan man f}r efter avslutad s`kning ett besked om hur
m}nga poster som uppfyllde villkoren.  D{refter kan man v{lja att
antingen skriva ut dem direkt p} terminalen, eller att spara dem
som en inverterad fil (se vidare avsnitt 7).  Villkorssekvenser
enligt ovan kan ocks} anv{ndas n{r man s`ker via relationer (set)
enligt avsnitt 6.
.SKIP
_.AND och .OR kan ocks} n{stas p} flera niv}er genom att man i
st{llet f`r ett enskilt villkor svarar med endera .AND eller .OR
och sedan ger en subsekvens av villkor.  Varje s}dan inre sekvens
m}ste avslutas med ett eget return.
.SKIP
Dessa kommandon kan ha ytterligare tv} parametrar, som kan anges
oberoende av varandra.  Man kan skriva t ex:
.SKIP
.nofill
_.and,FILENAME,SETNAME
.SKIP
FILENAME  {r normalt namnet p} den fil d{r utdata
          skall l{ggas. Detta f`ruts{tter att utdata
          tidigare beskrivits via kommandot .TABLE.
          Om filnamnet s{tts till SYSOUT kommer
          utmatningen {nd} p} terminalen, men i det format
          som angivits via .TABLE.
          Eller, om danna parameter {r str{ngen "NAMES"
          skrivs enbart nycklarna f`r funna poster ut.
.SKIP
SETNAME   anges om man vill st{lla s`kvillkor f`r
          en viss posttyp, men vid tr{ff ta ut data
          f`r postens {gare i set med angivet namn.
.PAGE
EXEMPEL I:
----------
.SKIP
.fill
Antag att vi har en databas med f`ljande posttyper och f{ltnamn:
.nofill
.SKIP
    STAD(NAMN,INV$NARANTAL)
    FIRMA(NAMN,ANTALANST_#LLDA,BRANSCH)
    PERSON(NAMN,$LDER,YRKE,L@N)
    L_#N(NAMN,INV$NARANTAL,BOKSTAV)
.SKIP
Antag vidare att vi har relationerna:
.SKIP
.SKIP
           LOK             ANST             F@DD
    STAD --------_> FIRMA --------_> PERSON _<-------- L_#N
.SKIP
.SKIP
Givet dessa poster och strukturer kan vi med FETCH direkt
genomf`ra f`ljande uttag:
.SKIP
Personer {ldre {n 40 }r med l`n mindre {n 5000
och anst{llda i f`retag i textilbranschen.
.SKIP
.type,PERSON
_.AND
*$LDER_>40
*L@N_<5000
*:ANST.BRANSCH=TEXTIL
*
.SKIP
Ett alternativt och kanske effektivare s{tt att g`ra detta uttag
redovisas i n{sta avsnitt.
.SKIP
EXEMPEL II:
----------
.fill
.SKIP
St{der d{r det finns f`retag med mer {n 1000 anst{llda.  Detta
uttag kan g`ras med ett enda .AND-kommando, men man f}r us
st{derna en g}ng f`r varje s}dant f`retag som finns i dem.
.nofill
.SKIP
_>.type,FIRMA
_>.and,,LOK
*ANTALANST_#LLDA _> 1000
*
.SKIP
Om man inte vill ha ut alla data f`r funna st{der, utan bara
namnen kan man i st{llet skriva .AND,NAMES,LOK.
.PAGE
.nofill
6.  S`kning via relationer mellan data.
    ==================================
.SKIP
.fill
Kommandot .SELECT medf`r att man fr}gas vilket set som s`kningen
avser, vilka villkor som {garposterna skall uppfylla, och sedan
}ter vilket set som skall vara n{sta steg i s`kningen.
.skip
P} fr}gan SET: kan man antingen svara med enbart namn p} det
set som skall f`ljas. S`kningen p}b`rjas d} med en genomg}ng av
alla poster av den typ som {r {gare i detta set. Eller
ocks} svarar man med ##SETNAME,RECORDNAME, varvid endast den angivna
postens set g}s igenom. S`kningen forts{tter sedan med de poster
som {r medlemmar i angivet set.
.skip
Man kan  avbryta s`kningen genom att svara .TYPE ,
_.INDEX (eller return om man vill avbryta utan datauttag).  D}
fr}gas man efter villkor p} de funna medlemmarna
p} den l{gsta niv}n, , vilket ges som
booleska and-villkor enligt avsnitt 5.
Vid .TYPE skrivs funna poster ut direkt, vid .INDEX f}r man f`rst
ett meddelande om antalet funna poster.
Sedan st{lls fr}gan "Next action:" som beskrivs i n{sta avsnitt.
.SKIP
_.SELECT kan ha en eller tv} parametrar FILENAME och SETNAME
precis analogt med .AND och .OR enligt beskrivningen i avsnitt 5
ovan.
.skip
Om man trasslar in sig ett stycke ned i specifikationen av
en SELECT-operation kan man svara med tv} punkter f`r att komma
tillbaka till kommandoniv}n. (detta g{ller f`r `vrigt i alla
l{gen inom FETCH.)
.SKIP
.nofill
EXEMPEL:
-------
.fill
.SKIP
Det uttag som beskrivits i exemplet i avsnitt 5
kan ocks} g`ras med hj{lp av .SELECT. Den prim{ra s`kningen
g`rs h{r `ver posttypen FIRMA men uttaget avser personer.
.SKIP
.nofill
_.select
SET: ANST
Conditions:
*BRANSCH=TEXTIL
*
SET: .TYPE
Final conditions:
*AGE_>40
*INKOMST_<5000
*
.PAGE
Ett mera komplext uttag ocks} ifr}n den databas
som skisserats i avsnitt 5 {r f`ljande:
.SKIP
Personer f`dda i U-l{n med mera an 6000
i l`n, och som arbetar i f`retag som har
f`ljande egenskaper:
Mera {n 2000 anst{llda.
Ligger i st{der med mera an 150 000 inv}nare.
.SKIP
_.type,STAD
_.select
Set: LOK
Conditions:
*INV$NARANTAL_>150000
*
Set: ANST
Conditions:
*ANTALANST_>2000
*
Set: .TYPE
Final conditions:
*L@N_>6000
*:F@DD.BOKSTAV=U
*
.skip 2
.fill
Det finns ocks} ett par enkla kommandon f`r att komma }t
medlemmar respektive {gare i ett visst set.
.SKIP
_.set,setname,ownername[,filename]
.SKIP
kan anv{ndas om man vill lista alla medlemmar i den f`rekomst av
setet setname vars {gare {r ownername.  Filename kan anges
antingen om man tidigare via ett .TABLE-kommando specificerat
formatet f`r en utadatafil, eller om man h{r ger exakt str{ngen
"NAMES" f`r att markera att man bara vill ha ut nycklarna f`r
funna poster.
.SKIP
_.owner,setname,membername[,filename]
.SKIP
{r analogt med .SET, men h{r skrivs i st{llet {garen ut om man
anger n}gon av medlemmarna.
.PAGE
.nofill
7.  Skapande av inverterade filer.
    =============================
.SKIP
.fill
Vid s`kning via booleska villkor f}r man tr{ff p} ett antal
poster, och dessa skrivs normalt ut direkt p} terminalen.  Genom
kommandot .INVERT kan man i st{llet f} pekare till dem
ackumulerade och vid avslutad s`kning f} ett besked om antalet
tr{ffar.  D{refter kan man v{lja att skriva ut dem direkt, eller
att spara dem i en indexpost i databasen.
Kommandot .TTY kan anv{ndas f`r att upph{va verkan av ett
tidigare .INVERT.
P} fr}gan "Next action:" kan man svara antingen .DISPLAY, .NAMES,
_.EXIT eller .INDEX,indexname.  Vid .DISPLAY skrivs alla data f`r
posterna ut direkt p} terminalen.  Vid .NAMES skrivs enbart deras
namn, och .INDEX,indexname medf`r att pekarna till posterna
sparas i en indexpost med angivet namn.  .EXIT svarar man om man
vill ge upp s`kningen utan speciell }tg{rd.
.SKIP
Tidigare skapade indexposter kan aktiveras genom att man vid
promtning med _> ger kommandot .INDEX,indexname.  Efterf`ljande
s`kningar med .AND eller .OR kommer sedan att g`ras med
utg}ngspunkt fr}n posterna i denna indexpost.
.SKIP
Kommandot .DISPLAY,indexname[,filename] kan anv{ndas f`r att f}
en utskrift av alla poster i en viss indexpost.
.SKIP
Ett liknande kommando {r .SET,setname,owner[,filename] som ger en
lista av alla posterna i ett visst set.
.SKIP
En inventering av de inverterade filer man har g`rs genom att
lista poster av typen INDEXFILE.
En inverterad fil {r n{mligen ingenting annat {n en post av denna
typ och har f`ljande dataf{lt:
.SKIP
.nofill
    namn    text        postens nyckel
    antal   integer     antal poster i m{ngden
    typ     text        posttypen f`r posterna
    conds   text        villkorssekvensen som genererade m{ngden
    remark  text        kommenterande text
    index   text        pekare till posterna
.fill
.SKIP
En specifikation f`r denna posttyp (liksom f`r posttypen setspec
som omn{mnts i avsnitt 3) skapas av SPEC f`rsta g}ngen programmet
appliceras p} en viss databasfil.
.SKIP
Detta slags poster skapas av FETCH, men kan i `vrigt behandlas
som vanliga poster via alla normala kommandon.
.PAGE
.skip 2
Det finns ocks} ett kommando f`r att parvis kombinera
indexposter:
.SKIP
_.APPEND,NYREG,REG1,REG2[,INTERSECTION]
.SKIP
Detta kommando skapar fr}n de existerande posterna REG1 och REG2
en ny som inneh}ller f`reningsm{ngden, eller, om den fj{rde
parametern satts, sk{rningsm{ngden.
.skip
Om fj{rde parametern b`rjar med N (som i NOT) erh}lles sk{rnigsm{ngden
mellan REG1 och komplementet till REG2, dvs de poster som ing}r
i REG1 men icke ing}r i REG2. Alla `vriga str{ngar som fj{rde parameter
ger de poster som ing}r i b}de REG1 och REG2.
.SKIP
En godtycklig m{ngd av poster kan ocks} sammanf`ras till en
indexpost genom kommandot:
.SKIP
_.MAKEINDEX,INAME
.SKIP
INAME {r h{r namnet p} det uppr{ttade registret.  Anv{ndaren
promptas med fr}gan KEYS:  att ange nycklar f`r de poster som
skall ing}.
.SKIP
.nofill
Exempel:
-------
.SKIP
.fill
I den databas som specificerats i exemplet i avsnitt 5 vill man
ha direkt tillg}ng till f`ljande m{ngder av f`retag:
.SKIP
.nofill
    (a)  inom textil-branschen
    (b)  inom livsmedelsbranschen
    (c)  med mer {n 300 anst{llda
    (d)  inom textilbranschen och med mer {n 300 anst{llda
.SKIP
Dessa m{ngder kan skapas enligt f`ljande:
.SKIP
.type,FIRMA
_.invert
_.and
*BRANSCH=TEXTIL
*
Nr of hits = 33
Next action: .index,TEXTIL
_>.and
*BRANSCH=LIVS
*
Nr of hits = 55
Next action: .index,LIVS
_>.and
*ANTALANST_>300
*
Nr of hits = 77
Next action: .index,FGT300
_.append,TEXGT300,TEXTIL,FGT300,intersection
.SKIP
Om man vid ett senare tillf{lle vill g`ra en viss
uts`kning f`r f`retag inom textil-branschen, f}r
man f`rst ge kommandot:
.SKIP
_.index,TEXTIL
.fill
.SKIP
Efterf`ljande .AND eller .OR-operation kommer d} att
medf`ra en s`kning `ver enbart dessa 33 f`retag.
.skip
Observera att indexposter bara }terspeglar databasens tillst}nd vid det
tillf{lle d} de skapades. Om man efter det tillfogar poster eller
uppdaterar poster, s} kanske dessa borde ing} i n}gra av de m{ngder som
definieras av indexposter. N}gon automatisk uppdatering av dessa g`rs dock
inte av FETCH. F`r att i n}gon m}n underl{tta f`r anv{ndaren att h}lla
indexposterna aktuella finns i dessa f{lten CONDS och REMARK (se ovan).
Om man s}ledes vill s{kerst{lla att indexposterna definierar aktuella
m{ngder, s} f}r man helt enkelt ta bort de gamla och skapa helt nya genom
att upprepa samma s`kning.
.PAGE
.nofill
8.  @versikt `ver tillg{ngliga kommandon.
    =====================================
.SKIP
.fill
Alla kommandon har ber`rts i n}got av f`reg}ende avsnitt.
H{r ges bara en kort sammanst{llning i alfabetisk ordning.
.SKIP
.nofill
_.and[,filename,setname]
.SKIP
        inleder inmatning av and-f`rknippade villkor
        Filename kan anges om .TABLE anv{nts tidigare f`r att
        specificera utseendet p} en tabell som skall matas
        ut p} en fil. Om filename {r "SYSOUT" g`rs
        utmatning p} terminalen, annars tolkas filename som
        namn p} en extern fil. Om filename {r str{ngen
        "NAMES" tolkas det dock inte som filnamn,
        utan anger att endast namnen skall skrivas ut f`r
        de poster som hittas.
        Om parametern setname angivits, kommer f`r varje
        post som hittas data f`r postens {gare
        inom angivet set att skrivas ut.
.SKIP
_.append,nyreg,reg1,reg2[,intersection]
.SKIP
        sl}r ihop tv} indexposter till en ny genom att
        bilda endera f`reningsm{ngden eller sk{rningsm{ngden
        av de ing}ende posterna.
.SKIP
_.define,setname,ownertype,membertype[,remark]
.SKIP
        definition av ett set innan det anv{nds
        i endera .INSERT, .SELECT eller .SET. Specifikationen
        l{ggs upp som en post i databasen och blir tillg{nglig
        vid senare k`rtillf{llen. SETSPEC kallas den posttyp som
        representerar detta slags specifikationer, REMARK {r en
        f`rklarande text som man kan ange om man vill.
.SKIP
_.delete,r1,r2,r3,r4, ...
.SKIP
        Uppr{knade poster tas bort ur databasen. Deras
        typ f`ruts{ttes given genom senast givna .TYPE-kommando.
        Innan de tas bort m}ste de plockas ur alla set
        d{r de ing}r som medlemmar eller {gare.
        Detta g`rs automatiskt av FETCH bara under vissa
        f`ruts{ttningar (se avsnitt 3).
.SKIP
_.display,indexname[,filename]
.SKIP
        lista posterna som refereras i en viss indexpost.
        Parametern filename har samma inneb`rd
        som f`r .AND-kommandot.
.page
_.exit
.SKIP
        avsluta exekveringen av FETCH, st{ng databasen
.skip
_.fields,recordtype
.SKIP
        lista dataf{ltnamn och typer f`r en viss posttyp.
.SKIP
_.index,indexname
.SKIP
        aktivera indexpost med angivet namn f`r f`rnyad
        s`kning med .AND eller .OR
.SKIP
_.insert,setname,owner,member1,member2, ...
.SKIP
        tillfoga medlemmar i ett set.
.SKIP
_.invert
.SKIP
        s`kning avser uppbyggande av inverterade filer,
        dvs data f`r funna poster skall inte skrivas ut
        direkt p} terminalen.
.SKIP
_.makeindex,iname
.SKIP
        skapa ett INDEXFILE-objekt genom direkt uppr{kning
        av ing}ende poster. Anv{ndaren promtas med KEYS:  att
        ange nycklarna.
.SKIP
_.or[,filename,setname]
.SKIP
        inleder or-f`rknippade villkor.
        Parametrarna filename och setname har samma inneb`rd
        som f`r .AND-kommandot.
.SKIP
_.owner,setname,member[,filename]
.SKIP
        skriv ut {garen i det set setname d{r member ing}r
        som medlem, antingen alla data eller bara namnet.
        Parametern filename har samma inneb`rd
        som f`r .AND-kommandot.
.SKIP
_.remove,setname,r1,r2,r3,r4,r5, ...
.SKIP
        Om de uppr{knade posterna ing}r i
        n}got set av typen 'setname' tas de bort ur det.
.page
_.select[,filename,setname]
.SKIP
        s`kning via ett set inleds. Anv{ndaren promptas
        p} varje niv} att ange setnamn och selekteringsvillkor.
        Parametrarna filename och setname har samma inneb`rd
        som f`r .AND-kommandot.
.skip
_.set,setname,owner[,filename]
.SKIP
        lista alla medlemmar i ett set.
        Parametern filename har samma inneb`rd
        som f`r .AND-kommandot.
.SKIP
_.store[,recordtype]
.SKIP
        lagra en post av angiven typ i databasen.
        Anv{ndaren promptas med f{ltnamnen att mata
        in alla f{lten. Om recordtype utel{mnas anses
        det vara den posttyp som angivits via senaste
        .TYPE-kommando.
.SKIP
_.table,[name,store,overwrite]
.SKIP
        Vid s`kning med .AND , .OR, .SELECT, .DISPLAY
        eller .SET, skriv ut resultatet p} en fil .
        Filnamnet anges i varje s{rskilt
        fall som extra parameter till dessa kommandon.
        Om man inte ger n}gon parameter blir specifikationen
        tempor{r dvs den g{ller forts{ttningsvis i denna k`rning
        men kommer inte att lagras i databasen. Om man enbart
        anger  .TABLE,NAME s} anses en tabell med detta namn
        finnas tidigare lagrad i databasen.  I `vriga fall skall
        en ny tabell specificeras och lagras i databasen.
        Man promptas med f`ljande fr}gor:
.SKIP
        FIELDS:     ange f{ltnamn som skall ing} i tabellen
        COLUMNS:    ange kolumner d{r dessa f{lt skall matas ut
        SUMS:       ange vilka numeriska f{lt som skall summeras
        REMARK:     f`rklarande kommentar
.SKIP
        Antal kolumner skall vara antalet f{lt+1 d{r sista talet
        anger radl{ngden f`r den fil d{r resultatet skall l{ggas.
        SUMS beh`ver inte anges (svara return), och f`r de f{lt
        i listan FIELDS som inte skall summeras anger man i
        motsvarande position n}got odefinierat namn
        t ex X (se exemplet nedan).
        Summan skrivs ut som en extra rad i slutet av filen i
        samma kolumner som angivits i COLUMNS.
.SKIP
        Numeriska f{lt blir h`gerjusterade, textf{lt
        v{nsterjusterade. D{rf`r kan det ibland vara `nskv{rt
        att l{gga in blanka f{lt emellan f`r att f}
        l{sliga tabeller.
        Detta g`rs genom att i listan FIELDS: ge blanka f{ltnamn.
.SKIP
        De f{ltnamn som anges som svar p} FIELDS: skall normalt
        vara giltiga f`r aktuell posttyp (dvs den som angetts
        via .TYPE). Dock finns det ett s{tt att byta kontext
        och ta fram data {ven f`r {garposten till aktuell post.
        Man anger SET-namn i st{llet f`r f{ltnamn och s{tter
        motsvarande position i COLUMNS=-1. D} kommer
        efterf`ljande f{lt att tas ifr}n {garen i angivet set.
        Fr}n denna kan man sedan vandra iv{g p} samma s{tt
        via n}got SET d{r denna {r medlem osv. Tyv{rr finns
        det f n inte n}got s{tt att komma tillbaka till den
        ursprungliga kontexten, vilket medf`r att man
        bara kan f`lja n{tverket i en enda riktning,
        och att data f`r 'sekund{ra poster' alltid m}ste l{ggas
        sist i tabellen.
.SKIP
        Observera att en tidigare lagrad tabellspecifikation kan
        aktualiseras genom kommandot  .TABLE,NAMN . D{rvid
        g`rs en verifierande utskrift av den p} terminalen.
        Ett antal olika tabellspecifikationer kan vara lagrade
        i databasen samtidigt. De representeras som poster av
        typ TABLE, och kan s}ledes modifieras och listas p}
        vanligt s{tt.
.SKIP
        EXEMPEL:  Skriv ut f{lten NAMN,AGE,LENGTH och WEIGHT i
        kolumnerna 1,20,25 och 30, samt summera AGE och WEIGHT
        och skriv summan i motsv kolumner. Spara specifikationen
        i databasen under namnet TAB1.
        Utskrift skall sedan g`ras f`r alla personer med
        inkomst _> 50000 och }lder _> 30 p} filen PERS1.DAT.
.SKIP
        _>.table,TAB1,STORE
        FIELDS: NAMN,AGE,LENGTH,WEIGHT
        COLUMNS: 1,20,25,30,40
        SUMS: X,AGE,X,WEIGHT
.SKIP
        _>.and,PERS1.DAT
        *INCOME _> 50000
        *AGE _> 30
        *
.SKIP
_.tty
.SKIP
        upph{ver tidigare .invert, dvs funna poster
        skall skrivas ut direkt p} terminalen.
.SKIP
_.type,recordtype
.SKIP
        Anger aktuell post-typ (Denna beh`ver vara k{nd vid
        direkt uts`kning via postnyckel, samt vid s`kning `ver
        hela areor via .AND och .OR-kommandona).
.nofill
.PAGE
9.  Beskrivning av programmet SPEC.
    ===============================
.fill
.SKIP
.fill
SPEC {r ett program f`r att interaktivt initiera en databasfil
genom att l{gga upp en dataspecifikation enligt
SIMDBM-konventioner.
Man anger namn p} de posttyper man vill ha, samt namn och typ
f`r varje dataf{lt i posten.
Det finns sex typer:  INTEGER,
REAL, TEXT samt arrayer av dessa typer.
.SKIP
SPEC l{gger ocks} ut fem stycken systemdefinierade posttyper:
RSPEC, STRUKTUR, SETSPEC, INDEXFILE och TABLE.
RSPEC {r den posttyp som representerar post-specifikationer, och
m}ste alltid finnas med. STRUKTUR och SETSPEC beh`vs bara om databasen
skall inneh}lla set-f`rekomster. INDEXFILE och TABLE anv{nds i en del
fall av programmet FETCH f`r att spara viss styrinformation.
.SKIP
Dialogen med SPEC inleds med ett par fr}gor fr}n programmet:
.SKIP
Name of data base file:
.SKIP
Svara med namn + extension.  Default {r x.tmp.
.SKIP
Image size:
.SKIP
Svara med trolig genomsnittlig postl{ngd, dock icke mindre {n 40.
Default {r 68, vilket medf`r att filen i sin r}a form kan listas
p} de flesta terminaler i relativt l{sbar form (t ex med
programmet DIRED).
.SKIP
Om databasen uppr{ttas f`rsta g}ngen f}r man sedan fr}gorna:
.SKIP
Delimiters:
.SKIP
H{r skall man ge ASCII-koderna (decimalt) f`r de tv} tecken som
anv{nds som delimiters internt i databasen.  Default {r 92 och 93
som svarar mot tecknen _\ och ].  Dessa tecken kan s}ledes inte
ing} i de texter som lagras i databasen.  De {r valda f`r att
under uttestning {nd} f} tryckbara tecken i den interna
representationen.  I mera produktionsinriktade databaser b`r man
i st{llet v{lja ett par otryckbara specialtecken.
.SKIP
System area sizes:
.SKIP
H{r skall man svara med svarar med fem heltal }tskilda av komman.
Defaultv{rden f`r dessa {r   20,10,10,10,10.
.SKIP
Siffrorna avser i n{mnd ordning storleken av areorna f`r f`ljande
posttyper:
.page
.nofill
  RSPEC     postspecifikationer
  STRUKTUR  separata poster f`r set-representation
  SETSPEC   poster f`r beskrivning av set-typer
  INDEXFILE indexposter
  TABLE     tabellspecifikationer
.SKIP
.SKIP
I det f`ljande styrs SPEC via ett enkelt kommandospr}k d{r
f`ljande 11 kommandon finns f`r att specificera olika egenskaper
f`r en post:  (TYPE st}r f`r sex olika datatyper)
.SKIP
NAME,postnamn              posttypens namn
KEY,fieldname              namn p} det f{lt som {r nyckel
SIZE,nn                    ungef{rligt antal poster f`r posttypen
TYPE,field1,field2, ...    typdeklaration f`r angivna f{lt
RECORD                     markering att en posttyp {r klar
EXIT                       normal utg}ng ur pogrammet SPEC
.SKIP
Kommandona har s}ledes noll, en eller flera parametrar }tskilda
fr}n varandra med kommatecken.  Inga extra blanka f}r f`rekomma i
kommandostr{ngarna.  TYPE kan vara endera
INTEGER,REAL,TEXT,INTEGER ARRAY,REAL ARRAY eller TEXT ARRAY
(eller f`rkortat I,R,T,IA,RA,TA).
_#ven `vriga kommandoord kan f`rkortas, n{mligen till N,K,S,REC
och EX.
.SKIP
Om man i st{llet f`r kommando svarar med ett fr}getecken, f}r man
p} sin terminal en kort redog`relse f`r tillg{ngliga kommandon i
SPEC.
.SKIP
Observera att f`r varje posttyp m}ste alltid NAME,KEY och SIZE
anges.  Skulle man gl`mma n}got av dem fr}gar SPEC efter
komplettering n{r man ger kommandot RECORD.  F`rst d{refter
lagras specifikationen i databasen.
.skip
EXEMPEL:
=======
.SKIP
Antag att en databas med tv} posttyper PERSON och FIRMA skall
definieras, med f`ljande f{lt:
.SKIP
PERSON(NAMN,$LDER,PA,TEL)
FIRMA(NAMN,PA,ANTALANST)
.SKIP
$LDER och ANTALANST skall vara heltal, de `vriga f{lten texter.
Dialogen med SPEC f`r detta skulle bli s}h{r:
.SKIP
Give name of data base file: PERS.DAT
Image size: 68
Delimiters /92,93/:
System area sizes /20,10,10,10,10/:
*NAME,PERSON
*TEXT,NAMN
*INTEGER,$LDER
*TEXT,PA,TEL
*KEY,NAMN
*RECORD
Record ok, Give new specification or EX to finish.
*NAME,FIRMA
*TEXT,NAMN,PA
*REAL,ANTALANST
*KEY,NAMN
*SIZE,50
*RECORD
Record OK, Give new specification or EX to finish.
*EXIT
.SKIP
SPEC kan ocks} anv{ndas f`r att komplettera eller {ndra post-
beskrivningarna i en befintlig databas.  D{rvid f}r inte SIZE och
KEY-kommandona anv{ndas p} f`rut befintliga poster.  Det enda man
g`r {r att f`rst med NAME-kommandot ange namnet p} den posttyp
man vill {ndra och sedan med TYPE-kommandon endera specificera
nya f{lt, eller omdefiniera typen p} befintliga f{lt.  N{r detta
{r klart lagrar man den {ndrade postspecifikationen via kommandot
RECORD.
.SKIP
Helt nya posttyper kan ocks} definieras och inf`ras i en
befintlig databas.  D{rvid st{lls inga fr}gor om Delimiters och
System area sizes.  I st{llet f}r man fr}gan:
.SKIP
Is an old file to be updated?
.SKIP
Exempel:
--------
.SKIP
I databasen i exemplet ovan skall f`r posttypen PERSON tv} nya
f{lt INKOMST och YRKE inf`ras.  Vidare skall f`r posttypen FIRMA
f{ltet ANTALANST {ndras tilltyp INTEGER.  Slutligen skall en helt
.SKIP
ny posttyp STAD(NAMN,INV,L_#N) inf`ras.
.SKIP
Detta genomf`res genom f`ljande dialog med SPEC:
.SKIP
Name of data base file: PERS.DAT
Image size: 68
Is an old file to be edited ? YES
*NAMN,PERSON
*INTEGER,INKOMST
*TEXT,YRKE
*REC
Record OK, Give new specification or EX to finish.
*NAMN,FIRMA
*INTEGER,ANTALANST
*REC
Record OK, Give new specification or EX to finish.
*NAMN,STAD
*TEXT,NAMN
*INTEGER,INV
*TEXT,L_#N
*KEY,NAMN
*SIZE,300
*REC
Record OK, Give new specification or EX to finish.
*EX