Rekonstrukce OCL z SQL *



Podobné dokumenty
Jazyk OCL a modelem řízený vývoj 1

OCL a integritní omezení

Databázové systémy. - SQL * definice dat * aktualizace * pohledy. Tomáš Skopal

2. blok část B Základní syntaxe příkazů SELECT, INSERT, UPDATE, DELETE

UML. Unified Modeling Language. Součásti UML

Primární klíč (Primary Key - PK) Je právě jedna množina atributů patřící jednomu z kandidátů primárního klíče.

Databázové systémy Cvičení 5.2

Jiří Mašek BIVŠ V Pra r ha

Úvod do databázových systémů

Úvod do databázových systémů

Kurz Databáze. Obsah. Dotazy. Zpracování dat. Doc. Ing. Radim Farana, CSc.

7. Integrita a bezpečnost dat v DBS

7. Integrita a bezpečnost dat v DBS

Databáze I. Přednáška 4

Unifikovaný modelovací jazyk UML

DBS Transformace konceptuálního schématu na

Informační systémy 2008/2009. Radim Farana. Obsah. Jazyk SQL

Modelem řízený vývoj. SWI 1 Jan Kryštof

Úvod do databázových systémů

UML - opakování I N G. M A R T I N M O L H A N E C, C S C. Y 1 3 A N W

DUM 12 téma: Příkazy pro tvorbu databáze

Obsah přednášky. Databázové systémy RDBMS. Fáze návrhu RDBMS. Coddových 12 pravidel. Coddových 12 pravidel

Relace x vztah (relationship)

A5M33IZS Informační a znalostní systémy. Relační databázová technologie

Transformace konceptuálního modelu na relační

TÉMATICKÝ OKRUH Softwarové inženýrství

Obsah. Zpracoval:

Principy UML. Clear View Training 2005 v2.2 1

Gymnázium a Střední odborná škola, Rokycany, Mládežníků 1115

Tvorba informačních systémů

Databázové systémy úvod

Obchodní akademie a Jazyková škola s právem státní jazykové zkoušky Jihlava

Databázové modelování. Analýza Návrh konceptuálního schématu

Modely datové. Další úrovní je logická úroveň Databázové modely Relační, Síťový, Hierarchický. Na fyzické úrovni se jedná o množinu souborů.

Databázové systémy trocha teorie

Gymnázium a Střední odborná škola, Rokycany, Mládežníků 1115

Vzorové příklady SQL. Tabulka: Kniha CREATE TABLE kniha (id INTEGER, název VARCHAR(50), PRIMARY KEY (id))

Konceptuální modelování a SQL

Modelování webových služeb v UML

RELAČNÍ DATABÁZOVÉ SYSTÉMY

2. Modelovací jazyk UML 2.1 Struktura UML Diagram tříd Asociace OCL. 3. Smalltalk 3.1 Jazyk Pojmenování

OBJECT DEFINITION LANGUAGE. Jonáš Klimeš NDBI001 Dotazovací Jazyky I 2013

Kapitola 6: Omezení integrity. Omezení domény

Databáze I. Přednáška 7

Informační systémy 2008/2009. Radim Farana. Obsah. Dotazy přes více tabulek

Databázové systémy. Doc.Ing.Miloš Koch,CSc.

Transformace ER SQL. Ing. Michal Valenta PhD. Databázové systémy BI-DBS ZS 2010/11, P edn. 9

DBS Konceptuální modelování

7.3 Diagramy tříd - základy

Databázové systémy. Cvičení 6: SQL

8.2 Používání a tvorba databází

Jaký je rozdíl v definicicíh VARCHAR2(20 BYTE) a VARCHAR2(20 CHAR):

6. SQL složitější dotazy, QBE

Kritéria hodnocení praktické maturitní zkoušky z databázových systémů

CASE nástroje. Jaroslav Žáček

Databázové systémy úvod

CASE. Jaroslav Žáček

Úvod do databází. Modelování v řízení. Ing. Petr Kalčev

Databázové systémy úvod

Databáze 2011/2012 SQL DDL (CREATE/ALTER/DROP TABLE), DML (INSERT/UPDATE/DELETE) RNDr.David Hoksza, Ph.D.

Relační databázová technologie

UML a jeho použití v procesu vývoje. Jaroslav Žáček jaroslav.zacek@osu.cz

X36SIN: Softwarové inženýrství. Životní cyklus a plánování

Gymnázium a Střední odborná škola, Rokycany, Mládežníků 1115

Diagram nebo text? Miroslav Benešovský, BenSoft s.r.o

