VaxNt/ProDB.PGuide.Příklady
Začneme několika příklady z praxe. Jazyk skriptů se vyvinul z původně pouze pomocného nástroje na plnohodnotný programovací jazyk. Primárně je ovšem určen k řešení jednoduchých záležitostí, jak bude vidět z následujících příkladů.
Naplánování mobilního přenosu. V jednoduchém scénáři chceme sejmout formulář (v naší terminologii wizard),
zkosntruovat pár pomocných proměnných a výsledek uložit do odpovídající databázové tabulky. Reálný skript
v ČRa je následující:
clear
set Datum,$(Today),WizCaption,Nový mobilní přenos
?wizard mobilniprenosy/form.wiz
randomize+random
set MobilId,$(DateTime)$(Random),KdoZapsal,$(User),KdyZapsal,$(DateTime),Stav,Nový,Color,Blue
insert MobPrenosy
dump mobilniprenosy_new
exit
Nyní si pěkně řádek po řádku probereme použité obraty:
Příkaz clear pro jistotu vyčistí úplně kontext volání. Kontext je jedna sada rovnic (multirovnice, TStringList). V tomto případě je příkaz nadbytečný, protože skript volaný na základní úrovní začíná s vyprázdněným kontextem. Pokud by ale tento skript byl náhodou volán jiným skriptem jako podřízený (podprogram), je použití _clear na místě, protože se jím vynulují ev. proměnné přicházející z nadřízeného skriptu. Většina skriptů začíná jedním z příkazů clear nebo _use. Příkaz _use slouží k propagování kontextu akce do proměnných skriptu. Skripty jsou totiž volány obvykle nad nějakou zobrazenou tabulkou / gridem. Přirozeným kontextem akce je pak obsah aktuálního řádku gridu - to je sada hodnot, která se pomocí _use dostane do skriptu.
Příkaz set bere jako argumenty seznam dvojic, první je vždy jméno proměnné a druhá je hodnota, kterou jí chceme dát. Jak vidno, součástí hodnoty mohou být konstanty, ale i systémové proměnné (Today,Tomorrow,...) a také i hodnoty jiných proměnných. K detailnímu popisu vyhodnocování proměnných se dostaneme v dalším. Vedle normálních proměnných existují i některé "smluvené", jejichž význam je důležitý spíše pro vzhled nebo chod akce než pro skutečné zpracování hodnot. Zde je to WizCaption, což je jméno titulku nad snímaným wizardem. To je typicky prázdné, ale je možno ho explicitně nastavit, jako se děje v našem případě. Protože jak volaný wizard převezme kompletní sadu proměnných, nastavením proměnné Datum rovnou ve wizardu přednastavíme hodnotu na nejběžnější případ, tedy dnes.
Dalším příkazem je volání wizarda. Zde má jediný parametr a sice jméno souboru, kde je definován wizard/formulář. Dalšími nepovinnými parametry by ještě mohlo být jméno proměnné, kde se má začít skenovat a ev. i mod zobrazení (přes celý desktop nebo menší, ...). Pokud je skenování hodnot operátorem ukončeno příkazem Storno, pak příkaz ?wizard rovnou ukončí interpretaci celého skriptu.
Poznámka: Jak uvidíme v dalším, wizardy mohou volat vedle interních funkcí na kontrolu dat i skripty a je tedy možné a často se to používá, že skript rozjede volaná wizarda a v něm zprostředkovaně dochází k volání jiného skriptu atd. Níže to je ilustrováno na příchodu pacienta na recepci PET centra.
Pomocí randomize+random se inicializuje generátor náhodných čísel a hnedka se jedno takové číslo vygeneruje. Dostane se do globální a po dobu běhu interpreteru stále existující proměnné Random. Náhodná čísla se generují v intervalu 0-4095 a používají se na vytváření unikátních databázových klíčů obvykle v podobě kompletního DateTime a nějakého suffixu.
Následuje zase přiřazovací příkaz set, kterým se zrovna konstruuje databázový klíč MobilId, nastavují evidenční proměnné KdoZapsal a KdyZapsal a pak ještě pár dalších.
Posléze se pomocí příkazu insert zapíše do databázové tabulky MobPrenosy. Jelikož mobilní přenosy plánuje právě jeden operátor, je vygenerovaný databázový klíč unikátní (i kdyby pracovalo více lidí, musli by v jedné vteříně vkládat mnoho záznamů, aby pravděpodobnost kolize byla nezanedbatelná). Zásadně důležité je ale to, že neuvádíme explicitně hodnoty proměnných, které chceme uložit. Ty jsou možná deklarovány ve wizardu, pokud ano, jednoduše jsme hodnoty i s jejich jmény získali voláním wizarda. Příkaz insert je implementován tak, že si sám již zjistí strukturu tabulky a sestaví vhodný "insert into MobPrenosy values ...." automaticky. Probere tedy VŠECHNY proměnné kontextu skriptu, vybere relevantní a nabídne je tabulce ke skutečné operaci insert. Pokud bychom chtěli ošetřit ev. výjimku jinak než standardním chybovým dialogem, pak bychom použili příkaz try.insert.
Příkaz dump slouží k logování událostí. V adresáři data/log se logují události ve formě textových souborů se jménem odvozeným od DateTime a parametru dump. Tyto logové soubory "požírá" noční běh daemonů na straně serveru. Typicky jsou logy ukládány na jiném diskové svazku než databáze a jsou produkovány tak, že v případě kolapsu systému je možno snadno sestavit ze souborů stejné třídy "dump" importní soubory na korekci databáze. Typicky se ale logy používají pro vzdálené monitorování systému a řešení chyb operátorů.
Příkaz exit ukončuje běh skriptu. Vedle toho je možno používat i příkaz return, kterým se ukončují podřízené skripty. Ukončí-li se podřízený skript returnem, vezmou se NEPRÁZDNÉ hodnoty jeho kontextu a propagují se do stejnojmenných proměnných volajícího skriptu. Prázdné hodnoty se ignorují. Později se k tomu dostaneme ještě detailněji. Teď sdělíme jenom tolik, že podřízený skript získává při startu automaticky kompletní kopii kontextu volajícího skriptu. Teprve při návratu se může rohodnout, jaké proměnné vlastně vrátí "o patro výše". Dobrým zvykem je pro jistotu před návratem přes return vyprázdnit hodnoty všelijakých pomocných proměnných tak, aby se zbytečně nevracely volajícímu skriptu...
Wizard z předchozího příkladu. Následuje wizard, který byl volán v předešlém příkladě. Jedná se o statickou definici formuláře a vlastností každého jeho řádku.
Datum Caption = Datum Comment = Datum přenosu Type = Calendar Definition Default = today Format = YYYYMMDD Check = !void Nazev Caption = Název Check = max(24) Zvuk Caption = Zvuk Check = upper & list(||MONO|STEREO|) KBod Caption = K-bod Check = max(40) Uzivatel Caption = Uživatel Comment = Uživatel, pro kterého se přenos uskutečňuje Type = Lookup Definition Database = DefaultVaxNtDb Key = Uzivatel Sql = select Uzivatel from MobUzivatele order by Uzivatel Fields = Uzivatel Kategorie Caption = Kategorie Comment = Kategorie Type = Lookup Definition Database = DefaultVaxNtDb Key = Kategorie Sql = select Kategorie,Popis,PoradiVMenu from Mobkategorie order by PoradiVMenu Fields = Kategorie;Popis Pasmo Caption = Pásmo Comment = Pásmo podle číselníku 1-5 Type = Lookup Definition Database = DefaultVaxNtDb Key = Pasmo Sql = select Pasmo,Popis,PoradiVMenu from MobPasma order by PoradiVMenu Fields = Pasmo;Popis PocetVozu Caption = Počet vozů Check = default(PocetVozu,1) & number(1,10) Planovano Caption = Plán Comment = Plánovaný čas přenosu ve formátu HHMM-HHMM, tedy například 1800-1935 Skutecnost Caption = Skutečnost Comment = Skutečný čas přenosu ve formátu HHMM-HHMM, tedy například 1810-1955 Trasa Caption = Trasa Comment = Trasa SpojeniPP Caption = Spojení PP Byrokracie Caption = Byrokracie Comment = Sem můžete psát běžný text popisující postup vyřízení výluky od A až do Z. Tedy položky, které databáze nemá. Všimněte si, že text se vždycky sám od sebe poznačí, kdo a kdy s ním dělal. Type = MEMO Definition WantReturns = 1 WordWrap = 1 WantTabs = 0 AutoDate = yyyymmdd hh:nn Autosign = 1 Hotovo Caption = Hotovo
Popis wizardů sleduje indentací stromovou strukturu. Na nejnižším patře jsou jména položek, jsou buď známa již volajícímu skriptu (Datum) nebo se do něj teprve dostanou po ukončení běhu wizarda. Vedle jména má položka i popisek ("lidské" jméno) - Caption a popis - Comment. Položky mohou být různých datových typů a mohou být podrobeny různým kontrolám. Reprezentativní položky si nyní rozebereme pěkně jednu po druhé.
Zobrazení textového souboru s novinkami v systému Chceme z distribuce vytáhnout nějaký soubor s popisem
nově implementovaných funkcí a zobrazit jej pomocí WordPadu. Napřed ale vytvoříme lokální kopii, aby někdo
originál nepokazil, kdyby náhodou měl právo zápisu na síťový disk...
set Par,$(Param)
cp !!$(Par)prg/jlabs/novinky.txt,c:\tmp\novinky.txt
viewer c:\tmp\novinky.txt
exit
Komentář:
První příkaz set je použit pro vyřešení technického detailu. Používáním znaku backslash ve jménech souborů totiž firma Microsoft úspěšně zadělala na nekončící problémy. Původně v unixu, ale hlavně i v C-čku je backslash určen na kódování řídících znaků. Globální proměnná Param je nastavena při startu VaxNt na domovský adresář aplikace - bude tedy určitě obsahovat backslashe v situaci, kdy VaxNt běží jako klient ve Windows. Substituce za výrazy tvaru $(X) se řídí určitými předpisy a zde si jenom pomáháme je oblafnout. Naším příkazem dostaneme do lokální proměnné skriptu Par obsah globální proměnné Param.
Pomocí příkazu cp uděláme lokální kopii souboru. Vidíme, že argument je prefixován hned dvěma vykřičníky. V dalším to bude vysvětleno detailně, tady dva vykřičníky značí pokyn, aby interpret ponechal "na pokoji" backslashe a nesnažil se jejich hodnotu dekódovat. Vezme se tedy slepě hodnota teď už lokální proměnné Par a dosadí se do výrazu. Používání znaků \ a / je pro jména souborů uvnitř VaxNt možné obojí. Pozor ale: některé utility Windows to snášejí také a jiné zase ne. Kupříkladu WordPadu nevadí slashová jména, ale Wordu ano.
Pomocí viever se zavolá nová instance WordPadu a nasaje se do ní zobrazovaný text. Skript pak dalším příkazem exit končí.