More work on the framework - now up to the point that I can auto-generate SQL with compound primary keys, and the other features required by Andrew.

This commit is contained in:
sb 2008-02-01 18:25:38 +00:00
parent d52a3d5653
commit 07b10ab336
5 changed files with 265 additions and 93 deletions

View file

@ -13,7 +13,7 @@
<!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --> <!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<!-- <!--
$Revision: 1.6 $ $Revision: 1.7 $
--> -->
<!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --> <!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
@ -82,8 +82,15 @@
char(1) java.sql.Types.CHAR char(1) java.sql.Types.CHAR
text: text or java.sql.Types.LONGVARCHAR text: text or java.sql.Types.LONGVARCHAR
memo java.sql.Types.CLOB memo java.sql.Types.CLOB
Also, a hack, which may not belong here:
serial: An integer whose value is automatically assigned by the database. Given
that Canonical ADL requires that every key must be specified, we
need a way of distinguishing those which are system generated from
those which aren't. This may not be the right way to do it!
--> -->
<!ENTITY % SimpleDataTypes "%DefinableDataTypes;|boolean|text" > <!ENTITY % SimpleDataTypes "%DefinableDataTypes;|boolean|text|serial" >
<!-- <!--
data types which are more complex than SimpleDataTypes... data types which are more complex than SimpleDataTypes...

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<!-- <!--
C1873 SRU Hospitality Application Description Language framework
adl2canonical.xsl adl2canonical.xsl
(c) 2007 Cygnet Solutions Ltd (c) 2007 Cygnet Solutions Ltd
@ -16,17 +16,17 @@
are generated. are generated.
$Author: sb $ $Author: sb $
$Revision: 1.1 $ $Revision: 1.2 $
$Date: 2008-02-01 12:43:18 $ $Date: 2008-02-01 18:25:38 $
--> -->
<xsl:stylesheet version="1.0" <xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:exsl="http://exslt.org/common"
xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2" xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="adl">
<xsl:output encoding="UTF-8" method="text"/> <xsl:output encoding="UTF-8" indent="yes" method="xml" />
<!-- <!--
The convention to use for naming auto-generated abstract primary keys. Known values are The convention to use for naming auto-generated abstract primary keys. Known values are
@ -36,13 +36,8 @@
Name_Id - 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:param name="abstract-key-name-convention" select="Id"/>
<xsl:param name="locale" select="en-UK"/>
<xsl:template match="adl:application"> <xsl:template match="adl:application">
<xsl:message terminate="no">
Abstract key naming convention selected is '<xsl:value-of select="$abstract-key-name-convention"/>'
Locale selected is '<xsl:value-of select="$locale"/>'
</xsl:message>
<xsl:copy> <xsl:copy>
<xsl:comment> <xsl:comment>
*************************************************************************** ***************************************************************************
@ -52,7 +47,7 @@
* THIS FILE IS AUTOMATICALLY GENERATED AND SHOULD NOT * THIS FILE IS AUTOMATICALLY GENERATED AND SHOULD NOT
* BE MANUALLY EDITED. * BE MANUALLY EDITED.
* *
* Generated using adl2canonical.xsl revision <xsl:value-of select="substring('$Revision: 1.1 $', 12)"/> * Generated using adl2canonical.xsl revision <xsl:value-of select="substring('$Revision: 1.2 $', 12)"/>
* *
*************************************************************************** ***************************************************************************
</xsl:comment> </xsl:comment>
@ -61,20 +56,21 @@
</xsl:template> </xsl:template>
<!-- an entity which already has a key tag - just copy it through --> <!-- an entity which already has a key tag - just copy it through -->
<xsl:template match="adl:entity[key]"> <xsl:template match="adl:entity[adl:key]">
<xsl:comment> <xsl:comment>
entity <xsl:value-of select="@name"/> already has a key - not generating one entity <xsl:value-of select="@name"/> already has a key - not generating one
</xsl:comment> </xsl:comment>
<adl:entity> <entity>
<xsl:apply-templates select="@* | node()"/> <xsl:apply-templates select="@* | node()"/>
</adl:entity> </entity>
</xsl:template> </xsl:template>
<!-- an entity which has a '@natural-key' attribute. <!-- an entity which has a '@natural-key' attribute.
Since we've got the key tag, I think this should be disallowed --> Since we've got the key tag, I think this should be disallowed -->
<xsl:template match="adl:entity[@natural-key]"> <xsl:template match="adl:entity[@natural-key]">
<xsl:message terminate="no">'@natural-key' is deprecated - use the 'key' sub element instead</xsl:message> <xsl:message terminate="no">
<adl:entity> [In entity '<xsl:value-of select="@name"/>']: '@natural-key' is deprecated - use the 'key' sub element instead</xsl:message>
<entity>
<xsl:variable name="nkey" select="@natural-key"/> <xsl:variable name="nkey" select="@natural-key"/>
<xsl:apply-templates select="@*"/> <xsl:apply-templates select="@*"/>
<!-- children copied through in legal order, to ensure the document remains valid --> <!-- children copied through in legal order, to ensure the document remains valid -->
@ -87,7 +83,7 @@
<xsl:apply-templates select="adl:property[not(@name=$nkey)] | adl:one-to-many | adl:many-to-many | adl:many-to-one"/> <xsl:apply-templates select="adl:property[not(@name=$nkey)] | adl:one-to-many | adl:many-to-many | adl:many-to-one"/>
<xsl:apply-templates select="adl:permission"/> <xsl:apply-templates select="adl:permission"/>
<xsl:apply-templates select="adl:form | adl:page | adl:list"/> <xsl:apply-templates select="adl:form | adl:page | adl:list"/>
</adl:entity> </entity>
</xsl:template> </xsl:template>
<!-- an entity which has no explicit key: auto-generate one --> <!-- an entity which has no explicit key: auto-generate one -->
@ -95,13 +91,13 @@
<xsl:comment> <xsl:comment>
entity <xsl:value-of select="@name"/> has no key - generating one entity <xsl:value-of select="@name"/> has no key - generating one
</xsl:comment> </xsl:comment>
<adl:entity> <entity>
<!-- copy attributes through --> <!-- copy attributes through -->
<xsl:apply-templates select="@*"/> <xsl:apply-templates select="@*"/>
<!-- children copied through in legal order, to ensure the document remains valid --> <!-- children copied through in legal order, to ensure the document remains valid -->
<xsl:apply-templates select="adl:documentation"/> <xsl:apply-templates select="adl:documentation"/>
<xsl:apply-templates select="adl:content"/> <xsl:apply-templates select="adl:content"/>
<adl:key> <key>
<!-- autogenerate a key element... --> <!-- autogenerate a key element... -->
<!-- select a name... --> <!-- select a name... -->
<xsl:variable name="key"> <xsl:variable name="key">
@ -133,23 +129,23 @@
</xsl:if> </xsl:if>
<!-- generate one property, the abstract primary key --> <!-- generate one property, the abstract primary key -->
<adl:property type="integer" distinct="system"> <property type="serial" distinct="system">
<xsl:attribute name="name"> <xsl:attribute name="name">
<xsl:value-of select="normalize-space( $key)"/> <xsl:value-of select="normalize-space( $key)"/>
</xsl:attribute> </xsl:attribute>
</adl:property> </property>
</adl:key> </key>
<xsl:apply-templates select="adl:property | adl:one-to-many | adl:many-to-many | adl:many-to-one"/> <xsl:apply-templates select="adl:property | adl:one-to-many | adl:many-to-many | adl:many-to-one"/>
<xsl:apply-templates select="adl:permission"/> <xsl:apply-templates select="adl:permission"/>
<xsl:apply-templates select="adl:form | adl:page | adl:list"/> <xsl:apply-templates select="adl:form | adl:page | adl:list"/>
</adl:entity> </entity>
</xsl:template> </xsl:template>
<!-- If properties='all', unroll them into a properties='listed' form. <!-- If properties='all', unroll them into a properties='listed' form.
We need to do this for lists, pages and forms; there's probably some clever We need to do this for lists, pages and forms; there's probably some clever
way of doing it all in a oner, but I don't know what that is --> way of doing it all in a oner, but I don't know what that is -->
<xsl:template match="adl:form[ @properties='all']"> <xsl:template match="adl:form[ @properties='all']">
<adl:form properties='listed'> <form properties='listed'>
<!-- copy the name attribute through --> <!-- copy the name attribute through -->
<xsl:apply-templates select="@name"/> <xsl:apply-templates select="@name"/>
<!-- children copied through in legal order, to ensure the document remains valid --> <!-- children copied through in legal order, to ensure the document remains valid -->
@ -159,14 +155,14 @@
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field| <xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
adl:fieldgroup|adl:auxlist|adl:verb| adl:fieldgroup|adl:auxlist|adl:verb|
adl:permission|adl:pragma"/> adl:permission|adl:pragma"/>
</adl:form> </form>
</xsl:template> </xsl:template>
<!-- If properties='all', unroll them into a properties='listed' form. <!-- If properties='all', unroll them into a properties='listed' form.
We need to do this for lists, pages and forms; there's probably some clever We need to do this for lists, pages and forms; there's probably some clever
way of doing it all in a oner, but I don't know what that is --> way of doing it all in a oner, but I don't know what that is -->
<xsl:template match="adl:page[ @properties='all']"> <xsl:template match="adl:page[ @properties='all']">
<adl:page properties='listed'> <page properties='listed'>
<!-- copy the name attribute through --> <!-- copy the name attribute through -->
<xsl:apply-templates select="@name"/> <xsl:apply-templates select="@name"/>
<!-- children copied through in legal order, to ensure the document remains valid --> <!-- children copied through in legal order, to ensure the document remains valid -->
@ -176,14 +172,14 @@
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field| <xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
adl:fieldgroup|adl:auxlist|adl:verb| adl:fieldgroup|adl:auxlist|adl:verb|
adl:permission|adl:pragma"/> adl:permission|adl:pragma"/>
</adl:page> </page>
</xsl:template> </xsl:template>
<!-- If properties='all', unroll them into a properties='listed' form. <!-- If properties='all', unroll them into a properties='listed' form.
We need to do this for lists, pages and forms; there's probably some clever We need to do this for lists, pages and forms; there's probably some clever
way of doing it all in a oner, but I don't know what that is --> way of doing it all in a oner, but I don't know what that is -->
<xsl:template match="adl:list[ @properties='all']"> <xsl:template match="adl:list[ @properties='all']">
<adl:list properties='listed'> <list properties='listed'>
<!-- copy the name attribute through --> <!-- copy the name attribute through -->
<xsl:apply-templates select="@name"/> <xsl:apply-templates select="@name"/>
<!-- children copied through in legal order, to ensure the document remains valid --> <!-- children copied through in legal order, to ensure the document remains valid -->
@ -193,13 +189,13 @@
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field| <xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
adl:fieldgroup|adl:auxlist|adl:verb| adl:fieldgroup|adl:auxlist|adl:verb|
adl:permission|adl:pragma"/> adl:permission|adl:pragma"/>
</adl:list> </list>
</xsl:template> </xsl:template>
<!-- In practice it's likely only to be lists which have properties='user-distinct', <!-- In practice it's likely only to be lists which have properties='user-distinct',
but the grammar allows this for pages and forms as well so we'll deal with it --> but the grammar allows this for pages and forms as well so we'll deal with it -->
<xsl:template match="adl:form[ @properties='user-distinct']"> <xsl:template match="adl:form[ @properties='user-distinct']">
<adl:form properties='listed'> <form properties='listed'>
<!-- copy the name attribute through --> <!-- copy the name attribute through -->
<xsl:apply-templates select="@name"/> <xsl:apply-templates select="@name"/>
<!-- children copied through in legal order, to ensure the document remains valid --> <!-- children copied through in legal order, to ensure the document remains valid -->
@ -209,13 +205,13 @@
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field| <xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
adl:fieldgroup|adl:auxlist|adl:verb| adl:fieldgroup|adl:auxlist|adl:verb|
adl:permission|adl:pragma"/> adl:permission|adl:pragma"/>
</adl:form> </form>
</xsl:template> </xsl:template>
<!-- In practice it's likely only to be lists which have properties='user-distinct', <!-- In practice it's likely only to be lists which have properties='user-distinct',
but the grammar allows this for pages and forms as well so we'll deal with it --> but the grammar allows this for pages and forms as well so we'll deal with it -->
<xsl:template match="adl:page[ @properties='user-distinct']"> <xsl:template match="adl:page[ @properties='user-distinct']">
<adl:page properties='listed'> <page properties='listed'>
<!-- copy the name attribute through --> <!-- copy the name attribute through -->
<xsl:apply-templates select="@name"/> <xsl:apply-templates select="@name"/>
<!-- children copied through in legal order, to ensure the document remains valid --> <!-- children copied through in legal order, to ensure the document remains valid -->
@ -225,14 +221,14 @@
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field| <xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
adl:fieldgroup|adl:auxlist|adl:verb| adl:fieldgroup|adl:auxlist|adl:verb|
adl:permission|adl:pragma"/> adl:permission|adl:pragma"/>
</adl:page> </page>
</xsl:template> </xsl:template>
<!-- In practice it's likely only to be lists which have properties='user-distinct', <!-- In practice it's likely only to be lists which have properties='user-distinct',
but the grammar allows this for pages and forms as well so we'll deal with it --> but the grammar allows this for pages and forms as well so we'll deal with it -->
<xsl:template match="adl:list[ @properties='user-distinct']"> <xsl:template match="adl:list[ @properties='user-distinct']">
<adl:list properties='listed'> <list properties='listed'>
<!-- copy the name attribute through --> <!-- copy the name attribute through -->
<xsl:apply-templates select="@name"/> <xsl:apply-templates select="@name"/>
<!-- children copied through in legal order, to ensure the document remains valid --> <!-- children copied through in legal order, to ensure the document remains valid -->
@ -242,7 +238,7 @@
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field| <xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
adl:fieldgroup|adl:auxlist|adl:verb| adl:fieldgroup|adl:auxlist|adl:verb|
adl:permission|adl:pragma"/> adl:permission|adl:pragma"/>
</adl:list> </list>
</xsl:template> </xsl:template>
<!-- unroll all the explicit properties in the ancestor entity of <!-- unroll all the explicit properties in the ancestor entity of
@ -252,11 +248,11 @@
ancestor::adl:entity/descendant::adl:one-to-many | ancestor::adl:entity/descendant::adl:one-to-many |
ancestor::adl:entity/descendant::adl:many-to-many | ancestor::adl:entity/descendant::adl:many-to-many |
ancestor::adl:entity/descendant::adl:many-to-one"> ancestor::adl:entity/descendant::adl:many-to-one">
<adl:field> <field>
<xsl:attribute name="property"> <xsl:attribute name="property">
<xsl:value-of select="@name"/> <xsl:value-of select="@name"/>
</xsl:attribute> </xsl:attribute>
</adl:field> </field>
</xsl:for-each> </xsl:for-each>
</xsl:template> </xsl:template>
@ -266,14 +262,33 @@
therefore not inspected --> therefore not inspected -->
<xsl:template name="unroll-user-distinct"> <xsl:template name="unroll-user-distinct">
<xsl:for-each select="ancestor::adl:entity/descendant::adl:property[@distinct='user']"> <xsl:for-each select="ancestor::adl:entity/descendant::adl:property[@distinct='user']">
<adl:field> <field>
<xsl:attribute name="property"> <xsl:attribute name="property">
<xsl:value-of select="@name"/> <xsl:value-of select="@name"/>
</xsl:attribute> </xsl:attribute>
</adl:field> </field>
</xsl:for-each> </xsl:for-each>
</xsl:template> </xsl:template>
<!-- Language constraints -->
<xsl:template match="property[ @type = 'string' and not( number( @size))]">
<xsl:message terminate="yes">
ADL ERROR: Properties of type 'string' must have a valid value for 'size'
</xsl:message>
</xsl:template>
<xsl:template match="property[ @type = 'entity' and not( @entity)]">
<xsl:message terminate="yes">
ADL ERROR: Properties of type 'entity' must have a valid value for 'entity'
</xsl:message>
</xsl:template>
<xsl:template match="property[ @type = 'defined' and not( @typedef)]">
<xsl:message terminate="yes">
ADL ERROR: Properties of type 'defined' must have a valid value for 'typedef'
</xsl:message>
</xsl:template>
<!-- copy anything that isn't explicitly matched --> <!-- copy anything that isn't explicitly matched -->
<xsl:template match="@* | node()"> <xsl:template match="@* | node()">

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!-- <!--
C1873 SRU Hospitality Application Description Language framework
adl2entityclass.xsl adl2entityclass.xsl
(c) 2007 Cygnet Solutions Ltd (c) 2007 Cygnet Solutions Ltd
@ -8,8 +8,8 @@
Transform ADL into entity classes Transform ADL into entity classes
$Author: sb $ $Author: sb $
$Revision: 1.1 $ $Revision: 1.2 $
$Date: 2008-01-31 17:06:35 $ $Date: 2008-02-01 18:25:38 $
--> -->
<!-- WARNING WARNING WARNING: Do NOT reformat this file! <!-- WARNING WARNING WARNING: Do NOT reformat this file!
@ -47,7 +47,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)"/>