Jazyk SQL 1. Michal Valenta. Katedra softwarového inženýrství FIT České vysoké učení technické v Praze c Michal Valenta, 2012 BI-DBS, ZS 2011/12

Databáze SQL SELECT. David Hoksza

6. blok část C Množinové operátory

Tvorba informačních systémů

Informační systémy 2008/2009. Radim Farana. Obsah. UML - charakteristika

Michal Krátký. Tvorba informačních systémů, 2008/2009. Katedra informatiky VŠB Technická univerzita Ostrava. Tvorba informačních systémů

Databázové systémy. Datová integrita + základy relační algebry. 4.přednáška

Kapitola 1: Úvod. Systém pro správu databáze (Database Management Systém DBMS) Účel databázových systémů

Operátory ROLLUP a CUBE

KIV/ZIS cvičení 5. Tomáš Potužák

6. blok část B Vnořené dotazy

SQL. strukturovaný dotazovací jazyk. Structured Query Language (SQL)

Úvod do databázových systémů

Návrh a tvorba WWW stránek 1/14. PHP a databáze

Marketingová komunikace. 2. soustředění. Mgr. Pavel Vávra Kombinované studium Skupina N9KMK1aPH/N9KMK1bPH (um1a1ph/um1b1ph)

Marketingová komunikace. 2. a 3. soustředění. Mgr. Pavel Vávra 9103@mail.vsfs.cz. Kombinované studium Skupina N9KMK3PH (vm3aph)

Kolaborativní aplikace

Inovace a zkvalitnění výuky prostřednictvím ICT. Základní seznámení s MySQL Ing. Kotásek Jaroslav

Jazyk SQL databáze SQLite. připravil ing. petr polách

Oracle XML DB. Tomáš Nykodým

Databázový systém označuje soubor programových prostředků, které umožňují přístup k datům uloženým v databázi.

UML: Unified Modeling Language

ZÁZNAM PROCESU TVORBY INFORMAČNÍHO SYSTÉMU CAPTURING OF AN INFORMATION SYSTEM DEVELOPMENT

7.3 Diagramy tříd - základy

Unifikovaný modelovací jazyk UML 1

Analýza a Návrh. Analýza

Analýza a modelování dat 3. přednáška. Helena Palovská

Informační systémy ve zdravotnictví. 6. cvičení

Klasické metodiky softwarového inženýrství I N G M A R T I N M O L H A N E C, C S C. Y 1 3 A N W

2. přednáška. Databázový přístup k datům (SŘBD) Možnost počítání v dekadické aritmetice - potřeba přesných výpočtů, např.

4IT218 Databáze. 4IT218 Databáze

Objektově relační databáze a ORACLE 8

1. Relační databázový model

Analýza a modelování dat. Přednáška 5

Primární klíč, cizí klíč, referenční integrita, pravidla normalizace, relace

Transkript:

Rekonstrukce OCL z SQL * Karel RICHTA 1 1 Katedra softwarového inženýrství, MFF UK Praha Malostranské nám. 25, 118 00 Praha karel.richta@mff.cuni.cz Abstrakt. Jednou z často citovaných zkratek poslední doby je MDD (Model Driven Development), příp. MDA (Model Driven Architecture), nebo dokonce MDE (Model Driven Engineering). Princip těchto přístupů spočívá v tom, že se při tvorbě aplikace využívají různé modely. Sdružení OMG propaguje myšlenku, že práce s modelem může přinést mnoho nových možností. Model může být použit pro generování struktury dat a kostry řešení, reverzním inženýrstvím lze získat model existujícího systému pro jeho snazší pochopení, či úpravy. Nad modelem lze provádět různé transformace, refaktorizace apod. Pro modelování se v současnosti nejvíce využívá standard UML (Unified Modeling Language [9]). Aby však byl model dostatečně úplný, je třeba doplnit diagramy v UML přesnými popisy různých integritních omezení. Pro tento účel obsahuje notace UML speciální jazyk nazvaný OCL (Object Constraint Language [7]). Tento příspěvek se zabývá možnostmi rekonstrukce OCL z existujícího SQL, jako příspěvek k reverznímu inženýrství pro modelem řízený vývoj. Klíčová slova: MDD, MDA, UML, OCL, SQL 1 Úvod Základní princip modelem řízeného stylu [8] spočívá v tom, že se při tvorbě aplikace využívá nějaký model nebo modely. Model nám umožňuje lepší pochopení situace, neboť je abstraktnější a uchopitelnější, než modelovaná skutečnost. Zpravidla se nevyužívá model jediný, ale spíše sada různých modelů (doménový, konceptuální, logický, implementační, či fyzický, apod.). V čem může být vytváření modelu přínosem, co může přinést nového? Jak říká klasik model zůstává, lidé odcházejí, proto je existence dostatečně vypovídajícího modelu určitě přínosem pro stabilitu řešení. Zdánlivou výhodou zanedbání modelu je, že vývoj produktu nezahrnuje žádné aktivity, které by nevedly přímo k výsledku, nevytvářejí se žádné vedlejší produkty a artefakty, výsledkem je přímo kód zkonstruovaný podle katalogu požadavků (samozřejmě, pokud nepovažujeme za model samotný katalog požadavků zapsaný v přirozeném jazyce). Vývojář produktu odevzdává tyto artefakty a vzápětí odchází k jiné firmě. V témže okamžiku přichází od zákazníka nový požadavek, nebo požadavek na změnu. Zodpovědné osobě nezbývá, než svěřit řešení změny někomu, kdo zatím neměl s tímto produktem nic společného. Nová osoba se musí seznámit s kódem, vytvořit si jeho model v hlavě a poté jej přizpůsobit novým požadavkům. * Tento text vznikl za částečné podpory výzkumného záměru MŠMT č. MSM0021620838, grantových projektů GAČR: GA201/09/0990 a GA201/09/0983. Petr Šaloun (ed.), DATAKON 2010, Mikulov, 16-19. 10. 2010, pp. 1-10.

