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;
		}
	}
}