View file

@ -1,5 +1,8 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:stylesheet version="1.0"
xmlns="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- <!--
C1873 SRU Hospitality C1873 SRU Hospitality
adl2mssql.xsl adl2mssql.xsl
@ -9,16 +12,17 @@
Convert ADL to MS-SQL Convert ADL to MS-SQL
$Author: sb $ $Author: sb $
$Revision: 1.1 $ $Revision: 1.2 $
--> -->
<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:template match="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.1 $ -- Generated for MS-SQL 2000+ using adl2mssql.xsl $Revision: 1.2 $
-- --
-- Code generator (c) 2007 Cygnet Solutions Ltd -- Code generator (c) 2007 Cygnet Solutions Ltd
-- --
@ -27,23 +31,23 @@
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
-- authentication roles -- authentication roles
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
<xsl:apply-templates select="group"/> <xsl:apply-templates select="adl:group"/>
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
-- tables, views and permissions -- tables, views and permissions
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
<xsl:apply-templates select="entity" mode="table"/> <xsl:apply-templates select="adl:entity" mode="table"/>
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
-- referential integrity constraints -- referential integrity constraints
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
<xsl:for-each select="entity"> <xsl:for-each select="adl:entity">
<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"/>
<xsl:variable name="keyfield" select="@name"/> <xsl:variable name="keyfield" select="@name"/>
<xsl:choose> <xsl:choose>
<xsl:when test="//entity[@name=$farside]/property[@farkey=$keyfield and @entity=$nearside]"> <xsl:when test="//adl:entity[@name=$farside]/adl:property[@farkey=$keyfield and @entity=$nearside]">
<!-- there's a 'list' property pointing the other way; let it do the heavy hauling --> <!-- there's a 'list' property pointing the other way; let it do the heavy hauling -->
</xsl:when> </xsl:when>
<xsl:otherwise> <xsl:otherwise>
@ -55,7 +59,7 @@
</xsl:otherwise> </xsl:otherwise>
</xsl:choose> </xsl:choose>
</xsl:for-each> </xsl:for-each>
<xsl:for-each select="property[@type='list']"> <xsl:for-each select="adl:property[@type='list']">
<xsl:variable name="farkey"> <xsl:variable name="farkey">
<xsl:choose> <xsl:choose>
<xsl:when test="@farkey"> <xsl:when test="@farkey">
@ -87,7 +91,7 @@
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
</xsl:template> </xsl:template>
<xsl:template match="group"> <xsl:template match="adl:group">
execute sp_addrole @rolename = '<xsl:value-of select="@name"/>' execute sp_addrole @rolename = '<xsl:value-of select="@name"/>'
GO GO
@ -108,22 +112,35 @@
</xsl:template> </xsl:template>
<xsl:template match="entity" mode="table"> <xsl:template match="adl:entity" mode="table">
<xsl:variable name="table" select="@name"/> <xsl:variable name="table" select="@name"/>
<!-- xsl:choose>
<xsl:when test="@table">
<xsl:value-of select="@table"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable -->
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
-- primary table <xsl:value-of select="@name"/> -- primary table <xsl:value-of select="@name"/>
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
CREATE TABLE "<xsl:value-of select="@name"/>" CREATE TABLE "<xsl:value-of select="@name"/>"
( (
<xsl:apply-templates select="property[@type!='link']"/> <xsl:for-each select="adl:key/adl:property">
<xsl:value-of select="@name"/>Id INT IDENTITY( 1, 1) PRIMARY KEY <xsl:apply-templates select="."/><xsl:text> PRIMARY KEY,</xsl:text>
</xsl:for-each>
<xsl:for-each select="adl:property[@type!='link' and @type != 'list']">
<xsl:apply-templates select="."/><xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
) )
GO GO
---- permissions ------------------------------------------------------------------------------ ---- permissions ------------------------------------------------------------------------------
<xsl:for-each select="permission"> <xsl:for-each select="adl:permission">
<xsl:call-template name="permission"> <xsl:call-template name="permission">
<xsl:with-param name="table" select="$table"/> <xsl:with-param name="table" select="$table"/>
</xsl:call-template> </xsl:call-template>
@ -132,7 +149,7 @@
<xsl:if test="property[@type='link']"> <xsl:if test="property[@type='link']">
---- link tables ------------------------------------------------------------------------------ ---- link tables ------------------------------------------------------------------------------
</xsl:if> </xsl:if>
<xsl:for-each select="property[@type='link']"> <xsl:for-each select="adl:property[@type='link']">
<xsl:call-template name="linktable"> <xsl:call-template name="linktable">
<xsl:with-param name="nearside" select="$table"/> <xsl:with-param name="nearside" select="$table"/>
</xsl:call-template> </xsl:call-template>
@ -342,21 +359,58 @@
</xsl:if> </xsl:if>
</xsl:template> </xsl:template>
<xsl:template match="property[@type='list']"> <xsl:template match="adl:property[@type='list']">
-- Suppressing output of property <xsl:value-of select="@name"/>, -- Suppressing output of property <xsl:value-of select="@name"/>,
-- as it is the 'one' end of a one-to-many relationship -- as it is the 'one' end of a one-to-many relationship
</xsl:template> </xsl:template>
<xsl:template match="property[@type='entity']"> <xsl:template match="adl:property[@type='serial']">
"<xsl:value-of select="@name"/>" INT<xsl:if <xsl:value-of select="@name"/><xsl:text> INT IDENTITY( 1, 1)</xsl:text>
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text>
</xsl:text>
</xsl:template> </xsl:template>
<xsl:template match="property[@type='defined']"> <!-- the grand unified property handler, using the sql-type template to
<xsl:variable name="name"><xsl:value-of select="@definition"/></xsl:variable> generate the correct types for each field -->
<xsl:variable name="definitiontype"><xsl:value-of select="/application/definition[@name=$name]/@type"/></xsl:variable> <xsl:template match="adl:property">
<xsl:variable name="type">
<xsl:call-template name="sql-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="base-type">
<xsl:call-template name="base-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
"<xsl:value-of select="@name"/>" <xsl:value-of select="normalize-space( $type)"/><xsl:if
test="string(@default)"> DEFAULT <xsl:choose>
<xsl:when test="$base-type = 'integer' or $base-type = 'real' or $base-type = 'money'">
<xsl:value-of select="@default"/>
</xsl:when>
<xsl:otherwise>'<xsl:value-of select="@default"/>'</xsl:otherwise>
</xsl:choose>
</xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>
</xsl:template>
<!-- properties of type 'entity' are supposed to be being handled by the
grand unified property handler. Unfortunately it gets them wrong and I'm not
sure why. So temporarily this special case template fixes the problem. TODO:
work out what's wrong with the grand unified version -->
<xsl:template match="adl:property[@type='entity']">
<xsl:variable name="type">
<xsl:call-template name="sql-type">
<xsl:with-param name="property" select="."/>
</xsl:call-template>
</xsl:variable>
"<xsl:value-of select="@name"/>" <xsl:value-of select="$type"/><xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/></xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>
</xsl:template>
<!-- xsl:template match="adl:property[@type='defined']">
<xsl:variable name="name"><xsl:value-of select="@typedef"/></xsl:variable>
<xsl:variable name="definitiontype"><xsl:value-of select="//adl:typedef[@name=$name]/@type"/></xsl:variable>
"<xsl:value-of select="@name"/>"<xsl:text> </xsl:text><xsl:choose> "<xsl:value-of select="@name"/>"<xsl:text> </xsl:text><xsl:choose>
<xsl:when test="$definitiontype='string'">VARCHAR( <xsl:value-of <xsl:when test="$definitiontype='string'">VARCHAR( <xsl:value-of
select="/application/definition[@name=$name]/@size"/>)</xsl:when> select="/application/definition[@name=$name]/@size"/>)</xsl:when>
@ -365,56 +419,91 @@
<xsl:otherwise><xsl:value-of select="$definitiontype"/></xsl:otherwise> <xsl:otherwise><xsl:value-of select="$definitiontype"/></xsl:otherwise>
</xsl:choose><xsl:if </xsl:choose><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>,<xsl:text> test="@required='true'"> NOT NULL</xsl:if>
</xsl:text>
</xsl:template> </xsl:template>
<xsl:template match="property[@type='boolean']"> <xsl:template match="adl:property[@type='boolean']">
-- SQL Server doesn't have proper booleans!
"<xsl:value-of select="@name"/>" BIT<xsl:choose> "<xsl:value-of select="@name"/>" BIT<xsl:choose>
<xsl:when test="@default='true'"> DEFAULT 1</xsl:when> <xsl:when test="@default='true'"> DEFAULT 1</xsl:when>
<xsl:when test="@default='false'"> DEFAULT 0</xsl:when> <xsl:when test="@default='false'"> DEFAULT 0</xsl:when>
</xsl:choose><xsl:if test="@required='true'"> NOT NULL</xsl:if>,<xsl:text> </xsl:choose><xsl:if test="@required='true'"> NOT NULL</xsl:if>
</xsl:text>
</xsl:template> </xsl:template>
<xsl:template match="property[@type='string']"> <xsl:template match="adl:property[@type='string']">
"<xsl:value-of select="@name"/>" VARCHAR( <xsl:value-of select="@size"/>)<xsl:if "<xsl:value-of select="@name"/>" VARCHAR( <xsl:value-of select="@size"/>)<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>,<xsl:text> test="@required='true'"> NOT NULL</xsl:if>
</xsl:text>
</xsl:template> </xsl:template>
<xsl:template match="property[@type='date' or @type = 'time']"> <xsl:template match="adl:property[@type='date' or @type = 'time']">
"<xsl:value-of select="@name"/>" DATETIME<xsl:if "<xsl:value-of select="@name"/>" DATETIME<xsl:if
test="string(@default)"> DEFAULT <xsl:value-of select="@default"/> test="string(@default)"> DEFAULT <xsl:value-of select="@default"/>
</xsl:if><xsl:if </xsl:if><xsl:if
test="@required='true'"> NOT NULL</xsl:if>,<xsl:text> test="@required='true'"> NOT NULL</xsl:if>
</xsl:text>
</xsl:template> </xsl:template>
<xsl:template match="property[@type='integer']"> <xsl:template match="adl:property[@type='integer']">
"<xsl:value-of select="@name"/>" INT<xsl:if "<xsl:value-of select="@name"/>" INT<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>,<xsl:text> test="@required='true'"> NOT NULL</xsl:if>
</xsl:text>
</xsl:template> </xsl:template>
<xsl:template match="property[@type='real']"> <xsl:template match="adl:property[@type='real']">
"<xsl:value-of select="@name"/>" DOUBLE PRECISION<xsl:if "<xsl:value-of select="@name"/>" DOUBLE PRECISION<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>,<xsl:text> test="@required='true'"> NOT NULL</xsl:if>
</xsl:text>
</xsl:template> </xsl:template>
<xsl:template match="property"> <xsl:template match="adl:property">
"<xsl:value-of select="@name"/>" <xsl:text> </xsl:text><xsl:value-of select="@type"/><xsl:if "<xsl:value-of select="@name"/>" <xsl:text> </xsl:text><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>,<xsl:text> test="@required='true'"> NOT NULL</xsl:if>
</xsl:text> </xsl:template -->
<!-- return the SQL type of the property which is passed as a parameter -->
<xsl:template name="sql-type">
<xsl:param name="property"/>
<xsl:variable name="base-type">
<xsl:call-template name="base-type">
<xsl:with-param name="property" select="$property"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="base-size">
<xsl:call-template name="base-size">
<xsl:with-param name="property" select="$property"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$base-type = 'entity'">
<xsl:variable name="entity" select="@entity"/>
<xsl:call-template name="sql-type">
<xsl:with-param name="property"
select="//adl:entity[@name=$entity]/adl:key/adl:property[position()=1]"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$base-type = 'link'">
ICollection&lt;<xsl:value-of select="@entity"/>&gt;
</xsl:when>
<xsl:when test="$base-type = 'list'">
ICollection&lt;<xsl:value-of select="@entity"/>&gt;
</xsl:when>
<xsl:when test="$base-type = 'date'">DATETIME</xsl:when>
<xsl:when test="$base-type = 'time'">DATETIME</xsl:when>
<!-- TODO: if the type was 'defined' then the size should probably come from the typedef -->
<xsl:when test="$base-type = 'string'">VARCHAR( <xsl:value-of select="$base-size"/>)</xsl:when>
<xsl:when test="$base-type = 'text'">TEXT</xsl:when>
<xsl:when test="$base-type = 'boolean'">BIT</xsl:when>
<xsl:when test="$base-type = 'timestamp'">TIMESTAMP</xsl:when>
<xsl:when test="$base-type = 'integer'">INT</xsl:when>
<xsl:when test="$base-type = 'real'">DOUBLE PRECISION</xsl:when>
<xsl:when test="$base-type = 'money'">DECIMAL</xsl:when>
<xsl:when test="$base-type = 'serial'">INT IDENTITY( 1, 1)</xsl:when>
<xsl:otherwise>[sql:unknown? [<xsl:value-of select="$base-type"/>]]</xsl:otherwise>
</xsl:choose>
</xsl:template> </xsl:template>

