| import SimpleUML : 'SimpleUml.ecore'::umlMM; |
| import SimpleUMLtoRDBMS : 'SimpleUMLtoRDBMS.ecore'::uml2rdbms; |
| import SimpleRDBMS : 'SimpleRdbms.ecore'::rdbmsMM; |
| |
| transformation umlRdbms { |
| uml imports SimpleUML; |
| rdbms imports SimpleRDBMS; |
| imports SimpleUMLtoRDBMS; |
| } |
| |
| -- utility functions for flattening |
| query umlRdbms::getAllSupers(cls : SimpleUML::Class) : Set(SimpleUML::Class) { |
| cls.general->collect(gen|if gen.oclIsKindOf(SimpleUML::Class) |
| then getAllSupers(gen.oclAsType(SimpleUML::Class)) else null endif)-> |
| including(cls)->asSet() |
| } |
| |
| query umlRdbms::getAllAttributes(cls : SimpleUML::Class) : Set(SimpleUML::Attribute) { |
| getAllSupers(cls)._'attribute'->asSet() |
| } |
| |
| query umlRdbms::getAllForwards(cls : SimpleUML::Class) : Set(SimpleUML::Association) { |
| getAllSupers(cls).forward->asSet() |
| } |
| |
| map packageToSchema in umlRdbms { |
| check uml () { |
| p:Package | |
| } |
| check enforce rdbms () { |
| s:Schema | |
| } |
| where () { |
| p2s:PackageToSchema |
| | p2s.umlPackage = p; |
| p2s.schema = s; |
| } |
| |
| map { |
| where () { |
| p2s.name := p.name; |
| p2s.name := s.name; |
| p.name := p2s.name; |
| s.name := p2s.name; |
| } |
| } |
| } |
| |
| map primitiveToName in umlRdbms { |
| check uml (p:Package | ) { |
| prim:PrimitiveDataType |
| | prim.namespace = p; |
| } |
| |
| check enforce rdbms () { |
| sqlType:String | |
| } |
| where (p2s:PackageToSchema| p2s.umlPackage=p;) { |
| realize p2n:PrimitiveToName |
| | p2n.owner := p2s; |
| p2n._'primitive' := prim; |
| p2n.typeName := sqlType; |
| } |
| map { |
| where () { |
| p2n.name := prim.name + '2' + sqlType; |
| } |
| } |
| } |
| |
| map integerToNumber in umlRdbms refines primitiveToName { |
| check uml () { |
| prim.name = 'Integer'; |
| } |
| check enforce rdbms () { |
| sqlType := 'NUMBER'; |
| } |
| where () {} |
| } |
| |
| map booleanToBoolean in umlRdbms refines primitiveToName { |
| check uml () { |
| prim.name = 'Boolean'; |
| } |
| check enforce rdbms () { |
| sqlType := 'BOOLEAN'; |
| } |
| where () {} |
| } |
| |
| map stringToVarchar in umlRdbms refines primitiveToName { |
| check uml () { |
| prim.name = 'String'; |
| } |
| check enforce rdbms () { |
| sqlType := 'VARCHAR'; |
| } |
| where () {} |
| } |
| |
| map classToTable in umlRdbms { |
| check enforce uml (p:Package | ) { |
| realize c:Class |
| | c.kind := 'persistent'; |
| c.namespace := p; |
| } |
| check enforce rdbms (s:Schema | ) { |
| realize t:Table |
| | t.kind <> 'meta'; |
| default t.kind := 'base'; |
| t.schema := s; |
| } |
| where (p2s:PackageToSchema |
| | p2s.umlPackage=p; |
| p2s.schema=s; |
| ) { |
| realize c2t:ClassToTable |
| | c2t.owner := p2s; |
| c2t.umlClass := c; |
| c2t.table := t; |
| } |
| map { |
| where () { |
| c2t.name := c.name; |
| c2t.name := t.name; |
| c.name := c2t.name; |
| t.name := c2t.name; |
| } |
| } |
| map { |
| check enforce rdbms () { |
| realize pk:Key, |
| realize pc:Column |
| | pk.owner := t; |
| pk.kind := 'primary'; |
| pc.owner := t; |
| pc.key->includes(pk); |
| default pc.key := Set{pk}; |
| default pc.type := 'NUMBER'; |
| } |
| where () { |
| c2t.primaryKey := pk; |
| c2t.column := pc; |
| } |
| map { |
| check enforce rdbms () { |
| pc.name := t.name+'_tid'; |
| pk.name := t.name+'_pk'; |
| } |
| where () {} |
| } |
| } |
| } |
| |
| map associationToForeignKey in umlRdbms { |
| check enforce uml (p:Package, sc:Class, dc:Class |
| | sc.namespace = p; |
| ) { |
| realize a:Association |
| | getAllForwards(sc)->includes(a); |
| default a.source := sc; |
| getAllSupers(dc)->includes(a.destination); |
| default a.destination := dc; |
| default a.namespace := p; |
| } |
| check enforce rdbms (s:Schema, st:Table, dt:Table, rk:Key |
| | st.schema = s; |
| rk.owner = dt; |
| rk.kind = 'primary'; |
| ) { |
| realize fk:ForeignKey, |
| realize fc:Column |
| | fk.owner := st; |
| fc.owner := st; |
| fk.refersTo := rk; |
| fc.foreignKey->includes(fk); |
| default fc.foreignKey := Set{fk}; |
| } |
| where (p2s:PackageToSchema, sc2t:ClassToTable, dc2t:ClassToTable |
| | sc2t.owner = p2s; |
| p2s.umlPackage = p; |
| p2s.schema = s; |
| sc2t.table = st; |
| dc2t.table = dt; |
| sc2t.umlClass = sc; |
| dc2t.umlClass = dc; |
| ) { |
| realize a2f:AssociationToForeignKey |
| | a2f.owner := sc2t; |
| a2f.referenced := dc2t; |
| a2f.association := a; |
| a2f.foreignKey := fk; |
| a2f.column := fc; |
| } |
| map { |
| where () { |
| a2f.name := 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; |
| a.name := if a.destination=dc and a.source=sc |
| then a2f.name |
| else a.name |
| endif; |
| -- fk.name := name; |
| -- name := fk.name; |
| -- fc.name := name+'_tid'; |
| fk.name := a.name; |
| fc.name := a.name+'_tid'; |
| } |
| } |
| map { |
| where () { |
| fc.type := rk.column->first().type; |
| } |
| } |
| } |
| |
| map attributes in umlRdbms { |
| check enforce uml (c:Class |) { |
| realize a:Attribute |
| | default a.owner := c; |
| getAllAttributes(c)->includes(a); |
| } |
| where (fao:FromAttributeOwner |) { |
| fa : FromAttribute |
| | fa._'attribute' := a; |
| fa.owner := fao; |
| } |
| map { |
| where () { |
| fa.kind := a.kind; |
| a.kind := fa.kind; |
| } |
| } |
| } |
| |
| map classAttributes in umlRdbms refines attributes { |
| where (faco:ClassToTable |
| | faco.umlClass=c; |
| ) {} |
| map { |
| where () { |
| fa.name := a.name; |
| a.name := fa.name; |
| } |
| } |
| } |
| |
| map primitiveAttribute in umlRdbms refines attributes { |
| check enforce uml (t:PrimitiveDataType |) { |
| a.type := t; |
| } |
| where (p2n:PrimitiveToName |
| | p2n._'primitive'=t; |
| ) { |
| realize fpa:AttributeToColumn |
| | fpa.type := p2n; |
| } |
| map { |
| where () { |
| fpa.leafs := Set{fpa}; |
| } |
| } |
| } |
| |
| map complexAttributeAttributes in umlRdbms refines attributes { |
| check uml (ca:Attribute |
| | ca.type=c; |
| ) {} |
| where (faco:NonLeafAttribute |
| | faco._'attribute'=ca; |
| ) {} |
| map { |
| where () { |
| fa.name := faco.name+'_'+a.name; |
| } |
| } |
| } |
| |
| map complexAttribute in umlRdbms refines attributes { |
| check enforce uml (t:Class |) { |
| a.type = t; |
| } |
| where () { |
| realize fca:NonLeafAttribute | |
| } |
| map { |
| where () { |
| fca.leafs := fao.fromAttributes.leafs->asSet(); |
| } |
| } |
| } |
| |
| map classPrimitiveAttributes in umlRdbms refines classAttributes, primitiveAttribute { |
| where () {} |
| } |
| |
| map classComplexAttributes in umlRdbms refines classAttributes, complexAttribute { |
| where () {} |
| } |
| |
| map complexAttributePrimitiveAttributes in umlRdbms refines complexAttributeAttributes, primitiveAttribute { |
| where () {} |
| } |
| |
| map complexAttributeComplexAttributes in umlRdbms refines complexAttributeAttributes, complexAttribute { |
| where () {} |
| } |
| |
| map attributeColumns in umlRdbms { |
| check enforce rdbms (t:Table |) { |
| realize c:Column |
| | c.owner := t; |
| c.key->size()=0; |
| c.foreignKey->size()=0; |
| } |
| where (c2t:ClassToTable| c2t.table=t;) { |
| realize a2c:AttributeToColumn |
| | a2c.column := c; |
| c2t.fromAttributes.leafs->includes(a2c); |
| default a2c.owner := c2t; |
| } |
| map { |
| check enforce rdbms (ct:String |) { |
| c.type := ct; |
| } |
| where (p2n:PrimitiveToName |) { |
| a2c.type := p2n; |
| p2n.typeName := ct; |
| } |
| } |
| map { |
| where () { |
| c.name := a2c.name; |
| a2c.name := c.name; |
| } |
| } |
| map { |
| where () { |
| c.kind := a2c.kind; |
| a2c.kind := c.kind; |
| } |
| } |
| } |