8.8. Zpracování relativního souboru Charakteristika relativního souboru Relativní soubor je asi nejlepší představit si jako posloupnost (poměrně dosti dlouhou) paměťových míst, dalo by se říci dokonce zásuvek, šuplíků, rámečků nebo i přihrádek na logické věty relativního souboru. Všechna tato paměťová místa jsou stejně dlouhá bez ohledu na to, zda logické věty mají pevnou nebo proměnnou délku. Vždy jsou ovšem veliká tak, aby do jednoho každého z nich bylo možno zapsat i tu nejdelší logickou větu, která je pro daný soubor ještě přípustná. (tedy pozor u proměnné délky vět, kde může dojít k neúměrnému plýtvání prostorem, když jsou mezi délkami vět značné rozdíly a věty s největší délkou se vyskytují jen zřídka). Dále je zapotřebí sdělit, že tato paměťová místa jsou pěkně popořadě očíslována počínaje nulou a dále po jedné. Každé z paměťových míst rezervovaných pro logické věty je buď obsazeno nějakou logickou větou nebo je prázdné, věta v něm není. To že paměťové místo je prázdné je poznačeno tak, že prvních 512 bytů věty (u kratších vět věta celá) je obsazeno binárními nulami. Logická věta relativního souboru tedy nesmí v prvních 512 bytech obsahovat samé binární nuly. Relativní soubor lze zpracovávat sekvenčně nebo přímo. Při přímém zpracování se používá relativní klíč, což je pořadové číslo paměťové oblasti s jejímž obsahem se má pracovat. 8.8.1. Vytvoření relativního souboru U relativního souboru se dá říci, že při vůbec prvním pokusu o práci s ním si lze představit, že všechna paměťová místa pro logické věty jsou prázdná, připravena pro zápis logických vět. Z tohoto hlediska je každý relativní soubor a priori vytvořen, byť v něm zatím není žádná logická věta. Logické věty lze do souboru zapisovat buď v rámci sekvenčního zpracování nebo při přímém přístupu. 8.8.2 Sekvenční zpracování relativního souboru A) Sekvenční psaní Při sekvenčním psaní se postupuje obdobně jako při vytváření sekvenčního souboru. Začne se s první větou v paměťovém místě s pořadovým číslem 0, pokračuje se větou v paměťovém místě s pořadovým číslem 1 atd. a to tak dlouho, dokud nedojde provedením příkazu CLOSE k ukončení zpracování. Při sekvenčním psaní jsou paměťová místa obsazována těsně jedno vedle druhého bez toho, že by se nechávalo některé paměťové místo neobsazené, prázdné. Klauzule SELECT má tvar: SELECT jméno-souboru ASSIGN systémové-jméno [ORGANIZATION RELATIVE] [RELATIVE KEY položka] V systémovém jméně musí být uvedena organizace R nebo musí být uvedena klauzule ORGANIZATION. Klauzule FD má tvar: FD jméno-souboru [RECORDING {F|V}]. Je-li uvedena klauzule RECORDING V, mohou být zapisovány věty různých délek, nicméně paměťová místa pro logické věty jsou na médiu vyhrazena vždy v maximální přípustné délce. Na začátku zpracování musí být soubor otevřen příkazem OPEN OUTPUT jméno-souboru Je-li uvedena klauzule RELATIVE KEY, bude v ní po provedení příkazu OPEN hodnota nula, znamenající pořadové číslo paměťového místa, do kterého bude zapsána logická věta nejbližším příkazem WRITE. Před zápisem logické věty musí uživatel umístit do 01 v paměti tu logickou větu, kterou chce zapsat do následujícího paměťového místa na médiu. Pořadové číslo (pokud si ji uživatel sám nepřepsal) je v RELATIVE-položce. Zápis logické věty se provede příkazem - - - - | |položka | | WRITE logická-věta | FROM | | |figurativní-konstanta| | | |ALL-klauzule | | - - - - [ INVALID KEY příkaz ... ] Je-li uvedena klauzule RELATIVE KEY, bude po provedení příkazu WRITE uloženo v RELATIVE-položce pořadové číslo paměťového místa následujícího za tím, do kterého příkaz WRITE právě zapsal logickou větu. Klauzule INVALID KEY se uplatní v případě, když logickou větu nelze na médium zapsat, protože je médium již zcela zaplněno. Po zápisu poslední logické věty je nutno soubor uzavřít příkazem CLOSE jméno-souboru B) Sekvenční čtení Klauzule SELECT má tvar SELECT jméno-souboru ASSIGN systémové-jméno [ORGANIZATION RELATIVE] [RELATIVE KEY položka] V systémovém jméně musí být uvedena organizace R nebo musí být uvedena klauzule ORGANIZATION. Klauzule FD má tvar: FD jméno-souboru [RECORDING {F|V}]. Na začátku zpracování musí být soubor otevřen příkazem OPEN {INPUT | I-O} jméno-souboru Je-li uvedena klauzule RELATIVE KEY, bude v ní po provedení příkazu OPEN hodnota nula, znamenající pořadové číslo paměťového místa, ze kterého bude čtena logická věta nejbližším příkazem READ. Volby INPUT a I-O jsou rovnocenné, při obou způsobech otevření je přípustné logické věty číst, opravovat i vyřazovat. Logickou větu z následujícího (těsně po OPEN prvního) paměťového místa přečteme z média do 01 příkazem READ jméno-souboru [INTO položka] [AT END příkaz ... ] Je-li uvedena klauzule RELATIVE KEY, bude po provedení příkazu READ uloženo v RELATIVE-položce pořadové číslo paměťového místa následujícího za tím, ze kterého příkaz READ právě přečetl logickou větu. Opravit lze pouze tu logickou větu, která byla přečtena posledním předcházejícím příkazem READ, přičemž ovšem při tomto příkazu READ nesměla nastat podmínka "konec souboru" (uplatnit se klauzule AT END). Každou přečtenou větu lze opravit i vícekrát. Uživatel tedy přečte logickou větu do 01 příkazem READ a opraví ji v paměti (tj. v 01). Opravu logické věty na médiu pak provede příkazem - - - - | |položka | | REWRITE logická-věta |FROM | | |figurativní-konstanta| | | |ALL-klauzule | | - - - - [INVALID KEY příkaz ...] Klauzule INVALID KEY se nemůže nikdy uplatnit a proto nemá smysl ji uvádět. Zrušit lze pouze tu logickou větu, která byla přečtena posledním předcházejícím příkazem READ, přičemž ovšem při tomto příkazu READ nesměla nastat podmínka "konec souboru" (uplatnit se klauzule AT END). Každou přečtenou větu lze pochopitelně zrušit pouze jednou. Zrušení věty relativního souboru vypadá tak, že se prvních 512 bytů (u kratších vět všechny byty) paměťového místa na médiu obsadí binárními nulami. Zrušení se provede příkazem DELETE jméno-souboru [INVALID KEY příkaz ... ] Klauzule INVALID KEY se nikdy neuplatní (je-li uvedena, vždy se odskočí na první příkaz za tečkou) a rovněž případná deklarativní sekce pro ošetření chyb vstupu/výstupu nebude nikdy vyvolána. Po ukončení zpracování je nutno soubor uzavřít příkazem CLOSE jméno-souboru 8.8.3 Přímé zpracování relativního souboru Klauzule SELECT má tvar SELECT jméno-souboru ASSIGN systémové-jméno [ORGANIZATION RELATIVE] ACCESS RANDOM RELATIVE KEY položka V systémovém jméně musí být uvedena organizace R nebo musí být uvedena klauzule ORGANIZATION. Klauzule FD má tvar: FD jméno-souboru [RECORDING {F|V}]. Na začátku zpracování musí být soubor otevřen příkazem OPEN {INPUT | I-O | OUTPUT} jméno-souboru Volby INPUT, I-O a OUTPUT jsou rovnocenné. Po kterémkoliv způsobu otevření lze provádět příkazy READ, WRITE, REWRITE a DELETE. Před přímým čtením logické věty musí uživatel naplnit RELATIVE-položku pořadovým číslem té logické věty, kterou chce přečíst. Logickou větu pak přečte do 01 příkazem READ jméno-souboru [INTO položka] [INVALID KEY příkaz ... ] Pokud pořadové číslo zadané v RELATIVE-položce je takové, že je buď větší než nejvyšší pořadové číslo doposud zapsaných vět nebo paměťové místo se zadaným pořadovým číslem neobsahuje platnou větu (tj. buď do něj věta ještě zapsána nebyla nebo již byla zrušena příkazem DELETE) nic se nepřečte a uplatní se klauzule INVALID KEY; při neuvedení klauzule INVALID KEY dojde k vyvolání deklarativní sekce pro ošetření chyb vstupu/výstupu (viz 5.5.2.). Ve zpracování souboru se však smí pokračovat. Opravit lze pouze tu logickou větu, která byla přečtena posledním předcházejícím příkazem READ, přičemž ovšem při tomto příkazu READ nesmělo dojít k výjimečnému stavu (uplatnění klauzule INVALID KEY resp. vyvolání deklarativní sekce). Každou přečtenou logickou větu lze opravit i vícekrát bezprostředně po sobě. Uživatel tedy přečte logickou větu do 01 příkazem READ a opraví ji v paměti (tj. v 01). Opravu logické věty v souboru dat pak provede příkazem - - - - | |položka | | REWRITE logická-věta | FROM | | |figurativní-konstanta| | | |ALL-konstanta | | - - - - [INVALID KEY příkaz ... ] Klauzule INVALID KEY se nikdy uplatnit nemůže, nemá tedy smysl ji uvádět. Zrušit lze pouze tu logickou větu, která byla přečtena posledním příkazem READ, přičemž ovšem toto čtení muselo být úspěšné. Uživatel tedy přečte logickou větu do 01 příkazem READ a zruší ji příkazem DELETE jméno-souboru [INVALID KEY příkaz ... ] Zrušení věty relativního souboru vypadá tak, že se prvních 512 bytů (u kratších vět všechny byty) paměťového místa na médiu obsadí binárními nulami. RELATIVE-položka se při rušení nepoužívá. Klauzule INVALID KEY se nikdy neuplatní (je-li uvedena, vždy se odskočí na první příkaz za tečkou) a rovněž případná deklarativní sekce pro ošetření chyb vstupu/výstupu nebude nikdy vyvolána. Před zápisem (tj. vložením) nové logické věty do souboru dat musí uživatel umístit do 01 tu logickou větu, která má být zapsána, do RELATIVE položky pak její pořadové číslo. Příkazem - - - - | |položka | | WRITE logická-věta | FROM | | |figurativní-konstanta| | | |ALL-konstanta | | - - - - [INVALID KEY příkaz ... ] se pak logická věta zapíše do zadaného paměťového místa, bez ohledu na to, zda v daném místě již nějaká logická věta leží nebo zda se do něj zapisuje poprvé, Je zcela na odpovědnosti uživatele, aby zajistil, že tímto příkazem WRITE, který se provádí v podstatě naslepo nebude omylem přepsána nějaká jinak potřebná logická věta. Klauzule INVALID KEY se uplatní v případě, jestliže zadané pořadové číslo je tak velké, že mu odpovídající paměťové místo nelze z kapacitních důvodů na médiu zřídit.