Co jsme ušetřili na začátku, jsme teď ztratili. Pokud se model vytvořený při realizaci změny opět nezaznamená, bude se situace při další změně opakovat. Zdánlivá úspora na začátku se pak ukazuje jako ztráta. Představme si obrácenou situaci analytik rád modeluje a snaží se vytvořit dokonalý model podle požadavků zákazníka. Neustále jej vylepšuje, aby ho připravil na rozmanité změny, které mohou v budoucnosti nastat. Kód nevzniká, neboť se stále zabývá modelem, který ještě není dokonalý. Obě situace nejsou optimální, správný postup představuje rozumný kompromis - vytvořit jen takový model, který pomůže při analýze, návrhu, implementaci, testování a údržbě produktu, a který navíc zůstane firmě k dispozici pro další změny. Pokud je model udržován současně s produktem, může takto sloužit po celý jeho životní cyklus. Ovšem představa, že by vývojáři, analytici, nebo architekti udržovali modely produktu spolu s jeho vývojem a změnami je ovšem do značné míry iluzorní. Disciplinovaný analytik a vývojář mohou pořizovat dokumentaci modelů alespoň na papíře. Pravděpodobně nikdy však neudrží tuto disciplinu při všech změnách - výsledkem je situace bez aktuálního modelu. Jediným řešením by byl nástroj, který by takovou synchronizaci modelu a kódu dostatečně podporoval. Pokud model vytváříme a udržujeme pomocí nějakého sofistikovaného CASE nástroje, bylo by možné o takové synchronizaci uvažovat (CASE je zkratka pro Computer Aided Software Engineering). CASE nástroj by měl podporovat jak přímé inženýrství, kdy tvoříme model a generujeme z něj kostru kódu, tak i reverzní postup, kdy se snažíme z kódu rekonstruovat kostru modelu. Čím více umí CASE nástroj podporovat oba směry, tím užitečnější je jeho využití v procesu vývoje a údržby. V ideálním případě umožňuje cyklické opakování využití přímého a zpětného inženýrství - používá se zde termín roundtrip okružní jízda [2]. Aktuální problém všech modelovacích technik a nástrojů je míra preciznosti. Na jedné straně by měl být model abstraktní, lehce uchopitelný a srozumitelný. Na straně druhé stojí model, který obsahuje všechny podrobnosti, může být použit pro generování, ale už asi není tak přehledný a uchopitelný. Sdružení OMG řeší tento problém tak [8], že doporučuje vytváření modelů na různých úrovních doménový model (označen CIM Computation Independent Model), konceptuální model (PIM Platform Independent Model), logický model (PSM Platform Specific Model) a nakonec kód - fyzický model (ISM Implementation Specific Model). Na všech úrovních je třeba modely prezentovat pokud možno přesně, ale pouze v rozsahu potřebném pro tuto úroveň náhledu. Samotné diagramy to nikdy neumožňují úplně. Uvažme příklad problému evidence hypoték (viz [10]). Ukázka z katalogu požadavků říká, že: 1. Každá hypotéka bude vždy pro jednu osobu. 2. Osoba si může vzít několik hypoték. 3. Každou nemovitost vlastní právě jedna osoba. 4. Osoba může vlastnit libovolný počet nemovitostí. 5. Každá hypotéka musí být zajištěna nejméně jednou nemovitostí. 6. Nemovitost může být použita k zajištění více hypoték. Uvedené požadavky lze snadno na konceptuální úrovni reprezentovat diagramem tříd uvedeným na Obr. 1. Tento poměrně jednoduchý model může mít zajímavé interpretace, neboť je zde např. přípustné, aby osoba zajistila hypotéku nemovitostí, kterou nevlastní. Model je proto zapotřebí doplnit integritním omezením: Osoby mohou jako zajištění hypotéky použít pouze nemovitosti, které samy vlastní. Integritní omezení lze zapsat v přirozeném jazyce - výhodou takového řešení je, že mu navazující řešitelé rozumí - pokud

