Skip to content

Commit

Permalink
Add ability to set dbms for raw sql changes.
Browse files Browse the repository at this point in the history
Currently, you can only specify database names at the changeset level.
This commit extends that functionality for sql changes.
Useful for creating more compact change logs.

I'm not fully comfortable with the practive of injecting variables into a changelog from java.
If that is possible, I can move my integration test to common.tests.changelog and pass in the current
database short name so that the testing can be used for all databases.

Currently only testing using H2 but since this feature is just liquibase based it should work fine with
all databases.
  • Loading branch information
damienbiggs committed Mar 8, 2013
1 parent e445123 commit ca13943
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 47 deletions.
22 changes: 22 additions & 0 deletions liquibase-core/src/main/java/liquibase/change/AbstractChange.java
Expand Up @@ -29,6 +29,8 @@
*/ */
public abstract class AbstractChange implements Change { public abstract class AbstractChange implements Change {


private String dbms;

private ChangeMetaData changeMetaData; private ChangeMetaData changeMetaData;


private ResourceAccessor resourceAccessor; private ResourceAccessor resourceAccessor;
Expand Down Expand Up @@ -236,6 +238,14 @@ public boolean supports(Database database) {
return true; return true;
} }


public boolean includes(final Database database) {
if (dbms == null || dbms.trim().isEmpty()) {
return true;
}
List<String> dbmsList = StringUtils.splitAndTrim(dbms, ",");
return dbmsList.contains(database.getShortName());
}

/** /**
* Implementation delegates logic to the {@link liquibase.sqlgenerator.SqlGenerator#warn(liquibase.statement.SqlStatement, liquibase.database.Database, liquibase.sqlgenerator.SqlGeneratorChain)} method on the {@link SqlStatement} objects returned by {@link #generateStatements }. * Implementation delegates logic to the {@link liquibase.sqlgenerator.SqlGenerator#warn(liquibase.statement.SqlStatement, liquibase.database.Database, liquibase.sqlgenerator.SqlGeneratorChain)} method on the {@link SqlStatement} objects returned by {@link #generateStatements }.
* If a generated statement is not supported for the given database, no warning will be added since that is a validation error. * If a generated statement is not supported for the given database, no warning will be added since that is a validation error.
Expand Down Expand Up @@ -403,6 +413,18 @@ public Set<DatabaseObject> getAffectedDatabaseObjects(Database database) {
return affectedObjects; return affectedObjects;
} }


/**
* @return A comma separated list of dbms' that this change will be run for. Will run for all dbms' if empty or null.
*/
@DatabaseChangeProperty(since = "3.0", exampleValue = "h2, oracle")
public String getDbms() {
return dbms;
}

public void setDbms(final String dbms) {
this.dbms = dbms;
}

public Set<String> getSerializableFields() { public Set<String> getSerializableFields() {
return getChangeMetaData().getParameters().keySet(); return getChangeMetaData().getParameters().keySet();
} }
Expand Down
5 changes: 5 additions & 0 deletions liquibase-core/src/main/java/liquibase/change/Change.java
Expand Up @@ -57,6 +57,11 @@ public interface Change extends LiquibaseSerializable {
*/ */
boolean supports(Database database); boolean supports(Database database);


/**
* @return Whether this change should run for the specified database
*/
boolean includes(Database database);

/** /**
* Generates warnings based on the configured Change instance. Warnings do not stop changelog execution, but are passed along to the end user for reference. * Generates warnings based on the configured Change instance. Warnings do not stop changelog execution, but are passed along to the end user for reference.
* Can return null or an empty Warnings object when there are no warnings. * Can return null or an empty Warnings object when there are no warnings.
Expand Down
Expand Up @@ -333,8 +333,12 @@ public ExecType execute(DatabaseChangeLog databaseChangeLog, Database database)


log.debug("Reading ChangeSet: " + toString()); log.debug("Reading ChangeSet: " + toString());
for (Change change : getChanges()) { for (Change change : getChanges()) {
database.executeStatements(change, databaseChangeLog, sqlVisitors); if (change.includes(database)) {
log.debug(change.getConfirmationMessage()); database.executeStatements(change, databaseChangeLog, sqlVisitors);
log.debug(change.getConfirmationMessage());
} else {
log.debug("Change " + change.getSerializedObjectName() + " not included for database " + database.getShortName());
}
} }


if (runInTransaction) { if (runInTransaction) {
Expand Down
Expand Up @@ -309,10 +309,14 @@
<xsd:attribute name="valueSequenceCurrent" type="xsd:string" /> <xsd:attribute name="valueSequenceCurrent" type="xsd:string" />
</xsd:attributeGroup> </xsd:attributeGroup>


<xsd:attributeGroup name="tableNameAttribute">
<xsd:attribute name="catalogName" type="xsd:string" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
</xsd:attributeGroup>

<xsd:attributeGroup name="dropTableAttributes"> <xsd:attributeGroup name="dropTableAttributes">
<xsd:attribute name="catalogName" type="xsd:string" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
<xsd:attribute name="cascadeConstraints" type="booleanExp" /> <xsd:attribute name="cascadeConstraints" type="booleanExp" />
</xsd:attributeGroup> </xsd:attributeGroup>


Expand All @@ -332,12 +336,6 @@
<xsd:attribute name="newViewName" type="xsd:string" use="required" /> <xsd:attribute name="newViewName" type="xsd:string" use="required" />
</xsd:attributeGroup> </xsd:attributeGroup>


<xsd:attributeGroup name="tableNameAttribute">
<xsd:attribute name="catalogName" type="xsd:string" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
</xsd:attributeGroup>

<xsd:attributeGroup name="renameColumnAttributes"> <xsd:attributeGroup name="renameColumnAttributes">
<xsd:attributeGroup ref="tableNameAttribute" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="oldColumnName" type="xsd:string" <xsd:attribute name="oldColumnName" type="xsd:string"
Expand Down Expand Up @@ -379,9 +377,7 @@


<xsd:element name="addPrimaryKey"> <xsd:element name="addPrimaryKey">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="catalogName" type="xsd:string" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
<xsd:attribute name="columnNames" type="xsd:string" <xsd:attribute name="columnNames" type="xsd:string"
use="required" /> use="required" />
<xsd:attribute name="constraintName" type="xsd:string" /> <xsd:attribute name="constraintName" type="xsd:string" />
Expand All @@ -391,18 +387,14 @@


<xsd:element name="dropPrimaryKey"> <xsd:element name="dropPrimaryKey">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="catalogName" type="xsd:string" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
<xsd:attribute name="constraintName" type="xsd:string" /> <xsd:attribute name="constraintName" type="xsd:string" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>


<xsd:element name="addUniqueConstraint"> <xsd:element name="addUniqueConstraint">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="catalogName" type="xsd:string" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
<xsd:attribute name="columnNames" type="xsd:string" <xsd:attribute name="columnNames" type="xsd:string"
use="required" /> use="required" />
<xsd:attribute name="constraintName" type="xsd:string" /> <xsd:attribute name="constraintName" type="xsd:string" />
Expand All @@ -415,19 +407,15 @@


<xsd:element name="dropUniqueConstraint"> <xsd:element name="dropUniqueConstraint">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="catalogName" type="xsd:string" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
<xsd:attribute name="constraintName" type="xsd:string" /> <xsd:attribute name="constraintName" type="xsd:string" />
<xsd:attribute name="uniqueColumns" type="xsd:string" /> <xsd:attribute name="uniqueColumns" type="xsd:string" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>


<xsd:element name="modifyDataType"> <xsd:element name="modifyDataType">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="catalogName" type="xsd:string" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
<xsd:attribute name="columnName" type="xsd:string" use="required" /> <xsd:attribute name="columnName" type="xsd:string" use="required" />
<xsd:attribute name="newDataType" type="xsd:string" use="required" /> <xsd:attribute name="newDataType" type="xsd:string" use="required" />
</xsd:complexType> </xsd:complexType>
Expand All @@ -454,9 +442,7 @@


<xsd:element name="addAutoIncrement"> <xsd:element name="addAutoIncrement">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="catalogName" type="xsd:string" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
<xsd:attribute name="columnName" type="xsd:string" use="required" /> <xsd:attribute name="columnName" type="xsd:string" use="required" />
<xsd:attribute name="columnDataType" type="xsd:string" /> <xsd:attribute name="columnDataType" type="xsd:string" />
<xsd:attribute name="startWith" type="xsd:long" /> <xsd:attribute name="startWith" type="xsd:long" />
Expand All @@ -466,9 +452,7 @@


<xsd:element name="addDefaultValue"> <xsd:element name="addDefaultValue">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="catalogName" type="xsd:string" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
<xsd:attribute name="columnName" type="xsd:string" use="required" /> <xsd:attribute name="columnName" type="xsd:string" use="required" />
<xsd:attribute name="columnDataType" type="xsd:string" /> <xsd:attribute name="columnDataType" type="xsd:string" />
<xsd:attribute name="defaultValue" type="xsd:string" /> <xsd:attribute name="defaultValue" type="xsd:string" />
Expand All @@ -482,9 +466,7 @@


<xsd:element name="dropDefaultValue"> <xsd:element name="dropDefaultValue">
<xsd:complexType> <xsd:complexType>
<xsd:attribute name="catalogName" type="xsd:string" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
<xsd:attribute name="columnName" type="xsd:string" use="required" /> <xsd:attribute name="columnName" type="xsd:string" use="required" />
<xsd:attribute name="columnDataType" type="xsd:string" /> <xsd:attribute name="columnDataType" type="xsd:string" />
</xsd:complexType> </xsd:complexType>
Expand All @@ -507,9 +489,7 @@
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="catalogName" type="xsd:string" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
<xsd:attribute name="file" type="xsd:string" /> <xsd:attribute name="file" type="xsd:string" />
<xsd:attribute name="encoding" type="xsd:string" default="UTF-8"/> <xsd:attribute name="encoding" type="xsd:string" default="UTF-8"/>
<xsd:attribute name="separator" type="xsd:string" default=","/> <xsd:attribute name="separator" type="xsd:string" default=","/>
Expand All @@ -534,9 +514,7 @@
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="catalogName" type="xsd:string" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
<xsd:attribute name="file" type="xsd:string" /> <xsd:attribute name="file" type="xsd:string" />
<xsd:attribute name="encoding" type="xsd:string" default="UTF-8"/> <xsd:attribute name="encoding" type="xsd:string" default="UTF-8"/>
<xsd:attribute name="primaryKey" type="xsd:string" use="required" /> <xsd:attribute name="primaryKey" type="xsd:string" use="required" />
Expand Down Expand Up @@ -579,9 +557,7 @@
</xsd:attributeGroup> </xsd:attributeGroup>


<xsd:attributeGroup name="addNotNullConstraintAttrib"> <xsd:attributeGroup name="addNotNullConstraintAttrib">
<xsd:attribute name="catalogName" type="xsd:string" /> <xsd:attributeGroup ref="tableNameAttribute" />
<xsd:attribute name="schemaName" type="xsd:string" />
<xsd:attribute name="tableName" type="xsd:string" use="required" />
<xsd:attribute name="columnName" type="xsd:string" use="required" /> <xsd:attribute name="columnName" type="xsd:string" use="required" />
<xsd:attribute name="defaultNullValue" type="xsd:string" /> <xsd:attribute name="defaultNullValue" type="xsd:string" />
<xsd:attribute name="columnDataType" type="xsd:string" /> <xsd:attribute name="columnDataType" type="xsd:string" />
Expand Down Expand Up @@ -916,6 +892,7 @@
<xsd:attribute name="stripComments" type="booleanExp" /> <xsd:attribute name="stripComments" type="booleanExp" />
<xsd:attribute name="splitStatements" type="booleanExp" /> <xsd:attribute name="splitStatements" type="booleanExp" />
<xsd:attribute name="endDelimiter" type="xsd:string" /> <xsd:attribute name="endDelimiter" type="xsd:string" />
<xsd:attribute name="dbms" type="xsd:string" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>


Expand Down Expand Up @@ -948,7 +925,8 @@
<xsd:attribute name="splitStatements" type="booleanExp" /> <xsd:attribute name="splitStatements" type="booleanExp" />
<xsd:attribute name="encoding" type="xsd:string" default="UTF-8"/> <xsd:attribute name="encoding" type="xsd:string" default="UTF-8"/>
<xsd:attribute name="endDelimiter" type="xsd:string" /> <xsd:attribute name="endDelimiter" type="xsd:string" />
<xsd:attribute name="relativeToChangelogFile" type="booleanExp" /> <xsd:attribute name="relativeToChangelogFile" type="booleanExp" />
<xsd:attribute name="dbms" type="xsd:string" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>


Expand Down
Expand Up @@ -200,11 +200,15 @@ public void testRunChangeLog() throws Exception {
} }


protected void runCompleteChangeLog() throws Exception { protected void runCompleteChangeLog() throws Exception {
Liquibase liquibase = createLiquibase(completeChangeLog); runChangeLog(completeChangeLog);
}

protected void runChangeLog(String changelogFile) throws Exception {
Liquibase liquibase = createLiquibase(changelogFile);
clearDatabase(liquibase); clearDatabase(liquibase);


//run again to test changelog testing logic //run again to test changelog testing logic
liquibase = createLiquibase(completeChangeLog); liquibase = createLiquibase(changelogFile);
try { try {
liquibase.update(this.contexts); liquibase.update(this.contexts);
} catch (ValidationFailedException e) { } catch (ValidationFailedException e) {
Expand Down
Expand Up @@ -12,8 +12,11 @@


public class H2IntegrationTest extends AbstractIntegrationTest { public class H2IntegrationTest extends AbstractIntegrationTest {


private final String changeSpecifyDbmsChangeLog;

public H2IntegrationTest() throws Exception { public H2IntegrationTest() throws Exception {
super("h2", "jdbc:h2:mem:liquibase"); super("h2", "jdbc:h2:mem:liquibase");
this.changeSpecifyDbmsChangeLog = "changelogs/h2/complete/change.specify.dbms.changelog.xml";
} }


@Test @Test
Expand Down Expand Up @@ -52,6 +55,11 @@ public void snapshot() throws Exception {
System.out.println(snapshot); System.out.println(snapshot);
} }


@Test
public void canSpecifyDbmsForIndividualChanges() throws Exception {
runChangeLog(changeSpecifyDbmsChangeLog);
}

// @Test // @Test
// public void testUpdateWithTurkishLocale() throws Exception { // public void testUpdateWithTurkishLocale() throws Exception {
// Locale originalDefault = Locale.getDefault(); // Locale originalDefault = Locale.getDefault();
Expand Down
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>

<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd">
<preConditions>
<dbms type="h2"/>
</preConditions>

<changeSet id="1" author="dbiggs">
<createTable tableName="testChangeDbms">
<column name="sampleColumn" type="varchar(50)"/>
</createTable>
<!-- sql will cause error if it was run -->
<sql dbms="oracle">select * from tableThatDoesNotExist</sql>
<insert tableName="testChangeDbms" dbms="h2">
<column name="sampleColumn" value="testValue"/>
</insert>
</changeSet>

<changeSet id="2" author="dbiggs">
<preConditions>
<sqlCheck expectedResult="1">select count(*) from testChangeDbms</sqlCheck>
</preConditions>
</changeSet>
</databaseChangeLog>

0 comments on commit ca13943

Please sign in to comment.