blob: 9b78f63ab95c10745db077c4f6ae2b04a9469878 [file] [log] [blame]
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;
}
}
}