např. toto zadání předáme nějaké osobě k řešení. Nevýhodou je, pokud toto zadání chceme předat k řešení programu např. CASE nástroji. Ten takovému zápisu zatím nerozumí. Pokud bychom vyjádřili integritní omezení formálně, bylo by možné CASE nástroj tomuto jazyku naučit. Pro notaci UML [9] představuje takový formální nástroj jazyk OCL [7], který stručně popíšeme v následujícím odstavci. class Hypotéky - PIM skládá_se_z 0..* +je_částí 1 Nemovitost - označení: string - hodnota: penize +v lastní 0..* +je_majetkem 1 - jméno: string - příjmení: string - příjem: peníze Osoba +je_zajištěna 1..* + žádost(peníze, Set{Nemovitost}) : boolean +pro 1 +zajišťuje 0..* +má_půjčenu 0..* Hypotéka - od: datum - do: datum - celková_částka: peníze = 250.000,- - měsíční_splátka: peníze Obr. 1: Jednoduchý konceptuální model hypoték (PIM) 2 Jazyk OCL Jazyk OCL [7] pochází původně z metodiky Syntropy (IBM, [10]). Je to čistě funkcionální jazyk - vyhodnocení výrazu je bez vedlejších efektů - neexistuje žádná globální paměť. Stejná funkce se stejnými argumenty dává vždy stejný výsledek. OCL není programovací jazyk - je určen pro vyjádření invariantů - je to specifikační jazyk. Zápisy v OCL je třeba chápat jako specifikaci pro programy, které budou odpovídající integritní omezení zajišťovat. OCL je silně typovaný jazyk, tj. každý výraz v jazyce OCL má definován typ. To umožňuje silnou statickou typovou kontrolu zapsaných omezení při jejich interpretaci. OCL má předdefinovánu sadu typů jsou to jednak primitivní typy: Integer, Boolean, String, Real, UnlimitedInteger, ze kterých lze vytvářet složené typy jako rozmanité kolekce: množina (Set), multi-množina (Bag), obecná kolekce (Collection), posloupnost (Sequence), atd. V jazyce OCL nezapisujeme programy tento pojem OCL nezná, není to programovací jazyk. Ve specifikačním jazyku OCL zapisujeme požadavky na to, aby v jistém kontextu byla splněna nějaká podmínka. Podmínku vyjádříme pomocí formule zapsané jako výraz v OCL. K ní pak připojíme specifikaci kontextu. Zápis v jazyce OCL má vždy jednotný tvar: context <jméno> [inv pre post]: <výraz> Klíčové slovo context zde slouží pro odkaz na kontext pro <výraz> v OCL, např. zápis: context Hypotéka inv : self.celková_částka > 250000

