Book a Demo

Author Topic: GUID for newly created class in transformation  (Read 4513 times)

thomaskilian

  • Guest
GUID for newly created class in transformation
« on: February 16, 2006, 03:57:32 am »
Hi there,
does anybody know how to retrieve the GUID of a class that has been created in the transformation process? What I'd like to do is to create a new class N and then associate it with a class A' previously transformed from class A, so it will result in N->A'.
Edit: I just wanted to know in addition whether someone has already managed to create more complex transformations than those provided by Sparx. Not only that the documentation is very meager, but the concept seems to let me run in a dead end very early. I tried a whole day but it wasn't even possible to create an association class I could use for the database from a n-m-association. Rather frustrated :(
« Last Edit: February 16, 2006, 07:10:31 am by thomaskilian »

Eve

  • EA Administrator
  • EA Guru
  • *****
  • Posts: 8110
  • Karma: +119/-20
    • View Profile
Re: GUID for newly created class in transformation
« Reply #1 on: February 16, 2006, 02:49:23 pm »
You can't actually refer to a created class by GUID in the transformation.  It actually doesn't exist yet.  However, if class N is being created from A or a relation to A then you can refer to it using the TRANSFORM_REFERENCE.

Now, I think I know what you're after.  So I'll try a bit of an impromptu tutorial.

Problem description:  The default DDL transform does not create an intersection table for many to many associations in the PIM.  Without this, the generated model isn't much use to you.

Solution: Generate the appropriate intersection table out of any many to many assocations.

The default templates create a foreign key connector out of any associations.  For n-m associations we also need to create another table.

Code: [Select]
%if connectorSourceMultiplicity!="" and connectorSourceMultiplicity!="0" and connectorSourceMultiplicity!="0..1" and connectorSourceMultiplicity!="1"%
$sourceMultiple="T"
%endIf%
%if connectorDestMultiplicity != "" and connectorDestMultiplicity != "0" and connectorDestMultiplicity != "0..1" and connectorDestMultiplicity != "1"%
$destMultiple="T"
%endIf%

%if $sourceMultiple=="T" and $destMultiple=="T"%
$joinKey=%connectorSourceElemName% + "_" + %connectorDestElemName% + "ID"
$joinKey=%CONVERT_NAME($joinKey, "Pascal Case","Camel Case")%
Table
{
 %TRANSFORM_REFERENCE("JoinTable",connectorGUID)%
 name=%qt%Join_%connectorSourceElemName%_%connectorDestElemName%%qt%
 language=%qt%%genOptDefaultDatabase%%qt%
 PrimaryKey
 {
   Column
   {
     name=%qt%$joinKey%qt%
     type=%qt%%CONVERT_TYPE(genOptDefaultDatabase,"Integer")%%qt%
   }
 }
}
%endIf%

All this does is check for the multiplicity of either end and create the appropriate table.  It doesn't create any associations to this table.  The important thing to note is the TRANSFORM_REFERENCE.  This is the unique ID that identifies this join table.  We need to use this to link this table to any other table.

Have a look at how the ForeignKey template creates a link between two existing classes.  In the source and target block it repeats the TRANSFORM_REFERENCE of the classes it is linking to.

So we'll need to know the references to three different tables.

Code: [Select]
$sourceTable=%TRANSFORM_REFERENCE("Table",connectorSourceElemGUID)%
$destTable=%TRANSFORM_REFERENCE("Table",connectorDestElemGUID)%
$joinTable=%TRANSFORM_REFERENCE("JoinTable",connectorGUID)%

If I now modify the ForeignKey template to directly use references given to it, rather than just the source guids.  Then call this template as appropriate.

The following templates are the result, including copying the appropriate multiplicities to the new connectors.

Connector
Code: [Select]
%if connectorType!="Association"%
%endTemplate%

$sourceTable=%TRANSFORM_REFERENCE("Table",connectorSourceElemGUID)%
$destTable=%TRANSFORM_REFERENCE("Table",connectorDestElemGUID)%
%if connectorSourceMultiplicity!="" and connectorSourceMultiplicity!="0" and connectorSourceMultiplicity!="0..1" and connectorSourceMultiplicity!="1"%
$sourceMultiple="T"
%endIf%
%if connectorDestMultiplicity != "" and connectorDestMultiplicity != "0" and connectorDestMultiplicity != "0..1" and connectorDestMultiplicity != "1"%
$destMultiple="T"
%endIf%

