/******************************************************************************* | |
* Copyright (c) 2016 University of York | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* | |
* Contributors: | |
* Horacio Hoyos - Initial API and implementation | |
*******************************************************************************/ | |
rule packageToSchema | |
transform p : uml!Package | |
to s : rdbms!Schema | |
{ | |
s.name = p.name; | |
p.name.println(); | |
} | |
function uml!PrimitiveDataType primitiveToName() : String { | |
switch(self.name) { | |
case 'Integer': return 'NUMBER'; | |
case 'Boolean':return 'BOOLEAN'; | |
case 'String':return 'VARCHAR'; | |
} | |
return ''; | |
} | |
function uml!Class getAllSupers() : Set(uml!Class) | |
{ | |
return self.general.collect(gen | gen.getAllSupers()).flatten().including(self).asSet(); | |
} | |
function uml!Class getAllSubs() : Set(uml!Class) | |
{ | |
return self.generalOpposite.collect(sub | sub.getAllSubs()).including(self).asSet(); | |
} | |
function uml!Class getAllAttributes() : Set(uml!Attribute) | |
{ | |
return self.getAllSupers().collect(c | c.attributes).flatten().asSet(); | |
} | |
function uml!Class getAllComplexAttributes() : Set(uml!Attribute) | |
{ | |
var selfCa = self.getAllAttributes().select(a | a.type.isTypeOf(uml!Class)); | |
return selfCa.includingAll(selfCa | |
.collect(a | a.type.getAllComplexAttributes()).flatten()).asSet(); | |
} | |
function uml!Class getAllForwards() : Set(uml!Association) | |
{ | |
return self.getAllSupers().flatten().collect(c | c.forward).asSet(); | |
} | |
rule classToTable | |
transform c : uml!Class | |
to t : rdbms!Table, pk: rdbms!Key, pc : rdbms!Column | |
{ | |
guard: c.kind == 'persistent' | |
t.kind = 'base'; | |
t.schema ::= c.namespace; | |
t.name = c.name; | |
var tableCols : Map; | |
//c.getAllAttributes().println("Class " + c.name + " "); | |
//c.getAllAttributes().select(a | a.type.isTypeOf(uml!PrimitiveDataType)).println("Class " + c.name + " prim attrs: "); | |
//c.getAllAttributes().select(a | a.type.isTypeOf(uml!PrimitiveDataType)) | |
// .collect(a | a.equivalents()).flatten().println("Class " + c.name + " prim attrs eqs: "); | |
for (colMap in c.getAllAttributes().select(a | a.type.isTypeOf(uml!PrimitiveDataType)) | |
.collect(a | a.equivalents()).flatten()) { | |
for (key in colMap.keySet()) { | |
var cols = tableCols.get(key); | |
if (cols == null) { | |
cols = new Set(); | |
tableCols.put(key, cols); | |
} | |
cols.add(colMap.get(key)); | |
} | |
} | |
//tableCols.println("Class " + c.name + " prim attrs eqs: "); | |
//if (not tableCols.isEmpty()) | |
// t.columns.addAll(tableCols.get(c)); | |
//c.getAllComplexAttributes().println("Class " + c.name + " cmplx "); | |
for (ca in c.getAllComplexAttributes()) { | |
for (colMap in ca.type.getAllAttributes().select(a | a.type.isTypeOf(uml!PrimitiveDataType)) | |
.collect(a | a.equivalents()).flatten()) { | |
for (key in colMap.keySet()) { | |
var cols = tableCols.get(key); | |
if (cols == null) { | |
cols = new Set(); | |
tableCols.put(key, cols); | |
} | |
cols.add(colMap.get(key)); | |
} | |
} | |
} | |
if (not tableCols.isEmpty()) | |
t.columns.addAll(tableCols.get(c)); | |
pk.owner = t; | |
pk.kind = 'primary'; | |
pc.owner = t; | |
pc.keys = Set{pk}; | |
pc.type = 'NUMBER'; | |
pc.name = t.name + '_tid'; | |
pk.name = t.name + '_pk'; | |
} | |
rule associationToForeignKey | |
transform a : uml!Association | |
to fk : rdbms!ForeignKey, fc : rdbms!Column | |
{ | |
guard: (a.source.kind == 'persistent') and (a.destination.kind == 'persistent') | |
var rk = a.destination.equivalents().select(rk | rk.isTypeOf(rdbms!Key)); | |
fk.owner ::= a.source; | |
fk.refersTo = rk; | |
fk.name = a.name; | |
fc.owner ::= a.source; | |
fc.foreignKeys = Set{fk}; | |
fc.name = a.name + '_tid'; | |
fc.type = 'NUMBER'; // We can not access output elements attribs rk.column->first().type; | |
} | |
rule PrimitiveAttributeToColumn | |
transform a : uml!Attribute | |
to cols : Map { | |
guard : a.type.isTypeOf(uml!PrimitiveDataType) | |
//a.owner.getAllSubs().flatten().println(a.name + " used in "); | |
if (a.owner.kind == 'persistent') { | |
for (sub in a.owner.getAllSubs().flatten()) { | |
var col : rdbms!Column = new rdbms!Column; | |
col.name = a.name; | |
col.kind = a.type.primitiveToName(); | |
cols.put(sub, col); | |
} | |
} | |
//a.getAllTypeOpposites().println("ca opposites "); | |
var prefix = ""; | |
for (tOpp in a.getAllTypeOpposites()) { | |
prefix = tOpp.name + "_" + prefix; | |
//prefix.println("prefix "); | |
if (tOpp.owner.kind == 'persistent') { | |
var col : rdbms!Column = new rdbms!Column; | |
col.name = prefix + a.name; | |
col.kind = a.type.primitiveToName(); | |
//col.println("Added to " + tOpp.owner); | |
cols.put(tOpp.owner, col); | |
} | |
} | |
} | |
function uml!Attribute getAllTypeOpposites() : Set(uml!Attribute) | |
{ | |
var result : Set(uml!Attribute); | |
if (self.owner.isTypeOf(uml!Class)) { | |
//self.owner.typeOpposite.println(self + " top "); | |
result.addAll(self.owner.typeOpposite.flatten()); | |
if (not self.owner.typeOpposite.isEmpty()) { | |
result.addAll(self.owner.typeOpposite->collect(top | top.getAllTypeOpposites()).flatten()); | |
} | |
} | |
return result; | |
} | |