označuje, že uvedený výraz se vztahuje ke kontextu třídy Hypotéka, tj. na všechny její instance (na konkrétní instanci se lze ve specifikaci odkazovat klíčovým slovem self). Výraz zde vyjadřuje podmínku, že pro každou instanci třídy Hypotéka, musí mít její vlastnost celková_částka hodnotu větší než 250000. V daném kontextu nelze evidovat hypotéky s nižší celkovou částkou. Klíčová slova inv, pre, post zastupují stereotypy <<invariant>> (obecně platné tvrzení), <<precondition>> (předpoklad např. vstupní podmínky operace) a <<postcondition>> (podmínka, která musí platit po provedení příslušné akce). OCL lze použít čistě jako navigační jazyk. Chceme-li označit jakýkoliv element některého diagramu, lze použít výraz v OCL. Např. příjem osoby x:osoba v kontextu modelu hypoték, zapíšeme to jako výraz x.příjem. Tento výraz má hodnotu, která je typu peníze. Chceme-li označit názvy nemovitostí, které osoba x:osoba v kontextu modelu hypoték právě vlastní, zapíšeme to jako výraz x.vlastní. V tomto případě je hodnotou množina nemovitostí výsledek je typu Set{Nemovitost}, neboť osoba může vlastnit více nemovitostí, příp. také žádnou. Nejčastěji se OCL používá pro vyjádření integritních omezení v datovém modelu, zejména v diagramech tříd. Také se používá pro vyjádření typových omezení při definici nových stereotypů. Lze jej ale rovněž použít pro vyjádření předpokládaného efektu operací, pro popis vstupních a výstupních podmínek operací. Jak již bylo řečeno, poskytuje jazyk OCL předefinované primitivní typy, ze kterých lze vytvářet složené typy. Při konstrukci hodnot složených typů lze využívat operátory: collect, select, reject, forall, exists, iterate, include, count, union, intersect, isempty, notempty, isunique a dalších. Volání operátorů se zapisuje ve tvaru inspirovaném jazykem Smalltalk, např. zápis: x.vlastní -> count() označuje počet nemovitostí, které osoba x:osoba vlastní. Podobně: x.vlastní.hodnota -> sum() označuje součet cen nemovitostí, které osoba x:osoba vlastní. Vzhledem k existenci kvantifikátorů (forall, exists), lze usuzovat, že OCL je notace pro zápis formulí predikátového kalkulu 1.řádu v programátorském stylu, smíchaná s množinovou notací. Konkrétní hodnoty kolekcí se konstruují stejně označenými konstruktory, např.: Set {2,4,1,5,7,13,11,17}, OrderedSet {1,2,3,5,7,11,13,17}, Sequence {1,2,3,5,7,11,13,17}, Bag {1,2,3,2,1}. 3 Příklad specifikace v OCL Jako ilustrační příklad použijeme dříve uvedenou jednoduchou evidenci hypoték. Model uvedený na obrázku Obr. 1 ale nevystihuje zdaleka všechny požadované vlastnosti hypoték. Původní požadavky doplnil systémový analytik o další, které by měla data o hypotékách splňovat:

7. Hypotéku lze zajistit pouze nemovitostmi, které osoba vlastní. 8. Cena nemovitostí zajišťujících hypotéku musí být větší, než celková zapůjčovaná částka. 9. Celková zapůjčovaná částka všech hypoték zajištěných danou nemovitostí nesmí přesahovat cenu nemovitosti. 10. Součet měsíčních splátek osoby by neměl přesáhnout 30% jejího měsíčního příjmu a zbytek příjmu po odečtení splátek musí splňovat zákonné požadavky nesmí klesnout pod zákonné minimum. 11. Půjčujeme nejméně 250 tis.kč. Tato integritní omezení již nevyjádříme pouze pomocí diagramů - musíme model doplnit o jejich specifikaci. Specifikaci zapíšeme pomocí výrazů v jazyce OCL. context Hypotéka inv IO7: self.je_zajištěna.je_majetkem = self.pro context Hypotéka inv IO8: self. celková_částka <= self.je_zajištěna.hodnota -> sum() context Nemovitost inv IO9: self.zajišťuje.celková_částka -> sum() <= self.cena context Hypotéka inv IO11: (self.celková_částka >= 250000). Podobným způsobem vyjadřujeme integritní omezení, popisující požadované vlastnosti operací. V našem modelu mohou osoby žádat o hypotéku na určitou částku, zajištěnou nějakou sadou nemovitostí. V modelu je na to určena metoda žádost, přesněji Osoba::žádost. Pro žádosti o hypotéky platí požadavek, který by měl omezit případy, kdy osoba nebude schopna hypotéky splácet, tj. kdy celkový součet měsíčních splátek přesáhne její možnosti: context Osoba::žádost(částka:peníze, zajištění:set{nemovitost}) pre IO10: (self.má_půjčenu.měsíční_splátka -> sum()) + částka <= self.příjem * 0.3 Ještě jedno důležité integritní omezení, které se týká rekurzivních vztahů: 12. Nemovitost se nemůže skládat sama ze sebe (dělíme jen na jedné úrovni). context Nemovitost inv IO12: not(self.skládá_se_z -> iselement(self)) Všechna uvedená integritní omezení zajišťují konzistenci evidovaných dat. Chytrý CASE nástroj může formální definici integritních omezení využít pro generování kódu zajišťující data proti porušení integrity. Např. na relační platformě může generovat relační integritní omezení nebo triggery, které porušení integrity hlídají a nepovolí uložení chybných dat. 4 Jazyk SQL Použijeme-li při vývoji jako platformu relační databázový systém, bude komunikačním jazykem této platformy jazyk SQL. Syntaxe SQL dělí příkazy do 5-ti kategorií: <SQL statement> ::= <QUERY> <DML> <DDL> <TCL> <DCL> Z hlediska našeho problému jsou zajímavé příkazy z kategorie DDL (Data Definition Language), neboť těmi se vytvářejí základní relační objekty tabulky atd. Tabulky a ostatní objekty uložené v databázi byly vytvořeny pomocí těchto příkazů. Ze všech možných druhů objektů se zde budeme zabývat pouze tabulkami, neboť ty jsou nejdůležitější.