View file

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Application Description Language framework
base-type-include.xslt
(c) 2007 Cygnet Solutions Ltd
An xsl transform intended to be included into other XSL stylesheets,
intended to keep lookup of the ADL base type from ADL properties in
one place for ease of maintenance
$Author: sb $
$Revision: 1.1 $
$Date: 2008-02-01 18:25:38 $
-->
<xsl:stylesheet version="1.0"
xmlns="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="adl">
<!-- return the base ADL type of the property which is passed as a parameter -->
<xsl:template name="base-type">
<xsl:param name="property"/>
<xsl:choose>
<xsl:when test="$property/@type='defined'">
<xsl:variable name="definition">
<xsl:value-of select="$property/@typedef"/>
</xsl:variable>
<xsl:message terminate="no">
Looking for definition of '<xsl:value-of select="$definition"/>';
Found to be defined as type '<xsl:value-of select="/adl:application/adl:typedef[@name=$definition]/@type"/>'
</xsl:message>
<xsl:value-of select="/adl:application/adl:typedef[@name=$definition]/@type"/>
</xsl:when>
<xsl:when test="$property/@type='serial'">integer</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$property/@type"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- return the size of the type of the property which is passed as a parameter -->
<xsl:template name="base-size">
<xsl:param name="property"/>
<xsl:choose>
<xsl:when test="$property/@type='defined'">
<xsl:variable name="definition">
<xsl:value-of select="$property/@typedef"/>
</xsl:variable>
<xsl:value-of select="/adl:application/adl:typedef[@name=$definition]/@size"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$property/@size"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>