$fkdoubleguid=%connectorSourceElemGUID%+%connectorDestElemGUID%
%if $sourceMultiple=="T" and $destMultiple=="T"%
$joinTable=%TRANSFORM_REFERENCE("JoinTable",connectorGUID)%
$joinKey=%connectorSourceElemName% + "_" + %connectorDestElemName% + "ID"
$joinKey=%CONVERT_NAME($joinKey, "Pascal Case","Camel Case")%
Table
{
 $joinTable
 name=%qt%Join_%connectorSourceElemName%_%connectorDestElemName%%qt%
 language=%qt%%genOptDefaultDatabase%%qt%
 PrimaryKey
 {
   Column
   {
     name=%qt%$joinKey%qt%
     type=%qt%%CONVERT_TYPE(genOptDefaultDatabase,"Integer")%%qt%
   }
 }
}
%ForeignKey(connectorGUID,$sourceTable,$joinTable,connectorDestElemName,connectorSourceElemGUID,connectorSourceMultiplicity,"1..1")%
%ForeignKey(connectorGUID,$destTable,$joinTable,connectorSourceElemName,connectorDestElemGUID,connectorDestMultiplicity,"1..1")%
%elseIf $destMultiple=="T"%
%ForeignKey(connectorGUID,$destTable,$sourceTable,connectorSourceElemName,$fkdoubleguid,connectorDestMultiplicity,connectorSourceMultiplicity)%
%else%
%ForeignKey(connectorGUID,$sourceTable,$destTable,connectorDestElemName,$fkdoubleguid,connectorSourceMultiplicity,connectorDestMultiplicity)%
%endIf%

ForeignKey
Code: [Select]
$connectorGUID=$parameter1
$source=$parameter2
$dest=$parameter3
$destName=$parameter4
$referenceName=$parameter5
$sourceMult=$parameter6
$destMult=$parameter7

ForeignKey
%PI="\n  "%
{
%TRANSFORM_REFERENCE($referenceName,$connectorGUID)%
Source
{
 $source
 multiplicity=%qt%$sourceMult%qt%
 Column
 {
   name=%qt%%CONVERT_NAME($destName, "Pascal Case","Camel Case")%ID%qt%
   type=%qt%%CONVERT_TYPE(genOptDefaultDatabase,"Integer")%%qt%
 }
}
Target
{
 $dest
 multiplicity=%qt%$destMult%qt%
 Column
 {
   name=%qt%%CONVERT_NAME($destName, "Pascal Case","Camel Case")%ID%qt%
   type=%qt%%CONVERT_TYPE(genOptDefaultDatabase,"Integer")%%qt%
 }
%PI="\n"%
}
}


Any questions?

thomaskilian

  • Guest
Re: GUID for newly created class in transformation
« Reply #2 on: February 16, 2006, 02:55:06 pm »
Hi Simon,
now you're awake and I have to go to bed :-[

I will have a look tomorrow - seems like a bit of work is waiting for me. Thanks in advance :)

Eve

  • EA Administrator
  • EA Guru
  • *****
  • Posts: 8110
  • Karma: +119/-20
    • View Profile
Re: GUID for newly created class in transformation
« Reply #3 on: February 16, 2006, 05:11:51 pm »
No worries.  I hope it answers your question.

Just in summary (that I should have given before).

To create a connector to any element that you have created you need to use the same TRANSFORM_REFERENCE in either the source or target that was used when defining the class originally.

The following help pages do actually cover this.  (Although they don't give a complicated example like I just did.)
Finally, the templates that I just are a cut down version of what I expect to be included in the DDL transformation not too far away. ;)  The process that I described is pretty much how they were written.
« Last Edit: February 16, 2006, 05:12:00 pm by simonm »

thomaskilian

  • Guest
Re: GUID for newly created class in transformation
« Reply #4 on: February 17, 2006, 03:40:01 am »
Hi Simon,
after some fiddling around I got it working according to your example. Thanks a lot!  :D

However, I'd like to give you some feedback:

- Debugging is 'sub-optimal'. There is no (documented) way to place debug comments in the intermediate file
- The syntax of the intermediate file is not documented (a little BNF would do). The only way to proceed is to trust your feeling and looking at examples
- Typos in macro names are simply ignored  :( At least a message in the intermediate file "Unknown macro %s" should appear
- A colleague of you once asked whether a tutorial for writing code templates is desired, which I affirmed :) Your example now helped me a lot, but a White Paper about codegen/transformation would really be appreciated.

Would be nice if some of above topics is of help for you.

And - keep on with the good work :D
Edit: Typos in variables (e.g. wrong case) are also not reported, but simply ignored. Hope you can do something about these... :-*
« Last Edit: February 20, 2006, 12:59:59 pm by thomaskilian »