| import SimpleUML : 'SimpleUML.ecore#/'; |
| import SimpleRDBMS : 'SimpleRDBMS.ecore#/'; |
| import SimpleUML2RDBMS : 'SimpleUML2RDBMS.ecore#/'; |
| |
| transformation umlRdbms |
| { |
| uml imports SimpleUML; |
| rdbms imports SimpleRDBMS; |
| imports SimpleUML2RDBMS; |
| } |
| /* |
| * -- Package and Schema mapping |
| * class PackageToSchema { |
| * composite classesToTables : Set(ClassToTable) opposites owner; |
| * composite primitivesToNames : Set(PrimitiveToName) opposites owner; |
| * name : String; |
| * -- uml |
| * umlPackage : Package; |
| * -- rdbms |
| * schema : Schema; |
| * } |
| */ |
| map packageToSchema in umlRdbms |
| { |
| uml() { |
| p : SimpleUML::Package[1] |
| |} |
| |
| enforce rdbms() { |
| realize s : SimpleRDBMS::Schema[1] |
| |} |
| |
| where() { |
| realize p2s : SimpleUML2RDBMS::PackageToSchema[1] |
| | |
| p2s.umlPackage := p; |
| p2s.schema := s; |
| } |
| |
| map |
| { |
| |
| where() { |
| p2s.name := p.name; |
| p2s.name := s.name; |
| p.name := p2s.name; |
| s.name := p2s.name; |
| } |
| } |
| } |
| /* |
| * -- Primitive data type marshaling |
| * class PrimitiveToName { |
| * owner : PackageToSchema opposites primitivesToNames; |
| * name : String; |
| * -- uml |
| * primitive : PrimitiveDataType; |
| * -- rdbms |
| * typeName : String; |
| * } |
| */ |
| map primitiveToName in umlRdbms |
| { |
| uml(p : SimpleUML::Package[1] |
| |) { |
| prim : SimpleUML::PrimitiveDataType[1] |
| | |
| prim.namespace = p; |
| } |
| enforce rdbms() { |
| sqlType : String[1] |
| |} |
| |
| where(p2s : SimpleUML2RDBMS::PackageToSchema[1] |
| | |
| p2s.umlPackage = p;) { |
| realize p2n : SimpleUML2RDBMS::PrimitiveToName[1] |
| | |
| p2n.owner := p2s; |
| p2n.primitive := prim; |
| p2n.typeName := sqlType; |
| } |
| |
| } |
| |
| map integerToNumber in umlRdbms refines primitiveToName |
| { |
| uml() { |
| prim.name = 'Integer'; |
| } |
| enforce rdbms() { |
| sqlType := 'NUMBER'; |
| } |
| |
| where() { |
| realize p2n : SimpleUML2RDBMS::IntegerToNumber[1] |
| |} |
| |
| map |
| { |
| |
| where() { |
| p2n.name := prim.name + '2' + 'NUMBER'; |
| } |
| |
| } |
| |
| } |
| |
| map booleanToBoolean in umlRdbms refines primitiveToName |
| { |
| uml() { |
| prim.name = 'Boolean'; |
| } |
| enforce rdbms() { |
| sqlType := 'BOOLEAN'; |
| } |
| |
| where() { |
| realize p2n : SimpleUML2RDBMS::BooleanToBoolean[1] |
| |} |
| |
| map |
| { |
| |
| where() { |
| p2n.name := prim.name + '2' + 'BOOLEAN'; |
| } |
| |
| } |
| |
| } |
| |
| map stringToVarchar in umlRdbms refines primitiveToName |
| { |
| uml() { |
| prim.name = 'String'; |
| } |
| enforce rdbms() { |
| sqlType := 'VARCHAR'; |
| } |
| |
| where() { |
| realize p2n : SimpleUML2RDBMS::StringToVarchar[1] |
| |} |
| |
| map |
| { |
| |
| where() { |
| p2n.name := prim.name + '2' + 'VARCHAR'; |
| } |
| |
| } |
| |
| } |
| |
| map flattening in umlRdbms |
| { |
| |
| where() {} |
| } |
| /* |
| * query umlRdbms::getAllSupers(cls : SimpleUML::Class) : Set(SimpleUML::Class) { |
| * cls.general->collect(gen | getAllSupers(gen))->including(cls)->asSet() |
| * } |
| * |
| * query umlRdbms::getAllAttributes(cls : SimpleUML::Class) : Set( SimpleUML::Attribute) { |
| * getAllSupers(cls)->collect(c | c.attributes) |
| * } |
| * |
| * query umlRdbms::getAllForwards(cls : SimpleUML::Class) : Set( SimpleUML::Association) { |
| * getAllSupers(cls)->collect(c | true) |
| * } |
| */ |
| /* |
| * -- Class and Table mapping |
| * class ClassToTable extends FromAttributeOwner, ToColumn { |
| * owner : PackageToSchema opposites classesToTables; |
| * composite associationToForeignKeys : |
| * OrderedSet(AssociationToForeignKey) opposites owner; |
| * name : String; |
| * -- uml |
| * umlClass : Class; |
| * -- rdbms |
| * table : Table; |
| * primaryKey : Key; |
| * } |
| */ |
| map classToTable in umlRdbms |
| { |
| enforce uml(p : SimpleUML::Package[1] |
| |) { |
| realize c : SimpleUML::Class[1] |
| | |
| c.kind := 'persistent'; |
| c.namespace := p; |
| } |
| |
| enforce rdbms(s : SimpleRDBMS::Schema[1] |
| |) { |
| realize t : SimpleRDBMS::Table[1] |
| | |
| default t.kind := 'base'; |
| t.schema := s; |
| t.kind <> 'meta'; |
| } |
| |
| where(p2s : SimpleUML2RDBMS::PackageToSchema[1] |
| | |
| p2s.umlPackage = p; |
| p2s.schema = s;) { |
| realize c2t : SimpleUML2RDBMS::ClassToTable[1] |
| | |
| 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 |
| { |
| enforce rdbms() { |
| realize pk : SimpleRDBMS::Key[1], |
| realize pc : SimpleRDBMS::Column[1] |
| | |
| pk.owner := t; |
| pk.kind := 'primary'; |
| pc.owner := t; |
| default pc.keys := OrderedSet(SimpleRDBMS::Key[*|1]){pk}; |
| default pc.type := 'NUMBER'; |
| } |
| |
| where() { |
| c2t.primaryKey := pk; |
| c2t.column := pc; |
| } |
| |
| map |
| { |
| enforce rdbms() { |
| pc.name := t.name + '_tid'; |
| pk.name := t.name + '_pk'; |
| } |
| |
| where() {} |
| } |
| |
| } |
| |
| } |
| /* |
| * -- Association and ForeignKey mapping |
| * class AssociationToForeignKey extends ToColumn { |
| * referenced : ClassToTable; |
| * owner : ClassToTable opposites associationToForeignKeys; |
| * name : String; |
| * -- uml |
| * association : Association; |
| * -- rdbms |
| * foreignKey : ForeignKey; |
| * } |
| */ |
| map associationToForeignKey in umlRdbms refines flattening |
| { |
| enforce uml(p : SimpleUML::Package[1], |
| sc : SimpleUML::Class[1], |
| dc : SimpleUML::Class[1] |
| | |
| sc.namespace = p;) { |
| realize a : SimpleUML::Association[1] |
| | |
| default a.source := sc; |
| default a.destination := dc; |
| default a.namespace := p; |
| } |
| enforce rdbms(s : SimpleRDBMS::Schema[1], |
| st : SimpleRDBMS::Table[1], |
| dt : SimpleRDBMS::Table[1], |
| rk : SimpleRDBMS::Key[1] |
| | |
| st.schema = s; |
| rk.owner = dt; |
| rk.kind = 'primary';) { |
| realize fk : SimpleRDBMS::ForeignKey[1], |
| realize fc : SimpleRDBMS::Column[1] |
| | |
| fk.owner := st; |
| fc.owner := st; |
| fk.refersTo := rk; |
| default fc.foreignKeys := OrderedSet(SimpleRDBMS::ForeignKey[*|1]){fk}; |
| } |
| |
| where(p2s : SimpleUML2RDBMS::PackageToSchema[1], |
| sc2t : SimpleUML2RDBMS::ClassToTable[1], |
| dc2t : SimpleUML2RDBMS::ClassToTable[1] |
| | |
| sc2t.owner = p2s; |
| p2s.umlPackage = p; |
| p2s.schema = s; |
| sc2t.table = st; |
| dc2t.table = dt; |
| sc2t.umlClass = sc; |
| dc2t.umlClass = dc;) { |
| realize a2f : SimpleUML2RDBMS::AssociationToForeignKey[1] |
| | |
| a2f.owner := sc2t; |
| a2f.referenced := dc2t; |
| a2f.association := a; |
| a2f.foreignKey := fk; |
| a2f.column := fc; |
| a2f.key := rk; |
| } |
| |
| 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 := a2f.name; |
| a2f.name := fk.name; |
| fc.name := a2f.name + '_tid'; |
| } |
| |
| } |
| |
| map |
| { |
| |
| where() { |
| fc.type := rk.column->first().type; |
| } |
| |
| } |
| |
| } |
| /* |
| * -- attribute mapping |
| * abstract class FromAttributeOwner { |
| * composite fromAttributes : Set(FromAttribute) opposites owner; |
| * } |
| * abstract class FromAttribute { |
| * name : String; |
| * kind : String; |
| * owner : FromAttributeOwner opposites fromAttributes; |
| * leafs : Set(AttributeToColumn); |
| * -- uml |
| * attribute : Attribute; |
| * } |
| * abstract class ToColumn { |
| * -- rdbms |
| * column : Column; |
| * } |
| * class NonLeafAttribute extends FromAttributeOwner, FromAttribute { |
| * leafs := fromAttributes.leafs; |
| * } |
| * class AttributeToColumn extends FromAttribute, ToColumn { |
| * type : PrimitiveToName; |
| * } |
| */ |
| map attributes in umlRdbms refines flattening |
| { |
| enforce uml(c : SimpleUML::Class[1] |
| |) { |
| realize a : SimpleUML::Attribute[1] |
| | |
| default a.owner := c; |
| } |
| |
| where(fao : SimpleUML2RDBMS::FromAttributeOwner[1] |
| |) { |
| realize fa : SimpleUML2RDBMS::FromAttribute[1] |
| | |
| fa.attribute := a; |
| fa.owner := fao; |
| } |
| |
| map |
| { |
| |
| where() { |
| fa.kind := a.kind; |
| a.kind := fa.kind; |
| } |
| } |
| } |
| |
| map classAttributes in umlRdbms refines attributes |
| { |
| |
| where(fao : SimpleUML2RDBMS::ClassToTable[1] |
| | |
| fao.umlClass = c;) {} |
| |
| map |
| { |
| |
| where() { |
| fa.name := a.name; |
| a.name := fa.name; |
| } |
| } |
| |
| } |
| |
| map primitiveAttribute in umlRdbms refines attributes |
| { |
| enforce uml(t : SimpleUML::PrimitiveDataType[1] |
| |) { |
| a.type := t; |
| } |
| |
| where(p2n : SimpleUML2RDBMS::PrimitiveToName[1] |
| | |
| p2n.primitive = t;) { |
| realize fa : SimpleUML2RDBMS::AttributeToColumn[1] |
| | |
| fa.type := p2n; |
| } |
| |
| map |
| { |
| |
| where() { |
| fa.leafs := Set(SimpleUML2RDBMS::AttributeToColumn[*|1]){fa}; |
| } |
| } |
| |
| } |
| |
| map complexAttributeAttributes in umlRdbms refines attributes |
| { |
| check uml(ca : SimpleUML::Attribute[1] |
| | |
| ca.type = c;) {} |
| |
| where(fao : SimpleUML2RDBMS::NonLeafAttribute[1] |
| | |
| fao.attribute = ca;) {} |
| |
| map |
| { |
| |
| where() { |
| fa.name := fao.name + '_' + a.name; |
| } |
| |
| } |
| |
| } |
| |
| map complexAttribute in umlRdbms refines attributes |
| { |
| check uml(t : SimpleUML::Class[1] |
| |) { |
| a.type = t; |
| } |
| |
| where() { |
| realize fa : SimpleUML2RDBMS::NonLeafAttribute[1] |
| |} |
| |
| map |
| { |
| |
| where() { |
| fa.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() {} |
| } |
| /* |
| * -- column mapping |
| */ |
| map attributeColumns in umlRdbms |
| { |
| enforce rdbms(t : SimpleRDBMS::Table[1] |
| |) { |
| realize c : SimpleRDBMS::Column[1] |
| | |
| c.owner := t; |
| c.keys->size() = 0; |
| c.foreignKeys->size() = 0; |
| } |
| |
| where(c2t : SimpleUML2RDBMS::ClassToTable[1] |
| | |
| c2t.table = t;) { |
| realize a2c : SimpleUML2RDBMS::AttributeToColumn[1] |
| | |
| a2c.column := c; |
| default a2c.owner := c2t; |
| c2t.fromAttributes.leafs->includes(a2c); |
| } |
| |
| map |
| { |
| |
| where(p2n : SimpleUML2RDBMS::PrimitiveToName[1] |
| |) { |
| ct : String[1] |
| | |
| a2c.type := p2n; |
| ct := c.type; |
| ct := p2n.typeName; |
| p2n.typeName := ct; |
| c.type := ct; |
| } |
| } |
| |
| map |
| { |
| |
| where() { |
| c.name := a2c.name; |
| a2c.name := c.name; |
| } |
| } |
| |
| map |
| { |
| |
| where() { |
| c.kind := a2c.kind; |
| a2c.kind := c.kind; |
| } |
| } |
| |
| } |