· 9 years ago · Nov 17, 2016, 04:58 PM
1-- 20 Gennaio 2016 Numero 2
2-- DEFINIZIONE DEI TIPI
3CREATE TYPE Attribute_ty AS OBJECT
4(
5 Name VARCHAR2(20)
6 Visible BOOLEAN
7 Abstract BOOLEAN
8);
9CREATE TYPE coll_attribute_ty AS TABLE OF Attribute_ty;
10
11CREATE TYPE Class_ty AS OBJECT
12(
13 Name VARCHAR2(20)
14 Diagram VARCHAR2(50)
15 HaAttr: coll_attribute_ty
16);
17CREATE TYPE coll_ref_class_ty AS TABLE OF REF Class_ty;
18
19CREATE TYPE BasicType_ty AS OBJECT UNDER Attribute_ty
20(
21 Type VARCHAR2(20)
22);
23
24CREATE TYPE DefType_Ty AS OBJECT UNDER Attribute_ty
25(
26 cref REF Class_ty
27);
28CREATE TYPE coll_defType_ty AS TABLE OF DefType_ty
29
30-- Ora modifico class_ty per aggiungere le 3 nuove collezioni
31ALTER TYPE Class_Ty
32(
33 ADD ATTRIBUTE(Sup REF Class_ty),
34 ADD ATTRIBUTE (Sub call_ref_class_ty),
35 ADD ATTRIBUTE (IN call_defType_ty),
36)
37
38-- Infine creo l'unica tabella che è quella delle class_ty
39CREATE TABLE Class_TAB OF Class_ty
40(
41 NESTED TABLE HaAttr STORE AS Attribute_TAB,
42 NESTED TABLE Sub STORE AS Sub_TAB,
43 NESTED TABLE IN STORE AS In_TAB
44);
45
46-- PLSQL METODO ADD ATTRIBUTE
47CREATE TYPE BODY Class_ty AS
48MEMBER PROCEDURE AddAttribute(Name String, Visible Boolean, Abstract Boolean, Type String) AS
49(
50 DECLARE
51 myClass REF Class_ty
52 classDefType REF Class_ty := NULL
53 newAttr DefType_ty
54 BEGIN
55 -- Controllo se esiste già un attributo con quel nome associato alla nostra classe
56 -- Prima mi salvo il riferimento alla nostra classe dentro la variabile myClass
57 SELECT REF(C) INTO myClass
58 FROM Class_TAB C
59 WHERE REF(C) = REF(SELF)
60 IF NOT EXISTS ( SELECT * FROM myClass.HaAttr AS A WHERE A.name = name) THEN
61 -- Non esiste l'attributo quindi posso inserirlo, contro quindi se è basictype
62 IF (Type = 'INTEGER' OR Type = 'BOOLEAN' OR Type = 'String' OR Type = 'REAL') THEN
63 -- Lo inserisco negli attributi come basicType
64 -- Prima mi prendo la nested table di attributi dalla nostra classe
65 INSERT INTO TABLE (SELECT A FROM myClass.HaAttr)
66 VALUES BasicType (Name=>Name, Visible=> Visible, Abstract => Abstract, Type=> Type)
67 ELSE -- Controllo se è un defType
68 -- Mi salvo in classDefType il riferimento alla classe alla quale l'attributo punta se è deftype
69 -- N.B. Se l'attributo da inserire non ha come tipo nessuna classe allora classDefType sarà null.
70 SELECT REF(C) INTO classDefType
71 FROM Class_TAB AS C
72 WHERE C.Name = Type
73 -- Se la variabile non è null allora sicuro l'attributo si riferisce ad una classe, quindi lo inserisco
74 IF (classDefType IS NOT NULL) THEN
75 INSERT INTO TABLE (SELECT A FROM myClass.HaAttr) AS G -- Mi prendo la nested table di attributi da class nostra
76 -- Inserisco il nuovo attributo e ne ritorno l'oggetto dentro la variabile newAtt(che mi servirà dopo)
77 VALUES DefType (Name=>Name, Visible=> Visible, Abstract => Abstract, cref=> classDefType) RETURNING G INTO newAttr
78 -- Ora inserisco il nuovo attributo nella nested table IN da Class a DefType
79 INSERT INTO TABLE (SELECT L.IN FROM Class_TAB L WHERE REF(L) = classDefType)
80 VALUES newAttr
81 ENDIF
82 ENDIF
83 ENDIF
84 END
85END
86
87-- ESERCIZIO DOPO
88-- mi creo prima una funzione per vedere se è concreta
89CREATE FUNCTION isConcrete(Class class_ty) RETURN BOOLEAN AS
90DECLARE
91RET BOOLEAN:= FALSE
92LCOUNT INTEGER
93ABCOUNT INTEGER
94BEGIN
95 SELECT COUNT(*) INTO LCOUNT
96 FROM (SELECT TREAT( A AS DefType) FROM Class.HaAttr AS A)
97 SELECT COUNT(*) INTO ABCOUNT
98 FROM Class.HaAttr AS A WHERE A.Abstract = TRUE
99 IF (ABCOUNT = 0 AND LCOUNT > 0) THEN
100 RET = TRUE
101 END IF
102 RETURN RET
103END
104END
105-- ora faccio la query
106SELECT STRUCT (S.REFER, VALUE(C))
107FROM Class_TAB AS C,
108 (SELECT TREAT( A AS DefType) FROM C.HaAttr AS A) AS D
109WHERE isConcrete(VALUE(C)) AND isConcrete(D.REFER)