CREATE TABLE "table_name" ("column 1" "data_type_for_column_1", "column 2" "data_type_for_column_2",... ) Uvažme např. tabulku osob (nazveme ji Osoby, neboť bude obsahovat záznamy typu Osoba o evidovaných osobách): CREATE TABLE Osoby (jméno VARCHAR2(24),... ) Při reverzním inženýrství můžeme všechny takové DDL příkazy rekonstruovat z katalogu databáze, kde musí být všechny informace o všech objektech uloženy. Konkrétní postup je samozřejmě závislý na struktuře katalogu daného poskytovatele. Tabulky v relační databázi jsou pro rekonstrukci OCL zajímavé pouze jako definice struktury. Pro jednoduchost budeme uvažovat pouze tabulky a ty později převedeme do UML/OCL jako třídy. Sloupce tabulek převedeme na vlastnosti tříd - atributy nebo vztahy. Pro rekonstrukci OCL jsou spíše zajímavá integritní omezení definovaná nad těmito tabulkami. SQL připouští pět typů deklarativních integritních omezení: <CONSTRAINT> ::= <NOT NULL> <UNIQUE> <PRIMARY KEY> <FOREIGN KEY> <CHECK> 5 Převod UML/OCL do SQL Převodem specifikace v UML/OCL do SQL se zabývají např. články [10], či [4]. Princip spočívá zhruba v tom, že třídy převedeme na tabulky, atributy na sloupce, vztahy 1:N realizujeme pomocí primárních a cizích klíčů. Vztahy M:N realizujeme pomocí vztahové tabulky a primárních a cizích klíčů. Příklad relačního logického modelu vytvořeného z konceptuálního modelu hypoték (viz Obr. 1) je zobrazen na obrázku Obr. 2. Byl pořízen automatickým převodem podle standardních pravidel pro transformaci PIM na PSM. Integritní omezení jsou na konceptuální úrovni reprezentována v OCL. Řadu z nich lze převést do SQL poměrně přímočaře. Zápis v OCL: context T inv IOT: <výraz> nahradíme v SQL příkazem: ALTER TABLE T ADD CONSTRAINT IOT CHECK (<výraz>) Uvažme např. integritní omezení č.11: context Hypotéka inv IO11: (self.celková_částka >= 250000) To nahradíme v SQL příkazem: ALTER TABLE Hypoteky ADD CONSTRAINT IO11 CHECK (celkova_castka >= 250000) Pokud výraz obsahuje operace pro práci s kolekcemi, bude převod o něco komplikovanější. Uvažme např. integritní omezení č.12: Nemovitost je majetkem právě jedné osoby, nebo se skládá z částí, které vlastní nějaká osoba (nemovitosti dělíme jen na jedné úrovni). context x:nemovitost inv IO14: (x.skládá_se_z -> isempty() and x.je_majetkem -> size() = 1) or (not (x.skládá_se_z -> isempty()) and (x.je_majetkem -> size() = 0)) and (x.skládá_se_z -> exists( y:osoba y.vlastní -> iselement(x))))

