Rozdział 14
RENTMAN- po narodzinach
Zakładamy, że skompletowaliście Państwo program RENTMAN zgodnie z planem
opracowanym we wcześniejszych rozdziałach książki. Faza analizy, planowania
i konstruowania aplikacji jest w zasadzie za nami.
Zgodnie z założonym, pięciofazowym modelem pracy nad aplikacją, pozostały
nam jeszcze etapy testowania i konserwacji. Zbadamy i omówimy liczne problemy
związane z życiem aplikacji po jej skonstruowaniu.
Testowanie aplikacji
Istnieją liczne sposoby testowania programów i zapewniania ich jakości, jednakże
kilka ogólnych wytycznych pozostaje prawdziwymi, niezależnie od założonej
drogi postępowania. Oto wskazówki, odnoszące się do testowania aplikacji:
Należy stwierdzić, czy program realizuje całkowicie założone wcześniej
zadania. Nie ograniczajmy się jedynie do wyszukiwania typowych błędów
w oprogramowaniu („pluskiew”); pełny proces sprawdzania wymaga spojrzenia
na aplikację jak na wielki obraz, powinniśmy wiedzieć, co program miał robić,
kiedy go planowaliśmy i porównać z efektem końcowym.
Przyjrzyjmy się kluczowym funkcjom, które program ma realizować
i zastanówmy się, czy aplikacja spełnia swoje zadania, czy jej funkcje są
realizowane tak, jak zaplanowaliśmy. Należy również przemyśleć sposób
zbadania, w jaki każda funkcja realizuje przypisane jej cele. Rzetelne
testowanie wymaga porównania aplikacji z
oryginalną specyfikacją jej
właściwości.
Po autorskiej weryfikacji należy przeprowadzić zarówno testy wewnętrzne, jak
i zewnętrzne. Wewnętrzne są prowadzone przez autora i jego zespół programistów.
Zewnętrzne mogą wykonywać ludzie z tej samej grupy, lecz w żaden sposób nie
związani z projektem (członkowie grupy prowadzącej beta testy oraz wszelkie inne
zespoły spoza przedsiębiorstwa). Oto kilka wskazówek przydatnych przy
prowadzeniu testów wewnętrznych:
Sprawdzić, czy więzy nałożone na bazę danych są realizowane prawidłowo.
434
Część II
Sprawdzić obiekty umiejscowione na serwerze, takie jak procedury pamiętane
(stored procedures) i perspektywy (views), upewniając się, czy wykonują
założone zadania.
Przetestować działanie programu podczas pracy z wieloma użytkownikami.
Zweryfikować, czy zdefiniowane prawa dostępu prawidłowo sterują
uprawnieniami.
Sprawdzić program na komputerze możliwie jak najbardziej podobnym do
maszyny użytkownika.
Poniższa lista zawiera kilka dodatkowych wskazówek do testów zewnętrznych:
Ustalić sformalizowaną procedurę raportowania o
błędach w
programie
i zasadach reakcji na takie informacje.
Zaplanować sposób łatwej dystrybucji aktualizacji i pakietów poprawiających
błędy.
Zapewnić pomoc techniczną ludzi nie związanych z testowaniem aplikacji.
Ustanowić małą grupę kluczowych użytkowników do prowadzenia beta testów.
Prowadzić testy przydatności z
użytkownikami o
różnym poziomie
zaawansowania.
Pamiętać, że to użytkownicy decydują, czy aplikacja im odpowiada oraz spełnia
ich Szczegółowa analiza zewnętrznego testowania programów wykracza poza
ramy tej książki.
Pierwsze i najważniejsze pytanie: Czy aplikacja realizuje zadanie, do którego
została zaprojektowana? W rozdziale 8 określono przeznaczenie programu
RENTMAN: ma być systemem ułatwiającym zarządzanie wynajmowanymi
nieruchomościami.
Czy program wywiązuje się z postawionego zadania? Wydaje się, że tak, ale
jedynie Allodium może naprawdę stwierdzić, czy aplikacja robi to w stopniu
przynajmniej dostatecznym.
Przejdźmy do funkcji kluczowych. Zgodnie z tym, co napisano w rozdziale 8,
aplikacja powinna:
Umożliwiać zapisywanie i konserwowanie danych o wynajmie nieruchomości.
Pozwalać na śledzenie realizacji prac związanych z ich utrzymaniem.
Umożliwiać rozliczanie najemców.
Dostarczać informacji o historii nieruchomości.
RENTMAN- po narodzinach
435
I znów musimy stwierdzić, że RENTMAN wydaje się spełniać wszystkie założone
funkcje oraz że jedynie Allodium może w pełni ocenić w jakim zakresie.
Przed rozpoczęciem testowania aplikacji przyjrzyjmy się oddzielnie każdej
wskazówce do przeprowadzania kontroli wewnętrznej, i zobaczmy, jak mogą być
one zastosowane w przypadku programu RENTMAN.
Sprawdzić więzy nałożone na bazę danych aplikacji
Należy sprawdzić (próbując je złamać), czy nałożone więzy istnieją, są wzajemnie
spójne i działają zgodnie z założeniami. Przy sprawdzaniu programu RENTMAN
powinniśmy spróbować:
Usunąć z pliku tabeli LEASE najemców, którzy utrzymują dzierżawę.
Wprowadzić do pola City tabeli PROPERTY wartość inną niż Richardson,
Dallas, Plano, Norman, Oklahoma City i Edmond.
Usunąć z tabeli PROPERTY rekord, opisujący nieruchomość, która zgodnie
z danymi z tabeli LEASE jest aktualnie wynajmowana.
Pominąć pole Deposit przy wprowadzaniu danych do tabeli PROPERTY.
Wprowadzić niewłaściwą datę do pola StartDate tabeli WORDER.
Dodać do tabeli PROPERTY nieruchomość mającą sześć sypialni.
Nie ma chyba wątpliwości, na czym polega ten etap testowania. Sprawdzamy
warunki konieczne poprawnego działania aplikacji, nałożone poprzez więzy bazy
danych.
Sprawdzić obiekty umiejscowione na serwerze
Jeśli zaimplementowany program wykorzystuje procedury pamiętane (stored
procedures), perspektywy (views) lub inne obiekty umiejscowione na serwerze, to
należy sprawdzić ich pracę. Testowanie systemów klienta jest dla wszystkich
oczywiste, tymczasem konieczność kontroli działania obiektów osadzonych na
serwerze jest przez wielu programistów aplikacji klient/serwer zaniedbywana lub
minimalizowana. A przecież SQL jest językiem, takim samym jak Object Pascal
czy C++. Oto kilka spraw, na które należy zwrócić uwagę:
Jeśli mamy zbudowany raport końcowy, który jest produkowany przez
procedurę pamiętaną lub inny obiekt umiejscowiony na serwerze, to należy
uruchomić procedurę poza aplikacją lub kreatorem raportów, aby się upewnić,
że działa zgodnie z oczekiwaniami. Nawet jeśli sprawdziliśmy pracę procedury
za pośrednictwem naszego programu, to uruchomienie jej bezpośrednio
pozwala zobaczyć ewentualne komunikaty serwera oraz inne informacje, które
436
Część II
mogą być ignorowane przez aplikację lub oprogramowanie dostępu do bazy
danych.
Jeśli wykonujemy operacje DML (Data Manipulation Language - język
operowania danymi), wykorzystując procedury pamiętane, to powinniśmy
dokonać zabronionych dla bazy danych lub procedury prób modyfikacji danych
(np. wprowadzić błędną wartość). Umieszczając w procedurach pamiętanych
elementy oprogramowania typu DML, bierzemy odpowiedzialność za
upewnienie się o ich poprawnym działaniu.
Przeprowadzanie testów w środowisku wielodostępnym
Implementując system wielodostępny, musimy uwzględnić przede wszystkim dwa
czynniki. Pierwszy to współbieżność. Duża liczba użytkowników próbujących
uzyskać dostęp do tych samych zasobów bazy danych może powodować
różnorodne problemy, z
których najważniejsze związane są z
zatorami
i blokowaniem dostępu. Użytkownicy mogą sobie wzajemnie blokować dostęp do
zasobów, których potrzebują. Za zatory mogą być również odpowiedzialne
działające w systemie procesy.
Drugim wyzwaniem, stawianym przez środowisko sieciowe, są ograniczenia
zasobów systemu. Układ poprawnie działający przy dziesięciu użytkownikach
może zawieść, gdy korzysta z niego dwadzieścia osób. Podłączenie się każdego
nowego użytkownika obciąża system, nawet jeśli w danej chwili nie korzysta on
z zasobów i nie blokuje połączeń. Istnieją po prostu fizyczne ograniczenia
spowodowane wydajnością przetwarzania danych przez serwer, szybkością
transmisji, oraz maksymalną liczbą transakcji możliwych do zrealizowania w sieci.
W czasie przeprowadzania testów powinno się przyjąć najgorszy scenariusz (jeśli
w systemie docelowym nie będzie pracowało więcej niż dwustu użytkowników, to
w czasie weryfikacji aplikacji należy ją sprawdzać przy czterystu odbiorcach).
Istotną sprawą jest zbadanie granic możliwości konstruowanego systemu. Planując
wydajność aplikacji warto się oprzeć na oszacowaniu zasobów dostępnych dla
użytkownika.
Sterowanie współbieżnością i model klient/serwer
Dostęp do danych na serwerze SQL, inaczej niż w lokalnych bazach danych, nie
jest zazwyczaj możliwy na zasadzie rekord po rekordzie. Niektóre serwery nie są
nawet w stanie blokować dostępu do pojedynczych wierszy, blokowane są większe
obiekty: strony lub segmenty celem zabezpieczenia przed zakłóceniami podczas
modyfikowania danych przez użytkownika.
Uniemożliwia to innym użytkownikom jakiekolwiek zmiany w zbiorze.
RENTMAN- po narodzinach
437
Programista musi wiedzieć, w
jaki sposób jest realizowane sterowanie
współbieżnością na platformach DBMS. Powinniśmy ograniczać do minimum
liczbę zatorów. Za wszelką cenę należy unikać przetwarzania danych rekord po
rekordzie. Rozważmy poniższą procedurę, służąca do modyfikacji tabeli LEASE
i ustawiania wartości danych z kolumny
LawnService
na
False
:
With taLease do
While not EOF do begin
If
taLEASEPetDeposit.AsFloat<>0
then
taLEASELawnservice.AsBoolean:=False;
Next;
end;
To standardowe na lokalnych tabelach rozwiązanie jest jednak powodem
problemów na serwerach baz danych, bowiem powoduje zablokowanie tabeli
Lease
w trakcie modyfikacji pola LawnService. Zamyka na chwilę dostęp do
danych dla innych użytkowników i działa relatywnie wolno. Zachodzi również
możliwość, że serwer rozszerzy blokadę rekordów lub strony na całą tabelę,
uniemożliwiając na czas jej trwania jakikolwiek dostęp do tabeli dla innych
użytkowników.
Aby wykonać podobne aktualizacje, należy stosować SQL: zarówno procedury
pamiętane, jak i
zwykłe zapytania. Należy trzymać się zasady: „Unikać
indywidualnego przetwarzania rekordów”. Niech robi to serwer, tak jest lepiej.
Oto zapytanie w języku SQL, które wykonuje to samo zadanie:
UPDATE LEASE
SET LawnService=’F’
WHERE PetDeposit<>0 AND LawnSerwice<>’F’
Zadanie zostanie wykonane w jednym przejściu, a blokady (blokada) będą
zwolnione tak szybko, jak to jest możliwe.
Transakcje i serwery baz danych
Przypomnijmy, że transakcja to grupa zmian bazy danych przetwarzana jako
pojedyncza porcja (batch). Zmiany są wykonywane albo w komplecie, albo wcale.
Zostało to zaimplementowane przy wykorzystaniu protokołów odtwarzania
transakcji (transaction/redo logs). Prawidłowe określenie rozmiaru protokołu
transakcji, ostrożność, aby nie przekraczać ich obszaru, wydajne zapisywanie
i odtwarzanie transakcji - to tylko niektóre realne problemy, które muszą być brane
pod uwagę przez projektanta aplikacji klient/serwer.
Delphi umożliwia sterowanie transakcjami, opartymi na serwerze, poprzez
komponent
TDatabase
. Aby rozpocząć transakcję, należy wywołać metodę
StartTransaction
, do jej zakończenia metodę
Commit
, a do odtworzenia
Rollback
. Wywołanie tych metod w środowisku klient/serwer daje ten sam
438
Część II
efekt, co wykonanie na serwerze równoważnego polecenia SQL (np. rozpoczęcie
transakcji w
bazie danych RENTMAN poprzez wywołanie metody
StartTransaction obiektu dbRENTMAN, jest równoważne użyciu komendy SQL-
SET TRANSACTION w systemie InterBase).
Poziomy izolowania transakcji
Innym ważnym obszarem zarządzania transakcjami jest wykorzystanie poziomów
separowania transakcji dla unikania utraty aktualizacji oraz konfliktów dostępu.
Poziom izolowania (TIL- Transaction Isolation Level) dotyczy zdolności
wzajemnego dostrzegania zmian realizowanych współbieżnie przez różne
transakcje.
Poziomy separowania danych możemy wykorzystywać za pośrednictwem
właściwości
TransIsolation
komponentu
TDatabase
. Może ona
przyjmować trzy wartości:
tiDirtyRead
,
tiReadCommited
oraz
tiRepeatableRead
. Pierwsza powoduje zgłaszanie każdej zmiany rekordu
dokonanej przez tę lub inną transakcję, nawet wtedy, gdy nie została jeszcze
zapisana Druga jedynie tych zmian, które zostały zapisane, trzecia natomiast
zwraca rekordy w postaci, w jakiej były podczas inicjalizacji transakcji. Rekordy
w ciągu trwania jednej transakcji ukazywane są jako nie zmienione, nawet jeśli
w tym czasie inna transakcja wprowadziła do podstawowej tablicy zmianę
rekordu.
Możliwość konfliktów między dwiema transakcjami, dotyczącymi dostępu do tej
samej bazy danych, występuje na wszystkich poziomach izolowania. Stopnie
tiReadCommited
oraz
tiRepeatableRead
redukują najbardziej
prawdopodobieństwo kolizji, tak jak w przypadku transakcji
Tran1
i
Tran2
.
Pierwsza jest separowana na poziomie
tiReadCommited
z dostępem read/write,
druga, z
tym samym dostępem, jest separowana właściwością
tiRepeatableRead
. Konflikt między obiema transakcjami może wystąpić
jedynie wtedy, gdy modyfikują ten sam rekord. Ogranicza się w ten sposób
możliwość zatorów na serwerze, podnosząc jednocześnie poziom ochrony przed
utratą uaktualnienia. Domyślnym poziomem izolowania transakcji jest
tiReadCommited
. Powinien być adekwatny dla większości transakcji.
UWAGA
Nie na wszystkich platformach serwerów są dostępne trzy stopnie separowania
transakcji. Jeśli dany serwer nie akceptuje jakiegoś poziomu, to BDE zmieni go na
kolejny (względem restrykcji) dostępny w tym środowisku. (Por. rozdział 23,
„Sterowanie współbieżnością”
RENTMAN- po narodzinach
439
WSKAZÓWKA
Większość serwerów baz danych umożliwia śledzenie blokad nakładanych na
obiekty baz danych. Na platformach Sybase oraz Microsoft wykorzystuje się do
monitorowania blokad procedurę pamiętaną
sp_lock
, w systemie Oracle można
posłużyć się zapytaniem do tabeli V$WAITSTAT. Odpowiednim narzędziem
w InterBase jest opcja Lock Manager Statistics programu Server Manager. Nawyk
monitorowania konfliktów na serwerze może ułatwić współużytkowanie tych
samych zasobów przez różne aplikacje i zminimalizować liczbę zatorów.
Tryb aktualizacji
Można wykorzystać właściwość
UpdateMode
komponentu
Table and
Query
do oddziaływania na typ kodu SQL generowanego podczas aktualizacji
rekordu. Dostarcza to kilku narzędzi sterowania współbieżnością oraz umożliwia
zrównoważone działanie przy zabezpieczeniu przed utratą aktualizacji danych.
Parametr
UpdateMode
może przyjmować trzy wartości:
upWhereAll
,
upWhereChanged
i
upWhereKeyOnly
. Ustawienia te określają rodzaj
warunku SQL
WHERE
, wykorzystywanego do lokalizacji aktualizowanego rekordu.
Podczas zmiany wartości tabeli lub aktualizacji zbioru wyników zapytania,
deklaracja SQL-
UPDATE
jest generowana celem przeprowadzenia modyfikacji na
serwerze. Jeśli jej wartość wynosi
upWhereAll
, to warunek
WHERE
powoduje
inwentaryzację wszystkich kolumn tabeli lub zapytania. Jeśli wartość równa jest
upWhereChanged
, zapisywane są jedynie pola kluczowe i pola modyfikowane.
Ostatnia wartość powoduje, że działaniem objęte są jedynie pola kluczowe.
Domyślnym stanem parametru jest
upWhereAll
, co można uznać za podejście
zbyt restrykcyjne. W większości przypadków wartość
upWhereChanged
jest
zupełnie bezpieczna, a może być znacznie szybsza od poprzedniej, co zależy od
liczby kolumn w tabeli. Nie należy używać parametru
upWhereKeyOnly
bez
uzgodnienia z administratorem bazy danych. Jeśli potrzebne jest bardzo szybkie
uaktualnianie tabeli, do której mamy wyłączny dostęp, to właściwym wyborem jest
upWhereKeyOnly
. Z drugiej strony użycie tego parametru w środowisku
wielodostępnym może spowodować utratę aktualizacji przez innych
użytkowników.
Efekt wyboru trybu aktualizacji można obserwować za pomocą programu
narzędziowego Delphi o nazwie SQL Monitor. Umożliwia on podglądanie BDE
i śledzenie interakcji rekordów między aplikacją a bazą danych. Poza innymi
zadaniami pozwala obserwować przesyłanie na serwer zleceń SQL.
Aby przekonać się, jak to działa, wybieramy narzędzie SQL Monitor z menu
Database w Delphi i zaznaczamy przycisk przełącznika obok ustawienia
Always in
Top
w menu
Options
. Następnie uruchamiamy aplikację i wciskamy klawisz F4, by
440
Część II
wyświetlić formularz
fmPROCGD0
. W chwili, gdy zjawi się on na ekranie,
zmieniamy wartość w jednym z jego pól, po czym wciskamy klawisz
Post
na
znajdującym się z
dołu formularza komponencie
DBNavigator
. Teraz
przewijamy górne okno programu SQL Monitor, aż zobaczymy deklarację SQL
Update
i klikamy na niej lewym przyciskiem myszy. Przed nami kod SQL, który
aplikacja przesyła do serwera, aby wywiązać się ze zlecenia modyfikacji tabeli.
UPDATE inwentaryzuje wszystkie pola w tabeli.
Zamykamy SQL Monitor oraz aplikację. W projektancie formularzy Delphi
umieszczamy moduł danych
dmRENTMAN
i zmieniamy właściwość
UpdateMode
komponentu
taPROPERTY
na
upWhereChanged
. Po przełączeniu parametru
ponownie uruchamiamy SQL Monitor oraz program RENTMAN. Również tym
razem dokonujemy zmiany w tabeli oraz przewijamy górne okno programu SQL
Monitor, aż zobaczymy wygenerowaną deklarację SQL
Update
. Klikamy na niej,
by móc ją przejrzeć w dolnym oknie. Liczba wypisanych kolumn powinna się
istotnie zmniejszyć.
Jeszcze raz powtarzamy całą procedurę, tym razem ustawiając wartość
UpdateMode
na
upWhereKeyOnly
. Jak można zauważyć, ta konfiguracja
najbardziej redukuje liczbę kolumn, ograniczając ją praktycznie do niezbędnych
dla jednoznacznej lokalizacji rekordu. Należy bardzo ostrożnie korzystać z tej
możliwości, gdyż dzieje się to kosztem ochrony. Ponieważ do aktualizacji
rekordów tabeli wykorzystuje się jedynie pola kluczowe, to zmiany poczynione
przez jednego użytkownika mogą zapisać modyfikacje drugiego.
Modyfikacje buforowane
Jedna z metod potencjalnego minimalizowania liczby konfliktów dostępu na
serwerze baz danych polega na wykorzystaniu buforowania modyfikacji. Jeśli
właściwość
CachedUpdates
komponentu
DataSet
jest ustawiona na
True
,
to zmiany dokonane w DataSet są buforowane (zachowywane lokalnie) do czasu
zapisania ich poleceniem
ApplyUpdates
.
Przyjrzyjmy się działaniu tej metody. Do wizualnego projektanta formularzy
wczytujemy moduł danych
dmRENTMAN
. Klikamy tabelę taTENAT i ustawiamy
wartość jej parametru
CachedUpdates
na
True
. Następnie instalujemy
formularz
fmRSYSMAN0
i wybieramy opcję
Tenant
w jego menu Tables. Linię
kodu:
fmRTENCGD0.Show;
zmieniamy na:
fmRTENCGD0.ShowModal;
w następnej linii wstawiamy polecenie:
RENTMAN- po narodzinach
441
dmRENTMAN.taTENANT.ApplyUpdates;
Dzięki temu modyfikacje w formularzu
fmRTENCGD0
będą zachowywane
lokalnie do czasu opuszczenia formularza, po czym dopiero zostaną wysłane do
serwera. Oczywiście, jeśli możemy zredukować częstotliwość aktualizacji serwera
oraz jego obiektów, zmniejszamy prawdopodobieństwo wystąpienia konfliktów
związanych z blokowaniem.
Zmiana zapytań na procedury pamiętane oraz perspektywy
Innym sposobem ograniczania prawdopodobieństwa konfliktów i poprawiania
współbieżności jest zamiana dynamicznych zapytań SQL na procedury pamiętane
i perspektywy. Dzięki temu aplikacja wywołuje zapytania SQL, które są już
skompilowane, a zatem działają szybciej. Poza tym eliminujemy konieczność
przesyłania do serwera poleceń SQL. Transmitowanie siecią obszernej paczki
tekstu zastępujemy wywołaniem procedury pamiętanej, co bardzo poprawia
wydajność.
Perspektywy umożliwiają zamianę prostych zapytań na procedury pamiętane, które
mogą być przetwarzane tak jak tabele. Na platformie InterBase można zdefiniować
procedury pamiętane, przetwarzane na wzór tabeli i perspektyw, co w tym
wypadku praktycznie zaciera różnicę między procedurami a perspektywami. Kilka
zapytań programu RENTMAN doskonale nadaje się na procedury pamiętane.
Przykładowo kod SQL w komponencie
Querry quWorkDuration
powinien
być przetłumaczony na następującą procedurę:
SET TERM ^;
CREATE procedure gETwORKdURATION (wonUM INTEGER)
RETURNS (WorkDuration float)
AS
BEGIN
FOR SELECT sum (WORKTYPE.TaskDuration) as WorkDuration
FROM WODETAIL, WORKTYPE
WHERE WODETAIL.WORK_TYPE_CODE=WORKTYPE.WORK_TYPE_CODE
AND WODETAIL.WORK_ORDER_NUMBER=:WONun
INTO :WORKdURATION
DO SUSPEND;
END ^
SET TERM ;^
Po zdefiniowaniu procedury pamiętanej, wystarczy zastąpić komponent
Query
przez element
StoredProc
i
odpowiednio zmodyfikować kod programu.
Ostatecznie otrzymujemy zapytanie, które nie tylko działa szybciej, ale jest
również łatwo dostępne z innych aplikacji.
Dobrym sposobem wykorzystania perspektyw w programie RENTMAN będzie
zastąpienie licznych kombinacji pól wyszukiwania w tabelach systemu prostymi
perspektywami. Zamiast określenia w tabeli WODETAIL pola umożliwiającego
442
Część II
przeglądanie informacji w tabeli WORKTYPE, należy zastąpić je perspektywą,
która realizuje połączenie na serwerze. Perspektywa będzie wyglądała w aplikacji
jak każda inna tabela, będzie jednak zawierała pola Description i TaskDuration
z tabeli WORKTYPE, które nie będą wymagały dostępu za pośrednictwem pól
wyszukiwania. Jest to jeszcze jeden przykład, że praca z bazami danych na
serwerach wymaga innego sposobu myślenia niż z systemami lokalnymi typu
dBase lub Paradox.
WSKAZÓWKA
Komponent
TLiveQuery
, który jest naszkicowany w rozdziale 27 „Tworzenie
własnych komponentów Delphi”, umożliwia łatwe tworzenie perspektyw do
składowania na serwerze, na wzór konfiguracji komponentu
TQuery
. Jak
zauważyliśmy wcześniej, wykorzystanie perspektyw może przyśpieszyć działanie
programu i umożliwia wyeliminowanie pól wyszukiwania. Więcej informacji na
ten temat zawiera rozdział 27.
Weryfikacja uprawnień dostępu użytkowników
System ochrony powinien być zainstalowany przed oddaniem aplikacji
użytkownikom. Autor programu musi się upewnić, że dostęp do poufnych
informacji jest ograniczony, że system jest chroniony przed intruzami ze świata
zewnętrznego oraz że dane klientów są zabezpieczone przed zamierzonym lub
przypadkowym zniszczeniem. System ochrony może się opierać na kodzie
aplikacji lub zostać zaimplementowany na serwerze, uprawnienia zaś mogą być
realizowane na bazie komend, obiektów, albo jednych i drugich.
Kiedy przechodzimy od używania tabel lokalnych do serwera baz danych, zmienia
się dynamika praw użytkownika i oznaczenia uprawnień. W wielodostępnych
aplikacjach środowiska Paradox przyznaje się zazwyczaj uprawnienia dostępu
poprzez sieć lub na poziomie serwera. Użytkownicy mają nadane prawa do pliku
poprzez system operacyjny, co niezbyt pasuje do zbiorów baz danych. Niektóre
formaty tablic lokalnych umożliwiają zachowywanie wszystkich tabel bazy danych
w jednym fizycznym pliku, więc użytkownicy muszą mieć uprawnienia do tabel
korespondujące z prawami do plików. Możliwość kombinacji jest zazwyczaj
ograniczona do wyboru między dostępem typu „tylko do odczytu” (read access),
a dostępem rodzaju „do zapisywania i odczytu” (read/write accsess). Większość
platform DBMS nie umożliwia przyznania użytkownikowi prawa dopisywania
rekordów do bazy bez prawa ich usuwania.
Wszystko się zmienia, gdy projektujemy aplikację na platformę klient/serwer.
Dostęp do poszczególnych tabel, perspektyw i procedur bazy danych musi być
przyznany przez administratora bazy danych, który określa również sposób
RENTMAN- po narodzinach
443
rejestracji w systemie, grupy użytkowników itp. Pełne opracowanie przedmiotu
administrowania bazami danych wykracza poza ramy tej książki. Musimy jednak,
choćby pokrótce, zwrócić uwagę na niektóre problemy.
Przyznawanie uprawnień poleceniem GRANT
GRANT
jest komendą SQL przeznaczoną do przyznawania uprawnień
użytkownikom; do odbierania praw służy bliźniacza komenda
REVOKE
. Obie
wymagają trzech parametrów: uprawnień, które chcemy nadać lub odebrać,
obiektu bazy danych, których dotyczą uprawnienia oraz użytkownika, którego
przywileje są zmieniane. Oto przykład komendy SQL przyznającej uprawnienia do
tabeli WORKTYPE bazy RENTMAN:
GRANT ALL ON WORKTYPE TO PUBLIC
Polecenie przyznaje komplet uprawnień (
SELECT, INSERT, UPDATE,
DELETE i
REFERENCES
) wszystkim użytkownikom. Nadane przywileje
odbieramy podobnie:
REVOKE ALL ON WORKTYPE FROM PUBLIC
WSKAZÓWKA
Przenosząc tablice lokalne na platformę klient/server, można zaoszczędzić czas,
przyznając lub odbierając uprawnienia w całości. Wystarczy napisać skrypt SQL,
który wykorzystuje polecenie
GRANT ALL ON nazwa_tablicy TO
PUBLIC
do jednoczesnego nadania uprawnień użytkownikom. Później, w razie
potrzeby, precyzuje się odpowiednie uprawnienia.
Zastępując parametr
ALL
listą przywilejów, można nadać kilka specyficznych
uprawnień, na przykład:
GRANT SELECT, INSERT, UPDATE ON EMPLOYEE TO PUBLIC
.
Podobnie:
REVOKE SELECT, INSERT ON EMPLOYEE FROM PUBLIC
.
Odnotujmy możliwość zastąpienia parametru
PUBLIC
listą użytkowników,
których dotyczy zmiana uprawnień. Zanim to zrobimy, trzeba wprowadzić
użytkowników oraz określić zasady rejestracji w systemie (logins). Odmiennie niż
większość platform klient/serwer, InterBase nie obsługuje grup użytkowników
(oprócz predefiniowanej grupy ALL). Z wyjątkiem systemów Sybase i Microsoft
nie rozróżnia się identyfikatorów i haseł użytkowników, stosowanych na serwerze
i w bazie danych. Dodanie nowego użytkownika z prawami dostępu do serwera
daje mu możliwość komunikowania się z bazą danych.
444
Część II
Wykorzystując program Server Manager systemu InterBase, w następujący sposób
konfigurujemy dostęp do aplikacji RENTMAN:
1. Uruchomiæ Server Manager z folderu InterBase.
2. Zarejestrować się na serwerze, wybierając opcję
File\Server Login
.
3. Połączyć się z bazą danych, klikając na opcji
Database
Connect
menu
File
.
4. Wybrać opcję
Security
menu
Task
.
Na ekranie powinno ukazać się okienko dialogowe
Security
, umożliwiające
dodanie użytkowników i określenie zasad rejestracji w systemie.
5. Wcisnąć przycisk
Add
User
, a następnie wprowadzić nazwę użytkownika oraz
hasło.
Nie
można wprowadzić nazwy użytkownika, pisząc ją małymi literami- zostaną
zastąpione wielkimi. Przy wprowadzaniu hasła należy zachować ostrożność.
Niektóre programy zezwalają na pisanie małymi literami, które są odróżniane
przez serwer od swoich wielkich odpowiedników.
6. Wcisnąć przycisk
OK
, aby zapisać na serwerze informacje o
nowym
użytkowniku.
Używając nowego identyfikatora i hasła można już nawiązać kontakt z dowolną
bazą danych InterBase, aby jednak uzyskać dostęp do konkretnych obiektów,
nowemu użytkownikowi muszą zostać nadane odpowiednie uprawnienia. Jak już
mówiliśmy, prawa dostępu możemy przyznać przy pomocy komendy
GRANT
.
Polecenie:
GRANT ALL ON TENANT TO MARY
nadaje wszystkie uprawnienia użytkownikowi o nazwie MARY. Dla każdej tabeli,
perspektywy i procedury pamiętanej, którym chcemy przyznać uprawnienia,
musimy z osobna powtórzyć te komendę.
Prawo nadawania uprawnień dostępu można rozciągnąć na innych użytkowników.
Służy temu deklaracja
WITH GRANT OPTION
komendy
GRANT
.
Polecenie:
GRANT EXECUTE ON PROCEDURE LISTPROP TO MARY WITH GRANT OPTION
daje użytkownikowi o identyfikatorze MARY nie tylko możliwość uruchamiania
procedury pamiętanej, ale również pełnomocnictwo do nadawania innym
użytkownikom tego prawa dostępu.
RENTMAN- po narodzinach
445
Eksploatacja programu
Eksploatacja aplikacji jest szczegółowo omawiana w rozdziale 29, przedstawimy
więc zaledwie kilka uwag na początek:
Jak już mówiliśmy, zanim zdecydujemy się uruchomić oprogramowanie
gdziekolwiek dalej, należy zainstalować je i
przetestować w
systemie
symulującym środowisko przyszłego użytkownika.
Starać się unikać oddziaływania na maszynę użytkownika. Nie modyfikować
żadnych parametrów konfiguracji oprócz niezbędnie koniecznych.
Ustalić, jaki dodatkowy sprzęt lub oprogramowanie będą potrzebne
użytkownikowi przed zainstalowaniem aplikacji. Na przykład, jeśli
przewidujemy komunikację z DBMS poprzez TCP/IP, w systemie użytkownika
musi być dostępna obsługa tego protokołu. Na tym etapie wskazana jest
współpraca ze swoim administratorem sieci.
Utworzyć program instalacyjny, wykorzystując pakiet narzędziowy Delphi
o nazwie InstallShield Express. Konstruowanie programu, służącego do
instalacji systemu i współpracujących z nim plików, jest szczegółowo opisane
w rozdziale 29.