Many changes, principally dealing with composite primary keys and foreign entities.

This commit is contained in:
sb 2008-02-06 17:24:53 +00:00
parent d61f36c13d
commit 7f5585d492
4 changed files with 205 additions and 70 deletions

View file

@ -9,8 +9,8 @@
Transform ADL into (partial) controller classes Transform ADL into (partial) controller classes
$Author: sb $ $Author: sb $
$Revision: 1.2 $ $Revision: 1.3 $
$Date: 2008-02-01 21:47:15 $ $Date: 2008-02-06 17:24:53 $
--> -->
<!-- WARNING WARNING WARNING: Do NOT reformat this file! <!-- WARNING WARNING WARNING: Do NOT reformat this file!
@ -40,22 +40,34 @@
If not 'Application', then 'Database'. --> If not 'Application', then 'Database'. -->
<xsl:param name="authentication-layer" select="Application"/> <xsl:param name="authentication-layer" select="Application"/>
<!--
The convention to use for naming auto-generated abstract primary keys. Known values are
Id - the autogenerated primary key, if any, is called just 'Id'
Name - the autogenerated primary key has the same name as the entity
NameId - the name of the auto generated primary key is the name of the entity followed by 'Id'
Name_Id - the name of the auto generated primary key is the name of the entity followed by '_Id'
-->
<xsl:param name="abstract-key-name-convention" select="Id"/>
<xsl:template match="adl:application"> <xsl:template match="adl:application">
<xsl:apply-templates select="adl:entity"/> <xsl:apply-templates select="adl:entity"/>
</xsl:template> </xsl:template>
<xsl:template match="adl:entity"> <!-- Don't bother generating anything for foreign entities -->
<xsl:template match="adl:entity[@foreign='true']"/>
<xsl:template match="adl:entity[adl:form|adl:page|adl:list]">
<!-- what's all this about? the objective is to get the revision number of the <!-- what's all this about? the objective is to get the revision number of the
transform into the output, /without/ getting that revision number overwritten transform into the output, /without/ getting that revision number overwritten
with the revision number of the generated file if the generated file is with the revision number of the generated file if the generated file is
stored to CVS --> stored to CVS -->
<xsl:variable name="transform-rev1" <xsl:variable name="transform-rev1"
select="substring( '$Revision: 1.2 $', 11)"/> select="substring( '$Revision: 1.3 $', 11)"/>
<xsl:variable name="transform-revision" <xsl:variable name="transform-revision"
select="substring( $transform-rev1, 0, string-length( $transform-rev1) - 1)"/> select="substring( $transform-rev1, 0, string-length( $transform-rev1) - 1)"/>
<xsl:variable name="key"> <xsl:variable name="key">
<xsl:call-template name="primary-key"> <xsl:call-template name="primary-key-name">
<xsl:with-param name="entityname" select="@name"/> <xsl:with-param name="entityname" select="@name"/>
</xsl:call-template> </xsl:call-template>
</xsl:variable> </xsl:variable>
@ -109,6 +121,8 @@ namespace <xsl:value-of select="$controllerns"/> {
/// &lt;/summary&gt; /// &lt;/summary&gt;
public partial class <xsl:value-of select="@name"/>Controller : BaseController { public partial class <xsl:value-of select="@name"/>Controller : BaseController {
<xsl:if test="adl:form">
<!-- unless there's at least one form, we won't generate a 'store' method -->
/// &lt;summary&gt; /// &lt;summary&gt;
/// Store the record represented by the parameters passed in an HTTP service /// Store the record represented by the parameters passed in an HTTP service
/// Without Id -&gt; it's new, I create a new persistent object; /// Without Id -&gt; it's new, I create a new persistent object;
@ -124,14 +138,15 @@ namespace <xsl:value-of select="$controllerns"/> {
<xsl:value-of select="$entityns"/>.<xsl:value-of select="@name"/> record; <xsl:value-of select="$entityns"/>.<xsl:value-of select="@name"/> record;
<xsl:apply-templates select="property"/> <xsl:apply-templates select="adl:property"/>
<!-- TODO: this does not corectly handle entities with composite primary keys -->
string id = Form["<xsl:value-of select="concat( 'instance.', $key)"/>"]; string id = Form["<xsl:value-of select="concat( 'instance.', $key)"/>"];
if ( String.IsNullOrEmpty( id)) if ( String.IsNullOrEmpty( id))
{ {
/* it's new, create persistent object */ /* it's new, create persistent object */
record = new <xsl:value-of select="$entityns"/>.<xsl:value-of select="@name"/>(<xsl:for-each select="property[@distinct='system']">Form[<xsl:value-of select="concat( 'instance.', @name)"/>]<xsl:choose> record = new <xsl:value-of select="$entityns"/>.<xsl:value-of select="@name"/>(<xsl:for-each select="adl:property[@distinct='system']">Form[<xsl:value-of select="concat( 'instance.', @name)"/>]<xsl:choose>
<xsl:when test="position() = last()"/> <xsl:when test="position() = last()"/>
<xsl:otherwise>, </xsl:otherwise> <xsl:otherwise>, </xsl:otherwise>
</xsl:choose> </xsl:choose>
@ -145,6 +160,7 @@ namespace <xsl:value-of select="$controllerns"/> {
else else
{ {
/* it's existing, retrieve it */ /* it's existing, retrieve it */
<!-- TODO: this does not corectly handle entities with composite primary keys -->
record = record =
hibernator.CreateCriteria(typeof(<xsl:value-of select="concat( $entityns, '.', @name)"/>)) hibernator.CreateCriteria(typeof(<xsl:value-of select="concat( $entityns, '.', @name)"/>))
.Add(Expression.Eq("<xsl:value-of select="$key"/>", Int32.Parse(id))) .Add(Expression.Eq("<xsl:value-of select="$key"/>", Int32.Parse(id)))
@ -158,13 +174,14 @@ namespace <xsl:value-of select="$controllerns"/> {
/* actually update the record */ /* actually update the record */
BindObjectInstance( record, ParamStore.Form, "instance"); BindObjectInstance( record, ParamStore.Form, "instance");
<xsl:for-each select="property[@type='entity']"> <xsl:for-each select="adl:property[@type='entity']">
/* for properties of type 'entity', it should not be necessary to do anything /* for properties of type 'entity', it should not be necessary to do anything
* special - BindObjectInstance /should/ do it all. Unfortunately it sometimes * special - BindObjectInstance /should/ do it all. Unfortunately it sometimes
* doesn't, and I haven't yet characterised why not. TODO: Fix this! */ * doesn't, and I haven't yet characterised why not. */
<!-- TODO: Fix this! -->
record.<xsl:value-of select="@name"/> = record.<xsl:value-of select="@name"/> =
hibernator.CreateCriteria(typeof(<xsl:value-of select="concat( $entityns, '.', @entity)"/>)) hibernator.CreateCriteria(typeof(<xsl:value-of select="concat( $entityns, '.', @entity)"/>))
.Add(Expression.Eq("<xsl:call-template name="primary-key"> .Add(Expression.Eq("<xsl:call-template name="primary-key-name">
<xsl:with-param name="entityname" select="@entity"/> <xsl:with-param name="entityname" select="@entity"/>
</xsl:call-template>", Int32.Parse(Form["<xsl:value-of select="concat( $entityns, '.', @entity)"/>"]))) </xsl:call-template>", Int32.Parse(Form["<xsl:value-of select="concat( $entityns, '.', @entity)"/>"])))
.UniqueResult&lt;<xsl:value-of select="concat( $entityns, '.', @entity)"/>&gt;(); .UniqueResult&lt;<xsl:value-of select="concat( $entityns, '.', @entity)"/>&gt;();
@ -200,7 +217,7 @@ namespace <xsl:value-of select="$controllerns"/> {
} }
</xsl:for-each> </xsl:for-each>
<xsl:for-each select="property[@type='list']"> <xsl:for-each select="adl:property[@type='list']">
/* with a list we cannot just smash the old values! Instead we need to check /* with a list we cannot just smash the old values! Instead we need to check
* each one and exclude it if no longer required */ * each one and exclude it if no longer required */
if ( Form.GetValues( "<xsl:value-of select="concat( 'instance.', @name)"/>") != null) if ( Form.GetValues( "<xsl:value-of select="concat( 'instance.', @name)"/>") != null)
@ -274,14 +291,18 @@ namespace <xsl:value-of select="$controllerns"/> {
<xsl:call-template name="menus"> <xsl:call-template name="menus">
<xsl:with-param name="entity" select="."/> <xsl:with-param name="entity" select="."/>
</xsl:call-template> </xsl:call-template>
RenderViewWithFailover("<xsl:value-of select="concat( form[position()=1]/@name, '.vm')"/>", "<xsl:value-of select="concat( form[position()=1]/@name, '.auto.vm')"/>"); RenderViewWithFailover("<xsl:value-of select="concat( adl:form[position()=1]/@name, '.vm')"/>",
"<xsl:value-of select="concat( adl:form[position()=1]/@name, '.auto.vm')"/>");
} }
else else
{ {
throw new Exception( String.Format( "No record of type <xsl:value-of select="@name"/> with key value {0} found", id)); throw new Exception( String.Format( "No record of type <xsl:value-of select="@name"/> with key value {0} found", id));
} }
} }
</xsl:if>
<xsl:if test="adl:form">
<!-- unless there's at least one form, we won't generate a 'delete' method -->
/// &lt;summary&gt; /// &lt;summary&gt;
/// Actually delete the selected record /// Actually delete the selected record
/// &lt;/summary&gt; /// &lt;/summary&gt;
@ -318,7 +339,7 @@ namespace <xsl:value-of select="$controllerns"/> {
} }
} }
<xsl:choose> <xsl:choose>
<xsl:when test="list"> <xsl:when test="adl:list">
InternalShowList(); InternalShowList();
</xsl:when> </xsl:when>
<xsl:otherwise> <xsl:otherwise>
@ -326,12 +347,12 @@ namespace <xsl:value-of select="$controllerns"/> {
</xsl:otherwise> </xsl:otherwise>
</xsl:choose> </xsl:choose>
} }
</xsl:if>
<xsl:apply-templates select="adl:form"/>
<xsl:apply-templates select="form"/> <xsl:if test="adl:list">
<xsl:variable name="listname" select="adl:list[position()=1]/@name"/>
<xsl:if test="list"> <xsl:apply-templates select="adl:list"/>
<xsl:variable name="listname" select="list[position()=1]/@name"/>
<xsl:apply-templates select="list"/>
/// &lt;summary&gt; /// &lt;summary&gt;
/// list all instances of this entity to allow the user to select one for editing /// list all instances of this entity to allow the user to select one for editing
/// this method invokes the default list view - which is probably what you want unless /// this method invokes the default list view - which is probably what you want unless
@ -369,7 +390,7 @@ namespace <xsl:value-of select="$controllerns"/> {
} }
</xsl:template> </xsl:template>
<xsl:template match="property[@required='true']"> <xsl:template match="adl:property[@required='true']">
if ( Form[ "<xsl:value-of select="concat( 'instance.', @name)"/>" ] == null) if ( Form[ "<xsl:value-of select="concat( 'instance.', @name)"/>" ] == null)
{ {
AddError( <xsl:choose> AddError( <xsl:choose>
@ -383,13 +404,13 @@ namespace <xsl:value-of select="$controllerns"/> {
</xsl:template> </xsl:template>
<!-- suppress properties otherwise --> <!-- suppress properties otherwise -->
<xsl:template match="property"/> <xsl:template match="adl:property"/>
<xsl:template match="ifmissing"> <xsl:template match="adl:ifmissing">
"<xsl:value-of select="normalize-space(.)"/>" "<xsl:value-of select="normalize-space(.)"/>"
</xsl:template> </xsl:template>
<xsl:template match="form"> <xsl:template match="adl:form">
<xsl:variable name="key"> <xsl:variable name="key">
<xsl:choose> <xsl:choose>
<xsl:when test="../@natural-key"> <xsl:when test="../@natural-key">
@ -496,7 +517,7 @@ namespace <xsl:value-of select="$controllerns"/> {
</xsl:template> </xsl:template>
<xsl:template match="list"> <xsl:template match="adl:list">
/// &lt;summary&gt; /// &lt;summary&gt;
/// list all instances of this entity to allow the user to select one /// list all instances of this entity to allow the user to select one
/// this method invokes the named view. /// this method invokes the named view.
@ -508,22 +529,26 @@ namespace <xsl:value-of select="$controllerns"/> {
</xsl:template> </xsl:template>
<xsl:template match="adl:documentation">
/* <xsl:apply-templates/> */
</xsl:template>
<xsl:template name="menus"> <xsl:template name="menus">
<xsl:param name="entity"/> <xsl:param name="entity"/>
<xsl:for-each select="$entity/property[@type='entity']"> <xsl:for-each select="$entity/adl:property[@type='entity']">
/* produce a list of <xsl:value-of select="@entity"/> to populate the menu for <xsl:value-of select="@name"/> */ /* produce a list of <xsl:value-of select="@entity"/> to populate the menu for <xsl:value-of select="@name"/> */
<xsl:call-template name="menu"> <xsl:call-template name="menu">
<xsl:with-param name="property" select="."/> <xsl:with-param name="property" select="."/>
</xsl:call-template> </xsl:call-template>
</xsl:for-each> </xsl:for-each>
<xsl:for-each select="$entity/property[@type='link']"> <xsl:for-each select="$entity/adl:property[@type='link']">
/* produce a list of <xsl:value-of select="@entity"/> to populate the LHS of the shuffle for <xsl:value-of select="@name"/> */ /* produce a list of <xsl:value-of select="@entity"/> to populate the LHS of the shuffle for <xsl:value-of select="@name"/> */
<xsl:call-template name="menu"> <xsl:call-template name="menu">
<xsl:with-param name="property" select="."/> <xsl:with-param name="property" select="."/>
</xsl:call-template> </xsl:call-template>
</xsl:for-each> </xsl:for-each>
<xsl:for-each select="$entity/property[@type='list']"> <xsl:for-each select="$entity/adl:property[@type='list']">
/* produce a list of <xsl:value-of select="@entity"/> to populate the multi-select for <xsl:value-of select="@name"/> */ /* produce a list of <xsl:value-of select="@entity"/> to populate the multi-select for <xsl:value-of select="@name"/> */
<xsl:call-template name="menu"> <xsl:call-template name="menu">
<xsl:with-param name="property" select="."/> <xsl:with-param name="property" select="."/>
@ -535,22 +560,48 @@ namespace <xsl:value-of select="$controllerns"/> {
<xsl:template name="menu"> <xsl:template name="menu">
<xsl:param name="property"/> <xsl:param name="property"/>
<xsl:variable name="ename" select="$property/@entity"/> <xsl:variable name="ename" select="$property/@entity"/>
<xsl:variable name="entity" select="//entity[@name=$ename]"/> <xsl:variable name="entity" select="//adl:entity[@name=$ename]"/>
PropertyBag["<xsl:value-of select="concat('all_', $property/@name)"/>"] = PropertyBag["<xsl:value-of select="concat('all_', $property/@name)"/>"] =
hibernator.CreateCriteria(typeof(<xsl:value-of select="concat( $entityns, '.', $property/@entity)"/>))<xsl:for-each select="$entity/property[@distinct='user']"> hibernator.CreateCriteria(typeof(<xsl:value-of select="concat( $entityns, '.', $property/@entity)"/>))<xsl:for-each select="$entity/property[@distinct='user']">
<xsl:value-of select="concat('.AddOrder( new Order( &#34;', @name, '&#34;, true))')"/> <xsl:value-of select="concat('.AddOrder( new Order( &#34;', @name, '&#34;, true))')"/>
</xsl:for-each>.List&lt;<xsl:value-of select="concat( $entityns, '.', $property/@entity)"/>&gt;(); </xsl:for-each>.List&lt;<xsl:value-of select="concat( $entityns, '.', $property/@entity)"/>&gt;();
</xsl:template> </xsl:template>
<xsl:template name="primary-key"> <xsl:template name="primary-key-name">
<!-- return the name of the primary key of the entity with this name --> <!-- return the name of the primary key of the entity with this name -->
<xsl:param name="entityname"/> <xsl:param name="entityname"/>
<xsl:choose> <xsl:choose>
<xsl:when test="//entity[@name=$entityname]/@natural-key"> <xsl:when test="//adl:entity[@name=$entityname]/@natural-key">
<xsl:value-of select="//entity[@name=$entityname]/@natural-key"/> <xsl:value-of select="//adl:entity[@name=$entityname]/@natural-key"/>
</xsl:when>
<xsl:when test="//adl:entity[@name=$entityname]/key">
<xsl:choose>
<xsl:when test="count(//adl:entity[@name=$entityname]/adl:key/adl:property) &gt; 1">
<xsl:message terminate="no">
ADL: WARNING: entity '<xsl:value-of select="$entityname"/>' has a compound primary key;
adl2controllerclasses is not yet clever enough to generate appropriate code
</xsl:message>
</xsl:when> </xsl:when>
<xsl:otherwise> <xsl:otherwise>
<xsl:value-of select="concat( $entityname, 'Id')" /> <xsl:value-of select="//adl:entity[@name=$entityname]/adl:key/adl:property[position()=1]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$abstract-key-name-convention='Name'">
<xsl:value-of select="@name"/>
</xsl:when>
<xsl:when test="$abstract-key-name-convention = 'NameId'">
<xsl:value-of select="concat( $entityname, 'Id')"/>
</xsl:when>
<xsl:when test="$abstract-key-name-convention = 'Name_Id'">
<xsl:value-of select="concat( $entityname, '_Id')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'Id'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise> </xsl:otherwise>
</xsl:choose> </xsl:choose>
</xsl:template> </xsl:template>

View file

@ -8,8 +8,8 @@
Transform ADL into entity classes Transform ADL into entity classes
$Author: sb $ $Author: sb $
$Revision: 1.3 $ $Revision: 1.4 $
$Date: 2008-02-01 21:47:15 $ $Date: 2008-02-06 17:24:53 $
--> -->
<!-- WARNING WARNING WARNING: Do NOT reformat this file! <!-- WARNING WARNING WARNING: Do NOT reformat this file!
@ -41,6 +41,9 @@
<xsl:apply-templates select="adl:entity"/> <xsl:apply-templates select="adl:entity"/>
</xsl:template> </xsl:template>
<!-- Don't bother generating anything for foreign entities -->
<xsl:template match="adl:entity[@foreign='true']"/>
<xsl:template match="adl:entity"> <xsl:template match="adl:entity">
<xsl:message terminate="no">Matched entity with name <xsl:value-of select="@name"/> <xsl:message terminate="no">Matched entity with name <xsl:value-of select="@name"/>
</xsl:message> </xsl:message>
@ -50,7 +53,7 @@
stored to CVS --> stored to CVS -->
<xsl:variable name="transform-rev1" <xsl:variable name="transform-rev1"
select="substring( '$Revision: 1.3 $', 11)"/> select="substring( '$Revision: 1.4 $', 11)"/>
<xsl:variable name="transform-revision" <xsl:variable name="transform-revision"
select="substring( $transform-rev1, 0, string-length( $transform-rev1) - 1)"/> select="substring( $transform-rev1, 0, string-length( $transform-rev1) - 1)"/>
@ -108,7 +111,7 @@
/* natural primary key exists - not generating abstract key */ /* natural primary key exists - not generating abstract key */
</xsl:when> </xsl:when>
<xsl:when test="adl:key"> <xsl:when test="adl:key">
/* composite promary key exists - not generating abstract key */ /* primary key exists - not generating abstract key */
/// &lt;summary&gt; /// &lt;summary&gt;
/// Auto-generated constructor; initialises each of the slots within /// Auto-generated constructor; initialises each of the slots within

View file

@ -12,17 +12,26 @@
Convert ADL to MS-SQL Convert ADL to MS-SQL
$Author: sb $ $Author: sb $
$Revision: 1.3 $ $Revision: 1.4 $
--> -->
<xsl:output indent="no" encoding="utf-8" method="text"/> <xsl:output indent="no" encoding="utf-8" method="text"/>
<xsl:include href="base-type-include.xslt"/> <xsl:include href="base-type-include.xslt"/>
<!--
The convention to use for naming auto-generated abstract primary keys. Known values are
Id - the autogenerated primary key, if any, is called just 'Id'
Name - the autogenerated primary key has the same name as the entity
NameId - the name of the auto generated primary key is the name of the entity followed by 'Id'
Name_Id - the name of the auto generated primary key is the name of the entity followed by '_Id'
-->
<xsl:param name="abstract-key-name-convention" select="Id"/>
<xsl:template match="adl:application"> <xsl:template match="adl:application">
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
-- --
-- Database for application <xsl:value-of select="@name"/> version <xsl:value-of select="@version"/> -- Database for application <xsl:value-of select="@name"/> version <xsl:value-of select="@version"/>
-- Generated for MS-SQL 2000+ using adl2mssql.xsl $Revision: 1.3 $ -- Generated for MS-SQL 2000+ using adl2mssql.xsl $Revision: 1.4 $
-- --
-- Code generator (c) 2007 Cygnet Solutions Ltd -- Code generator (c) 2007 Cygnet Solutions Ltd
-- --
@ -46,7 +55,7 @@
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
-- primary referential integrity constraints -- primary referential integrity constraints
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
<xsl:for-each select="adl:entity"> <xsl:for-each select="adl:entity[ not(@foreign='true')]">
<xsl:variable name="nearside" select="@name"/> <xsl:variable name="nearside" select="@name"/>
<xsl:for-each select="property[@type='entity']"> <xsl:for-each select="property[@type='entity']">
<xsl:variable name="farside" select="@entity"/> <xsl:variable name="farside" select="@entity"/>
@ -116,10 +125,12 @@
GO GO
</xsl:template> </xsl:template>
<!-- don't generate foreign tables - although we will generate ref integ constraints for them -->
<xsl:template match="adl:entity[@foreign='true']" mode="table"/>
<xsl:template match="adl:entity" mode="table"> <xsl:template match="adl:entity" mode="table">
<xsl:variable name="table" select="@name"/> <xsl:variable name="table">
<!-- xsl:choose> <xsl:choose>
<xsl:when test="@table"> <xsl:when test="@table">
<xsl:value-of select="@table"/> <xsl:value-of select="@table"/>
</xsl:when> </xsl:when>
@ -127,12 +138,12 @@
<xsl:value-of select="@name"/> <xsl:value-of select="@name"/>
</xsl:otherwise> </xsl:otherwise>
</xsl:choose> </xsl:choose>
</xsl:variable --> </xsl:variable>
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
-- primary table <xsl:value-of select="@name"/> -- primary table <xsl:value-of select="$table"/>
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
CREATE TABLE "<xsl:value-of select="@name"/>" CREATE TABLE "<xsl:value-of select="$table"/>"
( (
<xsl:for-each select="descendant::adl:property[@type!='link' and @type != 'list']"> <xsl:for-each select="descendant::adl:property[@type!='link' and @type != 'list']">
<xsl:apply-templates select="."/><xsl:if test="position() != last()">,</xsl:if> <xsl:apply-templates select="."/><xsl:if test="position() != last()">,</xsl:if>
@ -376,7 +387,12 @@
</xsl:template> </xsl:template>
<xsl:template match="adl:property[@type='serial']"> <xsl:template match="adl:property[@type='serial']">
<xsl:value-of select="@name"/><xsl:text> INT IDENTITY( 1, 1)</xsl:text> <xsl:call-template name="property-name">
<xsl:with-param name="property" select="."/>
</xsl:call-template><xsl:text> INT IDENTITY( 1, 1)</xsl:text>
<xsl:message terminate="no">
ADL: WARNING: type='serial' is deprecated; add a generator with type='native' instead
</xsl:message>
</xsl:template> </xsl:template>
<xsl:template match="adl:generator[@action='native']"> <xsl:template match="adl:generator[@action='native']">
@ -387,6 +403,11 @@
<!-- the grand unified property handler, using the sql-type template to <!-- the grand unified property handler, using the sql-type template to
generate the correct types for each field --> generate the correct types for each field -->
<xsl:template match="adl:property"> <xsl:template match="adl:property">
<xsl:variable name="column">
<xsl:call-template name="property-name">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="type"> <xsl:variable name="type">
<xsl:call-template name="sql-type"> <xsl:call-template name="sql-type">
<xsl:with-param name="property" select="."/> <xsl:with-param name="property" select="."/>
@ -400,7 +421,7 @@
<xsl:variable name="generator"> <xsl:variable name="generator">
<xsl:apply-templates select="adl:generator"/> <xsl:apply-templates select="adl:generator"/>
</xsl:variable> </xsl:variable>
"<xsl:value-of select="@name"/>" <xsl:value-of "<xsl:value-of select="$column"/>" <xsl:value-of
select="concat( normalize-space( $type), ' ', normalize-space( $generator))"/><xsl:if select="concat( normalize-space( $type), ' ', normalize-space( $generator))"/><xsl:if
test="@required='true'"> NOT NULL</xsl:if><xsl:if test="@required='true'"> NOT NULL</xsl:if><xsl:if
test="string(@default)"> DEFAULT <xsl:choose> test="string(@default)"> DEFAULT <xsl:choose>
@ -418,17 +439,74 @@
sure why. So temporarily this special case template fixes the problem. TODO: sure why. So temporarily this special case template fixes the problem. TODO:
work out what's wrong with the grand unified version --> work out what's wrong with the grand unified version -->
<xsl:template match="adl:property[@type='entity']"> <xsl:template match="adl:property[@type='entity']">
<xsl:variable name="column">
<xsl:call-template name="property-name">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="type"> <xsl:variable name="type">
<xsl:call-template name="sql-type"> <xsl:call-template name="sql-type">
<xsl:with-param name="property" select="."/> <xsl:with-param name="property" select="."/>
</xsl:call-template> </xsl:call-template>
</xsl:variable> </xsl:variable>
"<xsl:value-of select="@name"/>" <xsl:value-of select="$type"/><xsl:if "<xsl:value-of select="$column"/>" <xsl:value-of select="$type"/><xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if> test="@required='true'"> NOT NULL</xsl:if>
</xsl:template> </xsl:template>
<!-- consistent, repeatable way of getting the column name for a given property -->
<xsl:template name="property-name">
<xsl:param name="property"/>
<xsl:choose>
<xsl:when test="$property/@column">
<xsl:value-of select="$property/@column"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$property/@name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="primary-key-name">
<!-- return the name of the primary key of the entity with this name -->
<xsl:param name="entityname"/>
<xsl:choose>
<xsl:when test="//adl:entity[@name=$entityname]/@natural-key">
<xsl:value-of select="//adl:entity[@name=$entityname]/@natural-key"/>
</xsl:when>
<xsl:when test="//adl:entity[@name=$entityname]/key">
<xsl:choose>
<xsl:when test="count(//adl:entity[@name=$entityname]/adl:key/adl:property) &gt; 1">
<xsl:message terminate="no">
ADL: WARNING: entity '<xsl:value-of select="$entityname"/>' has a compound primary key;
adl2mssql is not yet clever enough to generate appropriate code
</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="//adl:entity[@name=$entityname]/adl:key/adl:property[position()=1]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$abstract-key-name-convention='Name'">
<xsl:value-of select="@name"/>
</xsl:when>
<xsl:when test="$abstract-key-name-convention = 'NameId'">
<xsl:value-of select="concat( $entityname, 'Id')"/>
</xsl:when>
<xsl:when test="$abstract-key-name-convention = 'Name_Id'">
<xsl:value-of select="concat( $entityname, '_Id')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'Id'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- return the SQL type of the property which is passed as a parameter --> <!-- return the SQL type of the property which is passed as a parameter -->
<xsl:template name="sql-type"> <xsl:template name="sql-type">
<xsl:param name="property"/> <xsl:param name="property"/>

View file

@ -9,8 +9,8 @@
Transform ADL into velocity view templates Transform ADL into velocity view templates
$Author: sb $ $Author: sb $
$Revision: 1.1 $ $Revision: 1.2 $
$Date: 2008-01-31 17:06:35 $ $Date: 2008-02-06 17:24:53 $
--> -->
<!-- WARNING WARNING WARNING: Do NOT reformat this file! <!-- WARNING WARNING WARNING: Do NOT reformat this file!
Whitespace (or lack of it) is significant! --> Whitespace (or lack of it) is significant! -->
@ -31,7 +31,7 @@
stored to CVS --> stored to CVS -->
<xsl:variable name="transform-rev1" <xsl:variable name="transform-rev1"
select="substring( '$Revision: 1.1 $', 11)"/> select="substring( '$Revision: 1.2 $', 11)"/>
<xsl:variable name="transform-revision" <xsl:variable name="transform-revision"
select="substring( $transform-rev1, 0, string-length( $transform-rev1) - 1)"/> select="substring( $transform-rev1, 0, string-length( $transform-rev1) - 1)"/>
@ -45,6 +45,9 @@
</output> </output>
</xsl:template> </xsl:template>
<xsl:template match="entity[@foreign='true']"/>
<!-- Don't bother generating anything for foreign entities -->
<xsl:template match="entity"> <xsl:template match="entity">
<xsl:apply-templates select="form"/> <xsl:apply-templates select="form"/>
<xsl:apply-templates select="list"/> <xsl:apply-templates select="list"/>