class DDL Nemovitost «column» *PK nemovitostid: NUMBER(8) označení: VARCHAR2(50) hodnota: NUMBER(9,2) FK je_majetkem: NUMBER(8) FK je_částí: NUMBER(8) «PK» + PK_Nemovitost(NUMBER) + FK_je_majetkem(NUMBER) 1 + FK_je_částí(NUMBER) +PK_Nemovitost (nemovitostid = nemovitostid) +FK_Nemovitost 0..* JoinHypotékaToNemovitost «column» *FK nemovitostid: NUMBER(8) * hypotékaid: NUMBER(8) 0..* +FK_je_majetkem 0..* +PK_Nemovitost +skládá_se_z (je_majetkem = osobaid) (je_částí = nemovitostid) +FK_Hypoteka +PK_Hypoteka (hypotékaid = hypotékaid) 1..* +PK_Osoba 1 Osoba «column» *PK osobaid: NUMBER(8) jméno: VARCHAR2(24) příjmení: VARCHAR2(35) příjem: NUMBER(8,2) «PK» + PK_Osoba(NUMBER) +PK_Osoba 1 +FK_pro (pro = osobaid) Hypotéka 0..* «column» *PK hypotékaid: NUMBER(8) od: DATE do: DATE celková_částka: NUMBER(9,2) = 250.000,- měsíční_splátka: NUMBER(8,2) *FK pro: NUMBER(8) + FK_Nemovitost(NUMBER) + FK_Hypotéka() «PK» + PK_Hypotéka(NUMBER) + FK_pro(NUMBER) Obr. 2: Logický relační model hypoték (PSM) Můžeme opět vyzkoušet transformaci na klausuli CHECK, kde případně použijeme určitý trik např. při nahrazování univerzálního kvantifikátoru jej nahradíme pomocí dvojí negace a poté vyjádříme pomocí operátoru exists, který v SQL existuje. ALTER TABLE Nemovitosti ADD CONSTRAINT IO12 CHECK (IS NULL sklada_se_z AND ((SELECT count(*) FROM Osoby WHERE osobaid = je_majetkem) = 1) OR (IS NOT NULL sklada_se_z AND ((SELECT count(*) FROM Osoby WHERE osobaid = je_majetkem) = 0) AND (EXISTS (SELECT 'X' FROM Osoby WHERE nemovitostid in vlastni))) Ve skutečnosti bude převod o něco komplikovanější, neboť žádný poskytovatel systému řízení relační báze dat neumí implementovat klausuli CHECK, ve které se vyskytuje dotaz nad stejnou tabulkou. 6 Převod SQL do UML/OCL Poté, co jsme zkonstruovali PSM, můžeme se pokusit v rámci okružní jízdy o zpětný převod na PIM. Předmětem naší zpětné transformace je logický, relační databázový model (schema), který převádíme do UML/OCL. Výstupem by měl být konceptuální model vstupního schématu. Sloupec v tabulce T, nad kterým je definováno integritní omezení NOT

NULL budeme transformovat na povinný atribut v diagramu tříd UML, tj. atribut s četností [1..1], zkráceně [1] (nepovinný bude mít četnost [0..1]): SQL UML <sloupec> <typ> NOT NULL <sloupec> : <typ> [1] Sloupec v tabulce T, nad kterým je definováno integritní omezení UNIQUE budeme v OCL specifikovat pomocí zabudované metody isunique, kterou se v OCL vyjadřuje právě podmínka unikátnosti: SQL create table T ( <sloupec> <typ> UNIQUE ) OCL context T inv : self.<sloupec> -> isunique() Sloupec, nebo sloupce v tabulce T, nad kterými je definováno integritní omezení PRIMARY KEY budeme v OCL specifikovat jako kombinaci předešlých dvou vlastností: SQL create table T ( <sloupec> <typ> PRIMARY KEY ) OCL context T inv : self.<sloupec> -> isunique() and isdefined() Pro sloupec, nebo sloupce v tabulce T, nad kterými je definováno integritní omezení FOREIGN KEY se jménem <FK>, zavedeme v diagramu tříd vztah mezi tabulkou T a referencovaným objektem, který se bude jmenovat <FK>. Navíc budeme v OCL specifikovat omezení: SQL create table T ( <sloupec> <typ> CONSTRAINT <FK> REFERENCES <nazev>(<tabulka>) ) OCL context T inv : self.<sloupec> -> exists( x:<tabulka> x.<nazev> = self. <FK> ) Sloupec, nebo sloupce v tabulce T, nad kterými je definováno integritní omezení typu CHECK budeme v OCL specifikovat: SQL create table T ( <sloupec> <typ> CHECK(<výraz>) ) OCL context T inv : self.<sloupec> -> forall( x:t <výraz> ) Pokud aplikujeme tato pravidla na logický model PSM našich hypoték, získáme následující model zapsaný lineárně v jazyce USE [10]: model Hypotéky -- classes class Osoba attributes jméno : VARCHAR2(24)... end class Hypotéka attributes... end class Nemovitost attributes... end class JoinHypotékaToNemovitost attributes... end

-- associations association FK_pro between Osoba[1] Hypotéka[0..*] end association FK_je_majetkem between Nemovitost[0..*] Osoba[1] end association FK_Hypotéka between JoinHypotékaToNemovitost[1..*] Hypotéka[1] end association FK_Nemovitost between JoinHypotékaToNemovitost[0..*] Nemovitost[1] end -- OCL constraints constraints... context Hypotéka -- hypotéka musí být zajištěna vlastním majetkem inv IO7: self.je_zajištěna.je_majetkem = self.pro... context Hypotéka -- nejmenší částka je 250.000,- inv IO11: self.celková_částka >= 250000... Z uvedených příkladů je zřejmé, že pro okružní jízdu je třeba si některé informace uchovávat spolu s modely. Např. je to mapování mezi identifikátory na úrovni PIM a identifikátory v relačním modelu na úrovni PSM. Jiný příklad jsou vztahy M:N, které jsme při převodu do PSM nahradili vztahovými tabulkami. Takových informací je celá řada a pokud ji neuchováme, bude problém okružní jízdu realizovat. Jak to zařídit bude předmětem dalšího výzkumu. 7 Závěr V článku je rozebírána tzv. okružní jízda (round-trip) pro případ relační platformy a datového modelu. Uvedené příklady formálních specifikací integritních omezení zapsaných v jazyce OCL a SQL představují ukázku kontextu, ve kterém se bude muset CASE nástroj podporující okružní jízdu pohybovat. Naznačili jsme postup převodu konceptuálního datového modelu (PIM) v notaci UML/OCL do SQL a zpětný převod logického modelu (PSM) z SQL do OCL. Je to samozřejmě jen malý krůček do modelem řízeného vývoje. Existuje několik škol, kde se specifikacemi v OCL intenzivně zabývají, viz. např. [5], či [6]. OCL není samozřejmě jediným způsobem formální specifikace integritních omezení. V současné době se ale zdá být nejperspektivnější. Uveďme si příklad využití formálních specifikací v praxi. V roce 1998 byla uvedena do provozu linka 14 pařížského metra, pro kterou byl požadavek, aby mohla být plně řízena

nejen lidskou obsluhou, ale také pouze softwarem. Protože se jednalo o citlivou věc, byl vývoj a testování tohoto softwaru prováděn za pomoci formálních specifikací. Požadavky byly zformulovány ve specifikačním jazyce B - jednalo se o asi 100 tis. řádků specifikace. Za pomoci různých nástrojů byla tato specifikace testována, bylo provedeno asi 27 tis. důkazů různých vlastností popsaného produktu. Posléze tato specifikace posloužila pro vygenerování kostry kódu v jazyce Ada, který po úpravách představoval asi 87 tis. řádků kódu, tj. méně než byla specifikace. Byť se tento příklad netýká přímo OCL, je z něj vidět, že používání formálních specifikací má v některých případech uplatnění. Vývoj formálních specifikací a nástrojů, které s nimi pracují, probíhá neustále. Např. poslední verze OCL je z února tohoto roku, nejedná se tedy o mrtvý standard. Spíše se hledají cesty, jak formální specifikace v OCL využít v CASE nástrojích. Např. známý Enterprise Architect již dovoluje vkládání omezení v OCL do modelů, umí dokonce kontrolovat správnost syntaxe, ale zatím neumí z těchto formálních zápisů generovat nějaký kód. Před několika lety ale neuměl ani syntaxi OCL. Uvidíme, co se změní za pár let. Literatura [1] Arlow, J., and Neustadt, I.: UML 2 and the Unified Process: Practical Object-Oriented Analysis and Design (2nd Edition), Addison-Wesley Professional Press, 2005. [2] Beličák, M. Pokorný, J. Richta, K.: Open Design Architecture for Round Trip Engineering. In: Proceedings of ISD 2009, Nanchang, Springer-Verlag (v tisku). [3] Botting, R.: Simplex of OCL. URL: http://www.csci.csusb.edu/dick/samples/ocl.html. [4] Cook, S. - Daniels,J.: Designing Object Systems: Object-Oriented Modelling with Syntropy. Prentice Hall, 1994, ISBN 0-13-203860-9. URL: http://en.wikipedia.org/wiki/syntropy. [5] Dresden OCL Toolkit. URL: http://dresden-ocl.sourceforge.net/. [6] Octopus OCL Toolkit. URL: http://octopus.sourceforge.net/. [7] OMG: Object Constraint Language, Version 2.2. February 2010. URL: http://www.omg.org/spec/ocl/2.2/. [8] OMG: MDA Guide, 2003. URL: http://www.omg.org/mda/. [9] OMG: UML 2.2, February 2009. URL: http://www.omg.org/spec/uml/2.2/ [10] Richta, K: Jazyk OCL a modelem řízený vývoj. In: Moderní database 2010, Nesuchyně, Komix Praha 2010. [11] Richters, M. Gogolla, M.: OCL: Syntax, Semantics, and Tools. In: Object Modeling with the OCL, LNCS 2263, Springer Berlin/Heidelberg, ISBN978-3-540-43169-5, pp. 447-450, 2002 [12] Wikipedia: http://cs.wikipedia.org/wiki/14_(linka_metra_v_paříži). Annotation: Reconstruction of OCL from SQL This paper discusses the possibilities of reconstruction of UML classes and OCL constraints from an existing SQL, as a contribution to the reverse engineering process in the model-driven development.