root/trunk/contrib/dbd2propel/dbd2propel.xsl

Revision 1068, 12.1 kB (checked in by ron, 2 months ago)

Merge in changes from 1.3 branch: merge -r 832:1067

Line 
1 <?xml version="1.0"?>
2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
3 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
4 <xsl:strip-space elements="*"/>
5
6 <!--
7 DB Designer XML to Propel Schema XML
8
9 ==== Author: Jonathan Graham <jkgraham@gmail.com>
10 ==== Version: 0.5 (2008-01-25) (http://blog.tooleshed.com/?p=6)
11 ==== Description:
12 This XSL will transform a DB Designer 4 database model XML file into a
13 Propel database schema file.  This allows you to design your database
14 model using DB Designer 4 (models are saved in XML format) and then
15 easily create the Propel database schema file.
16
17 The PROPEL properties that this XSL will translate are listed below.
18
19 TABLE: name, description
20 COLUMN: name, primaryKey, required, type, size, scale, default, autoIncrement, description
21 FOREIGN-KEY: foreignTable, name, onDelete
22 REFERENCE: local, foreign
23 INDEX: index (not related to FK), unique, fulltext
24
25 ==== Usage:
26 - Simply feed this XSL into your favorite XSLT engine along with your DB Designer
27 XML model.  The resulting output is a Propel database schema XML.
28
29 ==== Collaboration:
30 Peter Banik <peter@froggle.org> - UNIQUE TAG
31 Benedicto Franco Jr. - MULTIPLE FOREIGN KEY, DATABASE NAME
32 Martin Kreidenweis <martin@kreidenweis.com> - Bug fixes, INDEX
33 Michiel Hakvoort - onDelete
34 Michel D'HOOGE - FULLTEXT
35 Oleg Marchuk <kingoleg@mail.ru> - version 0.5
36
37 ==== Software:
38 Propel: http://propel.phpdb.org/
39 DB Designer 4: http://www.fabforce.net/dbdesigner4/
40
41 ==== Copyright (c) 2004-2006, Jonathan Graham
42 Licensed under the GNU Lesser General Public License (LGPL) - http://www.gnu.org/copyleft/lgpl.html.
43
44 ==== Change Log
45 version 0.1 (2004-11-08) - initial version
46 version 0.2 (2006-10-18) - Added Peter and Benedicto's updates.
47 version 0.3 (2006-11-05) - added non-unique-INDEXes and onDelete
48 version 0.4 (2006-11-13) - added support for index names and FULLTEXT indexes, changed license to LGPL
49 version 0.5 (2008-01-25) - added ENUM, GEOMETRY as BLOB, scale for DECIMAL; fixed size in ENUM and spaces in relation names
50
51 -->
52
53 <!-- ============================================================ DATABASE template -->
54 <xsl:template match="/">
55         <database defaultIdMethod="native">
56                 <xsl:attribute name="name">
57                         <xsl:value-of select="/DBMODEL/SETTINGS/GLOBALSETTINGS/@ModelName"/>
58                 </xsl:attribute>               
59                 <xsl:apply-templates />
60         </database>
61 </xsl:template>
62
63 <!-- ============================================================ TABLES template -->
64 <xsl:template match="/DBMODEL/METADATA/TABLES/TABLE">
65         <table>
66                 <xsl:attribute name="name">
67                         <xsl:value-of select="@Tablename"/>
68                 </xsl:attribute>
69                 <xsl:if test="@Comments != ''">
70                         <xsl:attribute name="description">
71                                 <xsl:value-of select="@Comments" />
72                         </xsl:attribute>
73                 </xsl:if>
74                 <xsl:apply-templates />
75         </table>
76 </xsl:template>
77
78
79 <!-- ============================================================ COLUMNS template -->
80 <xsl:template match="COLUMNS/COLUMN">
81         <column>
82                 <!-- get data type -->
83                 <xsl:variable name="datatype">
84                         <xsl:call-template name="get_datatype">
85                                 <xsl:with-param name="id"><xsl:value-of select="@idDatatype"/></xsl:with-param>
86                         </xsl:call-template>
87                 </xsl:variable>
88                
89                 <!-- remove parens from datatypeparams -->
90                 <xsl:variable name="dtpclean">
91                         <xsl:call-template name="clean_dataparams">
92                                 <xsl:with-param name="dtp"><xsl:value-of select="@DatatypeParams"/></xsl:with-param>
93                         </xsl:call-template>
94                 </xsl:variable>
95
96                 <!-- ==== name ==== -->
97                 <xsl:attribute name="name">
98                         <xsl:value-of select="@ColName"/>
99                 </xsl:attribute>
100                
101                 <!-- ==== type ==== -->
102                 <xsl:attribute name="type">
103                         <xsl:choose>
104                                 <xsl:when test="$datatype = 'ENUM'">
105                                         <xsl:value-of select="'CHAR'" />
106                                 </xsl:when>
107                                 <xsl:otherwise>
108                                         <xsl:value-of select="$datatype"/>
109                                 </xsl:otherwise>
110                         </xsl:choose>
111                 </xsl:attribute>
112
113                 <xsl:if test="$dtpclean != ''">
114                         <!-- ==== size ==== -->
115                         <xsl:attribute name="size">
116                                 <xsl:call-template name="get_datasize">
117                                         <xsl:with-param name="dtpc"><xsl:value-of select="$dtpclean"/></xsl:with-param>
118                                         <xsl:with-param name="dtype"><xsl:value-of select="$datatype"/></xsl:with-param>
119                                 </xsl:call-template>
120                         </xsl:attribute>
121
122                         <xsl:if test="contains('FLOAT,DOUBLE,DECIMAL',$datatype)">
123                                 <!-- ==== scale ==== -->
124                                 <xsl:attribute name="scale">
125                                         <xsl:value-of select="substring-after($dtpclean,',')"/>
126                                 </xsl:attribute>
127                         </xsl:if>
128                        
129                 </xsl:if>
130                                
131                 <!-- ==== primaryKey ==== -->
132                 <xsl:if test="@PrimaryKey = '1'">
133                         <xsl:attribute name="primaryKey">true</xsl:attribute>
134                 </xsl:if>
135                
136                 <!-- ==== required ==== -->
137                 <xsl:if test="@NotNull = '1'">
138                         <xsl:attribute name="required">true</xsl:attribute>
139                 </xsl:if>
140
141                 <!-- ==== default ==== -->
142                 <xsl:if test="@DefaultValue != ''">
143                         <xsl:attribute name="default">
144                                 <xsl:value-of select="@DefaultValue"/>
145                         </xsl:attribute>
146                 </xsl:if>
147                
148                 <!-- ==== autoIncrement ==== -->
149                 <xsl:if test="@AutoInc = '1'">
150                         <xsl:attribute name="autoIncrement">true</xsl:attribute>
151                 </xsl:if>
152
153                 <!-- ==== description ==== -->
154                 <xsl:if test="@Comments != ''">
155                         <xsl:attribute name="description">
156                                 <xsl:value-of select="@Comments"/>
157                         </xsl:attribute>
158                 </xsl:if>
159
160         </column>
161 </xsl:template>
162
163 <!-- ============================================================ RELATIONS template -->
164 <xsl:template match="RELATIONS_END/RELATION_END">
165        
166         <xsl:variable name="id"><xsl:value-of select="@ID"/></xsl:variable>
167        
168         <xsl:call-template name="show_ForeignKey">
169                 <xsl:with-param name="relation" select="/DBMODEL/METADATA/RELATIONS/RELATION[@ID=$id]"/>
170         </xsl:call-template>
171        
172 </xsl:template>
173
174 <!-- ============================================================ INDEX template -->
175 <xsl:template match="INDICES/INDEX">
176         <xsl:choose>
177                 <xsl:when test="@IndexKind = '1' and @FKRefDef_Obj_id='-1'">
178                         <index>
179                                 <xsl:attribute name="name"><xsl:value-of select="@IndexName"/></xsl:attribute>
180                                 <xsl:apply-templates select="INDEXCOLUMNS/INDEXCOLUMN" mode="normal"/>
181                         </index>
182                 </xsl:when>
183                 <xsl:when test="@IndexKind = '2'">
184                         <unique>
185                                 <xsl:attribute name="name"><xsl:value-of select="@IndexName"/></xsl:attribute>
186                                 <xsl:apply-templates select="INDEXCOLUMNS/INDEXCOLUMN" mode="unique"/>
187                         </unique>
188                 </xsl:when>
189                 <xsl:when test="@IndexKind = '3'">
190                         <index>
191                                 <xsl:attribute name="name"><xsl:value-of select="@IndexName"/></xsl:attribute>
192                                 <xsl:apply-templates select="INDEXCOLUMNS/INDEXCOLUMN" mode="normal"/>
193                                 <vendor type="mysql">
194                                         <parameter name="Index_type" value="FULLTEXT"/>
195                                 </vendor>
196                         </index>
197                 </xsl:when>
198         </xsl:choose>
199 </xsl:template>
200
201
202 <!-- ============================================================ columns within an index -->
203 <xsl:template match="INDICES/INDEX/INDEXCOLUMNS/INDEXCOLUMN" mode="normal">
204         <xsl:variable name="columnId"><xsl:value-of select="@idColumn"/></xsl:variable>
205         <index-column>
206                 <xsl:attribute name="name"><xsl:value-of select="//COLUMNS/COLUMN[@ID=$columnId]/@ColName"/></xsl:attribute>
207         </index-column>
208 </xsl:template>
209
210 <xsl:template match="INDICES/INDEX/INDEXCOLUMNS/INDEXCOLUMN" mode="unique">
211         <xsl:variable name="columnId"><xsl:value-of select="@idColumn"/></xsl:variable>
212         <unique-column>
213                 <xsl:attribute name="name"><xsl:value-of select="//COLUMNS/COLUMN[@ID=$columnId]/@ColName"/></xsl:attribute>
214         </unique-column>
215 </xsl:template>
216
217
218 <!-- ============================================================ show_ForeignKey -->
219 <xsl:template name="show_ForeignKey">
220         <xsl:param name="relation"/>
221         <foreign-key>
222        
223                 <!-- foreignTable -->
224                 <xsl:attribute name="foreignTable">
225                         <xsl:value-of select="/DBMODEL/METADATA/TABLES/TABLE[@ID=$relation/@SrcTable]/@Tablename"/>
226                 </xsl:attribute>
227
228                 <!-- name -->
229                 <xsl:attribute name="name">
230                         <xsl:value-of select="translate($relation/@RelationName, ' ', '_')"/>
231                 </xsl:attribute>
232
233                 <!-- onDelete -->
234                 <xsl:attribute name="onDelete">
235
236                         <xsl:variable name="actionId">
237                                 <xsl:call-template name="str_replace">
238                                         <xsl:with-param name="stringIn" select="substring-before(substring-after($relation/@RefDef,'\n'), '\n')"/>
239                                         <xsl:with-param name="charsIn" select="'OnDelete='"/>
240                                         <xsl:with-param name="charsOut" select="''"/>
241                                 </xsl:call-template>
242                         </xsl:variable>
243
244                         <xsl:call-template name="get_actiontype">
245                                 <xsl:with-param name="id" select="$actionId" />
246                         </xsl:call-template>
247
248                 </xsl:attribute>
249
250                 <!-- === reference tag === -->
251                 <xsl:call-template name="build_fk">
252                         <xsl:with-param name="stringIn" select="$relation/@FKFields"/>
253                 </xsl:call-template>
254
255         </foreign-key>
256 </xsl:template>
257
258 <!--
259 ============================================================
260 ============================================================ template "functions"
261 ============================================================
262 -->
263
264 <!-- ============================================================ get_datatype -->
265 <xsl:template name="get_datatype">
266         <xsl:param name="id"/>
267
268         <xsl:variable name="type">
269                 <xsl:value-of select="/DBMODEL/SETTINGS/DATATYPES/DATATYPE[@ID=$id]/@TypeName"/>
270         </xsl:variable>
271
272         <xsl:choose>
273                 <xsl:when test="$type = 'DATETIME'" >TIMESTAMP</xsl:when>
274                 <xsl:when test="$type = 'TEXT'" >LONGVARCHAR</xsl:when>
275                 <xsl:when test="$type = 'BOOL'" >BOOLEAN</xsl:when>
276                 <xsl:when test="$type = 'GEOMETRY'" >BLOB</xsl:when>
277                 <xsl:otherwise>
278                         <xsl:value-of select="$type"/>
279                 </xsl:otherwise>
280         </xsl:choose>
281        
282 </xsl:template>
283
284
285 <!-- ============================================================ get_datasize -->
286 <xsl:template name="get_datasize">
287         <xsl:param name="dtpc"/>
288         <xsl:param name="dtype"/>
289
290         <xsl:choose>
291                 <xsl:when test="contains('FLOAT,DOUBLE,DECIMAL',$dtype)" >
292                         <xsl:value-of select="substring-before($dtpc,',')"/>
293                 </xsl:when>
294                 <xsl:when test="$dtype = 'ENUM'">
295                         <xsl:value-of select="''" />
296                 </xsl:when>     
297                 <xsl:otherwise>
298                         <xsl:value-of select="$dtpc"/>
299                 </xsl:otherwise>
300         </xsl:choose>
301        
302 </xsl:template>
303
304
305 <!-- ============================================================ clean_dataparams -->
306 <xsl:template name="clean_dataparams">
307         <xsl:param name="dtp"/>
308
309         <xsl:variable name="dtp2">
310                 <xsl:call-template name="str_replace">
311                         <xsl:with-param name="stringIn" select="$dtp"/>
312                         <xsl:with-param name="charsIn" select="'('"/>
313                         <xsl:with-param name="charsOut" select="''"/>
314                 </xsl:call-template>
315         </xsl:variable>
316
317         <xsl:call-template name="str_replace">
318                 <xsl:with-param name="stringIn" select="$dtp2"/>
319                 <xsl:with-param name="charsIn" select="')'"/>
320                 <xsl:with-param name="charsOut" select="''"/>
321         </xsl:call-template>
322        
323 </xsl:template>
324
325
326 <!-- ============================================================ str_replace -->
327 <xsl:template name="str_replace">
328         <xsl:param name="stringIn"/>
329         <xsl:param name="charsIn"/>
330         <xsl:param name="charsOut"/>
331         <xsl:choose>
332                 <xsl:when test="contains($stringIn,$charsIn)">
333                         <xsl:value-of select="concat(substring-before($stringIn,$charsIn),$charsOut)"/>
334                         <xsl:call-template name="str_replace">
335                                 <xsl:with-param name="stringIn" select="substring-after($stringIn,$charsIn)"/>
336                                 <xsl:with-param name="charsIn" select="$charsIn"/>
337                                 <xsl:with-param name="charsOut" select="$charsOut"/>
338                         </xsl:call-template>
339                 </xsl:when>
340                 <xsl:otherwise>
341                         <xsl:value-of select="$stringIn"/>
342                 </xsl:otherwise>
343         </xsl:choose>
344 </xsl:template>
345
346
347 <!-- ============================================================== build_fk -->
348 <xsl:template name="build_fk">
349         <xsl:param name="stringIn"/>
350         <xsl:variable name="FKClean">
351                 <xsl:value-of select="substring-before($stringIn, '\n')"/>
352         </xsl:variable>
353         <reference>
354         <xsl:attribute name="local">
355                 <xsl:value-of select="substring-after($FKClean, '=')"/>
356         </xsl:attribute>
357         <xsl:attribute name="foreign">
358                 <xsl:value-of select="substring-before($FKClean, '=')"/>
359         </xsl:attribute>
360         </reference>
361         <xsl:if test="contains(substring-after($stringIn,'\n'),'=')">
362                 <xsl:call-template name="build_fk">
363                         <xsl:with-param name="stringIn" select="substring-after($stringIn,'\n')"/>
364                 </xsl:call-template>
365         </xsl:if>
366 </xsl:template>
367
368 <!-- ======================================================== get_actiontype -->
369
370 <xsl:template name="get_actiontype">
371         <xsl:param name="id"/>
372
373         <xsl:choose>
374                 <xsl:when test="$id = 0">restrict</xsl:when>
375                 <xsl:when test="$id = 1">cascade</xsl:when>
376                 <xsl:when test="$id = 2">setnull</xsl:when>
377                 <xsl:otherwise>restrict</xsl:otherwise>
378         </xsl:choose>
379 </xsl:template>
380
381 </xsl:stylesheet>
Note: See TracBrowser for help on using the browser.