Permalink
Browse files

Add approach for excluding databases from running changesets.

Use ! to exclude a dbms.
E.g. to prevent oracle from running a changeset use dbms="h2,!oracle,mysql"
The changeset will run for h2 and mysql but not for oracle.
  • Loading branch information...
1 parent e445123 commit f377a1186a9b7a80c5a74a87b0073ce99ffb2191 @damienbiggs damienbiggs committed Mar 5, 2013
@@ -4,8 +4,11 @@
import liquibase.database.Database;
import liquibase.sql.visitor.SqlVisitor;
-import java.util.List;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
public class DbmsChangeSetFilter implements ChangeSetFilter {
@@ -18,12 +21,11 @@ public DbmsChangeSetFilter(Database database) {
public boolean accepts(ChangeSet changeSet) {
List<SqlVisitor> visitorsToRemove = new ArrayList<SqlVisitor>();
for (SqlVisitor visitor : changeSet.getSqlVisitors()) {
- if (databaseString != null && visitor.getApplicableDbms() != null && visitor.getApplicableDbms().size() > 0) {
- boolean shouldRemove = true;
- if (visitor.getApplicableDbms().contains(databaseString)) {
- shouldRemove = false;
- }
- if (shouldRemove) {
+ if (databaseString == null) {
+ continue;
+ }
+ if (visitor.getApplicableDbms() != null && visitor.getApplicableDbms().size() > 0) {
+ if (!visitor.getApplicableDbms().contains(databaseString)) {
visitorsToRemove.add(visitor);
}
}
@@ -33,17 +35,30 @@ public boolean accepts(ChangeSet changeSet) {
if (databaseString == null) {
return true;
}
+ Set<String> dbmsSet = changeSet.getDbmsSet();
- if (changeSet.getDbmsSet() == null) {
+ if (dbmsSet == null || dbmsSet.isEmpty()) {
return true;
}
- for (String dbms : changeSet.getDbmsSet()) {
- if (databaseString.equals(dbms)) {
- return true;
+ // !h2 would mean that the h2 database should be excluded
+ if (dbmsSet.contains("!" + databaseString)) {
+ return false;
+ }
+
+ Set<String> dbmsSupported = new HashSet<String>();
+ // add all dbms that do not start with ! to a list
+ for (String dbms: dbmsSet) {
+ if (!dbms.startsWith("!")) {
+ dbmsSupported.add(dbms);
}
}
+
+ if (dbmsSupported.isEmpty() || dbmsSupported.contains(databaseString)) {
+ return true;
+ }
+
return false;
}
}
@@ -74,7 +74,7 @@ public DatabaseChangeLog parse(String physicalChangeLogLocation, ChangeLogParame
Pattern runAlwaysPattern = Pattern.compile(".*runAlways:(\\w+).*", Pattern.CASE_INSENSITIVE);
Pattern contextPattern = Pattern.compile(".*context:([\\w,]+).*", Pattern.CASE_INSENSITIVE);
Pattern runInTransactionPattern = Pattern.compile(".*runInTransaction:(\\w+).*", Pattern.CASE_INSENSITIVE);
- Pattern dbmsPattern = Pattern.compile(".*dbms:(\\w+).*", Pattern.CASE_INSENSITIVE);
+ Pattern dbmsPattern = Pattern.compile(".*dbms:([\\w!]+).*", Pattern.CASE_INSENSITIVE);
Pattern failOnErrorPattern = Pattern.compile(".*failOnError:(\\w+).*", Pattern.CASE_INSENSITIVE);
Pattern onFailPattern = Pattern.compile(".*onFail:(\\w+).*", Pattern.CASE_INSENSITIVE);
Pattern onErrorPattern = Pattern.compile(".*onError:(\\w+).*", Pattern.CASE_INSENSITIVE);
@@ -25,6 +25,7 @@ public void singleDbms() {
assertTrue(filter.accepts(new ChangeSet(null, null, false, false, null,null, "mysql, oracle")));
assertFalse(filter.accepts(new ChangeSet(null, null, false, false, null,null, "oracle")));
assertTrue(filter.accepts(new ChangeSet(null, null, false, false, null, null, null)));
+ assertFalse(filter.accepts(new ChangeSet(null, null, false, false, null,null, "h2,!mysql")));
}
// @Test
@@ -18,6 +18,7 @@ public MarkChangeSetRanGeneratorTest() throws Exception {
super(new MarkChangeSetRanGenerator());
}
+ @Override
protected MarkChangeSetRanStatement createSampleSqlStatement() {
return new MarkChangeSetRanStatement(new ChangeSet("1", "a", false, false, "c", null, null), ChangeSet.ExecType.EXECUTED);
}
@@ -200,11 +200,15 @@ public void testRunChangeLog() throws Exception {
}
protected void runCompleteChangeLog() throws Exception {
- Liquibase liquibase = createLiquibase(completeChangeLog);
+ runChangeLogFile(completeChangeLog);
+ }
+
+ protected void runChangeLogFile(String changeLogFile) throws Exception {
+ Liquibase liquibase = createLiquibase(changeLogFile);
clearDatabase(liquibase);
//run again to test changelog testing logic
- liquibase = createLiquibase(completeChangeLog);
+ liquibase = createLiquibase(changeLogFile);
try {
liquibase.update(this.contexts);
} catch (ValidationFailedException e) {
@@ -12,8 +12,12 @@
public class H2IntegrationTest extends AbstractIntegrationTest {
+ private final String dbmsExcludeChangelog;
+
public H2IntegrationTest() throws Exception {
super("h2", "jdbc:h2:mem:liquibase");
+
+ this.dbmsExcludeChangelog = "changelogs/h2/complete/dbms.exclude.changelog.xml";
}
@Test
@@ -52,6 +56,11 @@ public void snapshot() throws Exception {
System.out.println(snapshot);
}
+ @Test
+ public void h2IsExcludedFromRunningChangeset() throws Exception {
+ runChangeLogFile(dbmsExcludeChangelog);
+ }
+
// @Test
// public void testUpdateWithTurkishLocale() throws Exception {
// Locale originalDefault = Locale.getDefault();
@@ -0,0 +1,29 @@
+<?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" dbms="!oracle">
+ <createTable tableName="testDbmsExclude">
+ <column name="sampleField" type="varchar(50)"/>
+ </createTable>
+ </changeSet>
+
+ <changeSet id="2" author="dbiggs" dbms="!h2">
+ <comment>Should never be executed by h2</comment>
+ <dropTable tableName="testDbmsExclude" />
+ </changeSet>
+
+ <changeSet id="3" author="dbiggs">
+ <preConditions>
+ <tableExists tableName="testDbmsExclude" />
+ </preConditions>
+ </changeSet>
+
+</databaseChangeLog>

0 comments on commit f377a11

Please sign in to comment.