| import simplerdbms : 'SimpleRDBMS.ecore#/'; |
| import simpleuml : 'SimpleUML.ecore#/'; |
| import umltordbms : 'SimpleUML2RDBMS.ecore#/'; |
| |
| package simpleUML2RDBMS = 'http://simpleUML2RDBMS' |
| { |
| transformation SimpleUML2RDBMS |
| { |
| check uml imports simpleuml; |
| enforce rdbms imports simplerdbms; |
| middle imports umltordbms; |
| } |
| } |
| |
| map packageToSchema_LM in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| guard:uml p : Package; |
| new:middle p2s : PackageToSchema; |
| set p2s.umlPackage := p; |
| set p2s.name := p.name; |
| } |
| |
| map packageToSchema_MR in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| guard:middle p2s : PackageToSchema; |
| new:rdbms s : Schema; |
| set s.name := p2s.name; |
| set p2s.schema := s; |
| } |
| |
| map integerToNumber_LM in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:uml p : Package; |
| guard:uml prim : PrimitiveDataType; |
| in:middle p2s : PackageToSchema; |
| check p2s.umlPackage = p; |
| check prim.namespace = p; |
| check prim.name = 'Integer'; |
| new:middle p2n : IntegerToNumber; |
| set p2n.owner := p2s; |
| set p2n._'primitive' := prim; |
| set p2n.name := prim.name + '2' + 'NUMBER'; |
| } |
| |
| map integerToNumber_MR in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:middle p2s : PackageToSchema; |
| guard:middle p2n : IntegerToNumber; |
| check p2n.owner = p2s; |
| var sqlType : String := 'NUMBER'; |
| set p2n.typeName := sqlType; |
| } |
| |
| map booleanToBoolean_MR in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:middle p2s : PackageToSchema; |
| guard:middle p2n : BooleanToBoolean; |
| check p2n.owner = p2s; |
| var sqlType : String := 'BOOLEAN'; |
| set p2n.typeName := sqlType; |
| } |
| |
| map booleanToBoolean_LM in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:uml p : Package; |
| guard:uml prim : PrimitiveDataType; |
| in:middle p2s : PackageToSchema; |
| check p2s.umlPackage = p; |
| check prim.namespace = p; |
| check prim.name = 'Boolean'; |
| new:middle p2n : BooleanToBoolean; |
| set p2n._'primitive' := prim; |
| set p2n.name := prim.name + '2' + 'BOOLEAN'; |
| set p2n.owner := p2s; |
| } |
| |
| map stringToVarchar_MR in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:middle p2s : PackageToSchema; |
| guard:middle p2n : StringToVarchar; |
| check p2n.owner = p2s; |
| var sqlType : String := 'VARCHAR'; |
| set p2n.typeName := sqlType; |
| } |
| |
| map stringToVarchar_LM in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:uml p : Package; |
| guard:uml prim : PrimitiveDataType; |
| in:middle p2s : PackageToSchema; |
| check p2s.umlPackage = p; |
| check prim.namespace = p; |
| check prim.name = 'String'; |
| new:middle p2n : StringToVarchar; |
| set p2n.name := prim.name + '2' + 'VARCHAR'; |
| set p2n.owner := p2s; |
| set p2n._'primitive' := prim; |
| } |
| |
| map classToTable_MR in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:rdbms s : Schema; |
| in:middle p2s : PackageToSchema; |
| guard:middle c2t : ClassToTable; |
| check p2s.schema = s; |
| check c2t.owner = p2s; |
| var c2t_name : String[?] := c2t.name; |
| new:rdbms t : Table; |
| new:rdbms pk : Key; |
| new:rdbms pc : Column; |
| set c2t.table := t; |
| set t.name := c2t_name; |
| set c2t.primaryKey := pk; |
| set c2t.column := pc; |
| set t.kind := 'base'; |
| set t.schema := s; |
| set pk.owner := t; |
| set pk.kind := 'primary'; |
| set pc.owner := t; |
| set pc.keys := OrderedSet(simplerdbms::Key){pk}; |
| set pc.type := 'NUMBER'; |
| set pc.name := c2t_name + '_tid'; |
| set pk.name := c2t_name + '_pk'; |
| } |
| |
| map classToTable_LM in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:uml p : Package; |
| guard:uml c : Class; |
| in:middle p2s : PackageToSchema; |
| check p2s.umlPackage = p; |
| check c.kind = 'persistent'; |
| check c.namespace = p; |
| new:middle c2t : ClassToTable; |
| set c2t.owner := p2s; |
| set c2t.name := c.name; |
| set c2t.umlClass := c; |
| } |
| |
| map associationToForeignKey_MR in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:rdbms s : Schema; |
| in:rdbms st : Table; |
| in:rdbms dt : Table; |
| guard:rdbms rk : Key; |
| in:middle p2s : PackageToSchema; |
| in:middle sc2t : ClassToTable; |
| in:middle dc2t : ClassToTable; |
| guard:middle a2f : AssociationToForeignKey; |
| check dc2t.table = dt; |
| check sc2t.owner = p2s; |
| check p2s.schema = s; |
| check sc2t.table = st; |
| check a2f.referenced = dc2t; |
| check a2f.owner = sc2t; |
| check rk.kind = 'primary'; |
| check rk.owner = dt; |
| check st.schema = s; |
| new:rdbms fk : ForeignKey; |
| new:rdbms fc : Column; |
| set fk.name := a2f.name; |
| set a2f.foreignKey := fk; |
| set fc.type := rk.column->first().type; |
| set fc.name := a2f.name + '_tid'; |
| set a2f.column := fc; |
| set fk.owner := st; |
| set fc.owner := st; |
| set fk.refersTo := rk; |
| set fc.foreignKeys := OrderedSet(simplerdbms::ForeignKey){fk}; |
| } |
| |
| map associationToForeignKey_LM in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:uml p : Package; |
| in:uml sc : Class; |
| in:uml dc : Class; |
| guard:uml a : Association; |
| in:middle p2s : PackageToSchema; |
| in:middle sc2t : ClassToTable; |
| in:middle dc2t : ClassToTable; |
| check sc2t.owner = p2s; |
| check dc2t.umlClass = dc; |
| check sc2t.umlClass = sc; |
| check p2s.umlPackage = p; |
| check a.namespace = p; |
| check sc.namespace = p; |
| check a.source = sc; |
| check a.destination = dc; |
| var a2f_name : String := if a.destination = dc and a.source = sc |
| then a.name |
| else if a.destination <> dc and a.source = sc |
| then dc.name + '_' + a.name |
| else if a.destination = dc and a.source <> sc |
| then a.name + '_' + sc.name |
| else dc.name + '_' + a.name + '_' + sc.name |
| endif |
| endif |
| endif; |
| new:middle a2f : AssociationToForeignKey; |
| set a2f.association := a; |
| set a2f.referenced := dc2t; |
| set a2f.name := a2f_name; |
| set a2f.owner := sc2t; |
| set a.name := if a.destination = dc and a.source = sc |
| then a2f_name |
| else a.name |
| endif; |
| } |
| |
| map classPrimitiveAttributes_LM in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:uml t : PrimitiveDataType; |
| in:uml c : Class; |
| guard:uml a : Attribute; |
| in:middle fao : ClassToTable; |
| in:middle p2n : PrimitiveToName; |
| check fao.umlClass = c; |
| check p2n._'primitive' = t; |
| check a.owner = c; |
| check a.type = t; |
| new:middle fa : AttributeToColumn; |
| set fa.owner := fao; |
| set fa.type := p2n; |
| set fa.name := a.name; |
| -- set fa.owner := fao; |
| set fa.kind := a.kind; |
| -- set fa.kind := a.kind; |
| set fa._'attribute' := a; |
| -- set fa._'attribute' := a; |
| set fa.leafs := Set(umltordbms::AttributeToColumn){fa}; |
| } |
| |
| map classComplexAttributes_LM in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:uml t : Class; |
| in:uml c : Class; |
| guard:uml a : Attribute; |
| in:middle fao : ClassToTable; |
| check fao.umlClass = c; |
| check a.owner = c; |
| check a.type = t; |
| var leafs := fao.fromAttributes.leafs->asSet(); |
| new:middle fa : NonLeafAttribute; |
| set fa._'attribute' := a; |
| set fa.kind := a.kind; |
| set fa.owner := fao; |
| -- set fa.owner := fao; |
| set fa.name := a.name; |
| set fa.leafs := leafs; |
| -- set fa.kind := a.kind; |
| } |
| |
| map complexAttributePrimitiveAttributes_LM in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| guard:uml ca : Attribute; |
| in:uml c : Class; |
| in:uml t : PrimitiveDataType; |
| guard:uml a : Attribute; |
| in:middle fao : NonLeafAttribute; |
| in:middle p2n : PrimitiveToName; |
| check fao._'attribute' = ca; |
| check p2n._'primitive' = t; |
| check a.owner = c; |
| check a.type = t; |
| check ca.type = c; |
| check a.owner = c; |
| new:middle fa : AttributeToColumn; |
| set fa.owner := fao; |
| set fa._'attribute' := a; |
| set fa.kind := a.kind; |
| set fa.type := p2n; |
| set fa.leafs := Set(umltordbms::AttributeToColumn){fa}; |
| set fa.name := fao.name + '_' + a.name; |
| -- set fa.kind := a.kind; |
| -- set fa._'attribute' := a; |
| -- set fa.owner := fao; |
| } |
| |
| map complexAttributeComplexAttributes_LM in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:uml ca : Attribute; |
| in:uml c : Class; |
| in:uml t : Class; |
| guard:uml a : Attribute; |
| guard:middle fao : NonLeafAttribute; |
| check fao._'attribute' = ca; |
| check a.owner = c; |
| check a.owner = c; |
| check ca.type = c; |
| check a.type = t; |
| var leafs := fao.fromAttributes.leafs->asSet(); |
| new:middle fa : NonLeafAttribute; |
| set fa.owner := fao; |
| set fa.kind := a.kind; |
| set fa.leafs := leafs; |
| set fa._'attribute' := a; |
| -- set fa._'attribute' := a; |
| set fa.name := fao.name + '_' + a.name; |
| -- set fa.kind := a.kind; |
| -- set fa.owner := fao; |
| } |
| |
| map attributeColumns_MR in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| in:rdbms t : Table; |
| in:rdbms ct : String; |
| in:middle c2t : ClassToTable; |
| in:middle p2n : PrimitiveToName; |
| guard:middle a2c : AttributeToColumn; |
| check c2t.table = t; |
| check p2n.typeName = ct; |
| check a2c.owner = c2t; |
| check c2t.fromAttributes.leafs->includes(a2c); |
| check a2c.type = p2n; |
| new:rdbms c : Column; |
| set c.name := a2c.name; |
| set c.kind := a2c.kind; |
| set a2c.column := c; |
| set c.owner := t; |
| set c.type := ct; |
| } |
| |
| map __root__ in simpleUML2RDBMS::SimpleUML2RDBMS |
| { |
| for p : simpleuml::Package in uml.objectsOfKind(Package) { |
| call packageToSchema_LM { |
| p iterates p; |
| } |
| } |
| for p2s : umltordbms::PackageToSchema in middle.objectsOfKind(PackageToSchema) { |
| call packageToSchema_MR { |
| p2s iterates p2s; |
| } |
| } |
| for c : simpleuml::Class in uml.objectsOfKind(Class) { |
| call classToTable_LM { |
| c iterates c; |
| p uses c.namespace; |
| p2s uses c.namespace.middle; |
| } |
| } |
| for c2t : umltordbms::ClassToTable in middle.objectsOfKind(ClassToTable) { |
| call classToTable_MR { |
| c2t iterates c2t; |
| p2s uses c2t.owner; |
| s uses c2t.owner.schema; |
| } |
| } |
| for a : simpleuml::Association in uml.objectsOfKind(Association) { |
| call associationToForeignKey_LM { |
| a iterates a; |
| sc uses a.source; |
| dc uses a.destination; |
| p uses a.namespace; |
| sc2t uses a.source.middle; |
| dc2t uses a.destination.middle; |
| p2s uses a.source.middle.owner; |
| } |
| } |
| for a2f : umltordbms::AssociationToForeignKey in middle.objectsOfKind(AssociationToForeignKey) { |
| for rk : simplerdbms::Key in rdbms.objectsOfKind(Key) { |
| call associationToForeignKey_MR { |
| a2f iterates a2f; |
| rk iterates rk; |
| dc2t uses a2f.referenced; |
| sc2t uses a2f.owner; |
| st uses a2f.owner.table; |
| s uses a2f.owner.table.schema; |
| dt uses a2f.referenced.table; |
| p2s uses a2f.owner.owner; |
| } |
| } |
| } |
| for prim : simpleuml::PrimitiveDataType in uml.objectsOfKind(PrimitiveDataType) { |
| call stringToVarchar_LM { |
| prim iterates prim; |
| p uses prim.namespace; |
| p2s uses prim.namespace.middle; |
| } |
| } |
| for prim : simpleuml::PrimitiveDataType in uml.objectsOfKind(PrimitiveDataType) { |
| call integerToNumber_LM { |
| prim iterates prim; |
| p uses prim.namespace; |
| p2s uses prim.namespace.middle; |
| } |
| } |
| for prim : simpleuml::PrimitiveDataType in uml.objectsOfKind(PrimitiveDataType) { |
| call booleanToBoolean_LM { |
| prim iterates prim; |
| p uses prim.namespace; |
| p2s uses prim.namespace.middle; |
| } |
| } |
| for a : simpleuml::Attribute in uml.objectsOfKind(Attribute)->select(type.oclIsKindOf(PrimitiveDataType)) { |
| call classPrimitiveAttributes_LM { |
| a iterates a; |
| c uses a.owner; |
| check t uses a.type; |
| p2n uses a.type.oclAsType(PrimitiveDataType).middle; |
| fao uses a.owner.middle; |
| } |
| } |
| for p2n : umltordbms::IntegerToNumber in middle.objectsOfKind(IntegerToNumber) { |
| call integerToNumber_MR { |
| p2n iterates p2n; |
| p2s uses p2n.owner; |
| } |
| } |
| for p2n : umltordbms::BooleanToBoolean in middle.objectsOfKind(BooleanToBoolean) { |
| call booleanToBoolean_MR { |
| p2n iterates p2n; |
| p2s uses p2n.owner; |
| } |
| } |
| for p2n : umltordbms::StringToVarchar in middle.objectsOfKind(StringToVarchar) { |
| call stringToVarchar_MR { |
| p2n iterates p2n; |
| p2s uses p2n.owner; |
| } |
| } |
| for a : simpleuml::Attribute in uml.objectsOfKind(Attribute) { |
| call classComplexAttributes_LM { |
| a iterates a; |
| check t uses a.type; |
| c uses a.owner; |
| fao uses a.owner.middle; |
| } |
| } |
| for fao : umltordbms::NonLeafAttribute in middle.objectsOfKind(NonLeafAttribute) { |
| for a : simpleuml::Attribute in uml.objectsOfKind(Attribute) { |
| call complexAttributeComplexAttributes_LM { |
| a iterates a; |
| fao iterates fao; |
| ca uses fao._'attribute'; |
| check t uses a.type; |
| check c uses fao._'attribute'.type; |
| } |
| } |
| } |
| for a : simpleuml::Attribute in uml.objectsOfKind(Attribute)->select(type.oclIsKindOf(PrimitiveDataType)) { |
| for ca : simpleuml::Attribute in uml.objectsOfKind(Attribute) { |
| call complexAttributePrimitiveAttributes_LM { |
| a iterates a; |
| ca iterates ca; |
| c uses a.owner; |
| check t uses a.type; |
| p2n uses a.type.oclAsType(PrimitiveDataType).middle; |
| check fao uses ca.middle; |
| } |
| } |
| } |
| for a2c : umltordbms::AttributeToColumn in middle.objectsOfKind(AttributeToColumn)->select(owner.oclIsKindOf(umltordbms::ClassToTable)) { |
| call attributeColumns_MR { |
| a2c iterates a2c; |
| p2n uses a2c.type; |
| check c2t uses a2c.owner; |
| t uses a2c.owner.oclAsType(umltordbms::ClassToTable).table; |
| ct uses a2c.type.typeName; |
| } |
| } |
| } |