Selaa lähdekoodia

added ability to upgrade initial data in DB
- xx_create.sql script is now separated to two scripts: xx_create.sql and xx_data.sql
xx_create.sql contain tables definitions and xx_data.sql contain all initial data (<row> elements from XML files)
- each <row> element have new optional attribute 'vendor-controlled'.
If vendor-controled='1' for a row, SQL DELETE statement is generated before INSERT statement for this row.
In this case is necessary to define <row-identificator> element wich contain list of <colref> elements.
This is a list of columns which will be in DELETE WHERE clause.
- From now is also necessary to define an unique index on all tables which contain an initial data. Otherwise
data will be duplicated on each update.

Karel Kozlik 19 vuotta sitten
vanhempi
commit
997e7d8270

+ 5 - 0
doc/stylesheets/dbschema/dtd/dbschema.dtd

@@ -42,7 +42,12 @@
     linkend IDREF #REQUIRED
 >
 
+<!ELEMENT row-identificator (colref+) >
+
 <!ELEMENT row (value*) >
+<!ATTLIST row
+    vendor-controlled (0|1) #IMPLIED
+>
 
 <!ELEMENT value (#PCDATA | null)* >
 <!ATTLIST value

+ 28 - 0
doc/stylesheets/dbschema/xsl/common.xsl

@@ -60,6 +60,12 @@
 	<xsl:apply-templates select="user"/>
     </xsl:template>
 
+    <xsl:template match="database" mode="data">
+
+	<!-- Insert initial data -->
+	<xsl:apply-templates select="table" mode="data"/>
+    </xsl:template>
+
     <!-- ################ /DATABASE ################# -->
 
     <!-- ################ TABLE ################# -->
@@ -146,6 +152,28 @@
 	</xsl:choose>
     </xsl:template>
 
+
+    <!-- column ID to column name -->
+    <xsl:template name="get-column-name">
+	<xsl:param name="select" select="."/>
+
+	<xsl:variable name="columns" select="key('column_id', $select)"/>
+	<xsl:variable name="column" select="$columns[1]"/>
+	<xsl:choose>
+	    <xsl:when test="count($column) = 0">
+		<xsl:message terminate="yes">
+		    <xsl:text>ERROR: Column with id '</xsl:text>
+		    <xsl:value-of select="$select"/>
+		    <xsl:text>' does not exist.</xsl:text>
+		</xsl:message>
+	    </xsl:when>
+	    <xsl:otherwise>
+		<xsl:call-template name="get-name">
+		    <xsl:with-param name="select" select="$column"/>
+		</xsl:call-template>
+	    </xsl:otherwise>
+	</xsl:choose>
+    </xsl:template>
     <!-- ################ /COLUMN ################# -->
 
     <!-- ################ INDEX ################# -->

+ 32 - 4
doc/stylesheets/dbschema/xsl/mysql.xsl

@@ -6,10 +6,6 @@
 
     <xsl:import href="sql.xsl"/>
 
-    <xsl:template match="database">
-	<xsl:apply-imports/>
-    </xsl:template>
-
     <xsl:template match="database" mode="drop">
 	<xsl:apply-templates mode="drop"/>
     </xsl:template>
@@ -152,4 +148,36 @@
 	<xsl:text>'</xsl:text>
     </xsl:template>
 
+<!-- ################ ROW ################  -->
+
+    <!-- override common template for ROW. Create INSERT statements 
+         with IGNORE keyword
+      -->
+    <xsl:template match="row">
+	<xsl:if test="@vendor-controlled[1]">
+	    <xsl:text>DELETE FROM </xsl:text>	    
+	    <xsl:call-template name="get-name">
+		<xsl:with-param name="select" select="parent::table"/>
+	    </xsl:call-template>
+	    <xsl:text> WHERE </xsl:text>	    
+	    <xsl:call-template name="row-identification"/>
+	    <xsl:text>;&#x0A;</xsl:text>	    
+	</xsl:if>
+
+	<xsl:text>INSERT IGNORE INTO </xsl:text>
+	<xsl:call-template name="get-name">
+	    <xsl:with-param name="select" select="parent::table"/>
+	</xsl:call-template>
+	<xsl:text> (</xsl:text>
+	<xsl:apply-templates select="value" mode="colname"/>
+	<xsl:text>) VALUES (</xsl:text>
+	<xsl:apply-templates select="value"/>
+	<xsl:text>);&#x0A;</xsl:text>
+	<xsl:if test="position()=last()">
+	    <xsl:text>&#x0A;</xsl:text>	    
+	</xsl:if>
+    </xsl:template>
+
+<!-- ################ /ROW ################  -->
+
 </xsl:stylesheet>

+ 0 - 3
doc/stylesheets/dbschema/xsl/postgres.xsl

@@ -106,9 +106,6 @@
 	<xsl:for-each select="index[count(child::unique)=0]">
 	    <xsl:call-template name="create_index"/>
 	</xsl:for-each>
-
-	<!-- Process initial rows of data -->
-	<xsl:apply-templates select="row"/>
     </xsl:template>
 
     <xsl:template match="index">

+ 87 - 33
doc/stylesheets/dbschema/xsl/sql.xsl

@@ -15,6 +15,15 @@
 	    <xsl:text> </xsl:text>
 	</xsl:document>
 
+	<xsl:variable name="datafile" select="concat($dir, concat('/', concat($prefix, 'data.sql')))"/>
+	<xsl:document href="{$datafile}" method="text" indent="no" omit-xml-declaration="yes">
+	    <xsl:apply-templates mode="data" select="/database[1]"/>
+	    <!-- This is a hack to ensure that the file gets created when
+	    nothing is written
+	    -->
+	    <xsl:text> </xsl:text>
+	</xsl:document>
+
 	<xsl:variable name="dropfile" select="concat($dir, concat('/', concat($prefix, 'drop.sql')))"/>
 	<xsl:document href="{$dropfile}" method="text" indent="no" omit-xml-declaration="yes">
 	    <xsl:apply-templates mode="drop" select="/database[1]"/>
@@ -53,8 +62,10 @@
 	<xsl:text>&#x0A;</xsl:text>
 
 	<xsl:call-template name="table.close"/>
+    </xsl:template>
 
-	<!-- Process initial rows of data -->
+    <xsl:template match="table" mode="data">
+	<!-- Process initial data --> 
 	<xsl:apply-templates select="row"/>
     </xsl:template>
 
@@ -178,22 +189,9 @@
 <!-- ################ COLREF ################  -->
 
     <xsl:template match="colref">
-	<xsl:variable name="columns" select="key('column_id', @linkend)"/>
-	<xsl:variable name="column" select="$columns[1]"/>
-	<xsl:choose>
-	    <xsl:when test="count($column) = 0">
-		<xsl:message terminate="yes">
-		    <xsl:text>ERROR: Column with id '</xsl:text>
-		    <xsl:value-of select="@linkend"/>
-		    <xsl:text>' does not exist.</xsl:text>
-		</xsl:message>
-	    </xsl:when>
-	    <xsl:otherwise>
-		<xsl:call-template name="get-name">
-		    <xsl:with-param name="select" select="$column"/>
-		</xsl:call-template>
-	    </xsl:otherwise>
-	</xsl:choose>
+	<xsl:call-template name="get-column-name">
+	    <xsl:with-param name="select" select="@linkend"/>
+	</xsl:call-template>
 	<xsl:if test="not(position()=last())">
 	    <xsl:text>, </xsl:text>
 	</xsl:if>
@@ -204,6 +202,16 @@
 <!-- ################ ROW ################  -->
 
     <xsl:template match="row">
+	<xsl:if test="@vendor-controlled[1]">
+	    <xsl:text>DELETE FROM </xsl:text>	    
+	    <xsl:call-template name="get-name">
+		<xsl:with-param name="select" select="parent::table"/>
+	    </xsl:call-template>
+	    <xsl:text> WHERE </xsl:text>	    
+	    <xsl:call-template name="row-identification"/>
+	    <xsl:text>;&#x0A;</xsl:text>	    
+	</xsl:if>
+
 	<xsl:text>INSERT INTO </xsl:text>
 	<xsl:call-template name="get-name">
 	    <xsl:with-param name="select" select="parent::table"/>
@@ -218,6 +226,65 @@
 	</xsl:if>
     </xsl:template>
 
+    <xsl:template name="row-identification">
+	<xsl:variable name="row-ident" select="parent::table/row-identificator"/>
+	<xsl:variable name="row" select="."/>
+	<xsl:variable name="columns" select="$row-ident/colref"/>
+
+
+	<xsl:choose>
+	    <xsl:when test="count($row-ident) = 0">
+		<xsl:message terminate="yes">
+		    <xsl:text>ERROR: row-identificator does not exists.</xsl:text>
+		</xsl:message>
+	    </xsl:when>
+	    <xsl:when test="count($columns) = 0">
+		<xsl:message terminate="yes">
+		    <xsl:text>ERROR: row-identificator does not have any column.</xsl:text>
+		</xsl:message>
+	    </xsl:when>
+	    <xsl:otherwise>
+
+
+	<xsl:for-each select="$columns">
+	    <xsl:variable name="col-id" select="@linkend"/>
+	    
+	    <!-- column name -->
+	    <xsl:call-template name="get-column-name">
+		<xsl:with-param name="select" select="$col-id"/>
+	    </xsl:call-template>
+
+	    <xsl:text>=</xsl:text>	    
+
+	    <!-- value of column -->
+	    <xsl:variable name="value" select="$row/value[@col=$col-id]"/>
+	    <xsl:choose>
+		<xsl:when test="count($value) = 0">
+		    <xsl:message terminate="yes">
+			<xsl:text>ERROR: Value of column with id '</xsl:text>
+			<xsl:value-of select="$col-id"/>
+			<xsl:text>' does not exist.</xsl:text>
+		    </xsl:message>
+		</xsl:when>
+		<xsl:otherwise>
+		    <xsl:text>'</xsl:text>
+		    <xsl:value-of select="$value"/>
+		    <xsl:text>'</xsl:text>
+		</xsl:otherwise>
+	    </xsl:choose>
+
+
+	    <xsl:if test="not(position()=last())">
+		<xsl:text> AND </xsl:text>
+	    </xsl:if>
+	</xsl:for-each>
+
+
+	    </xsl:otherwise>
+	</xsl:choose>
+    	
+    </xsl:template>
+
 <!-- ################ /ROW ################  -->
 
 <!-- ################ VALUE ################  -->
@@ -239,22 +306,9 @@
     </xsl:template>
 
     <xsl:template match="value" mode="colname">
-	<xsl:variable name="columns" select="key('column_id', @col)"/>
-	<xsl:variable name="column" select="$columns[1]"/>
-	<xsl:choose>
-	    <xsl:when test="count($column) = 0">
-		<xsl:message terminate="yes">
-		    <xsl:text>ERROR: Column with id '</xsl:text>
-		    <xsl:value-of select="@col"/>
-		    <xsl:text>' does not exist.</xsl:text>
-		</xsl:message>
-	    </xsl:when>
-	    <xsl:otherwise>
-		<xsl:call-template name="get-name">
-		    <xsl:with-param name="select" select="$column"/>
-		</xsl:call-template>
-	    </xsl:otherwise>
-	</xsl:choose>
+	<xsl:call-template name="get-column-name">
+	    <xsl:with-param name="select" select="@col"/>
+	</xsl:call-template>
 	<xsl:if test="not(position()=last())">
 	    <xsl:text>, </xsl:text>
 	</xsl:if>