background image

 

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. 

background image

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. 

background image

 

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 

background image

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.  

background image

 

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 

background image

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ą”  

 

background image

 

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 

background image

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: 

background image

 

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 

background image

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 

background image

 

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. 

background image

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. 

background image

 

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.