dbd2propel.xsl 12 KB

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