Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions dbdeploy-ant/src/main/java/com/dbdeploy/AntTarget.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import com.dbdeploy.database.DelimiterType;
import com.dbdeploy.database.LineEnding;
import com.dbdeploy.exceptions.UsageException;
import com.dbdeploy.scripts.ChangeScript;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

import java.io.File;
import java.util.List;

public class AntTarget extends Task {
private DbDeploy dbDeploy = new DbDeploy();
Expand Down Expand Up @@ -102,5 +104,27 @@ public void setEncoding(String encoding) {
public void setLineEnding(LineEnding lineEnding) {
dbDeploy.setLineEnding(lineEnding);
}

public void setChangeScriptFilterClassName(String className) {
ChangeScriptFilter filter = newChangeSciptFilter(className);
dbDeploy.setChangeScriptFilter(filter);
}

public void setExceptionsToContinueExecutionOn(String exceptionsCsv) {
dbDeploy.setExceptionsToContinueExecutionOn(exceptionsCsv);
}

private ChangeScriptFilter newChangeSciptFilter(String filterClassName) {
try {
ChangeScriptFilter filter = null;
if (filterClassName != null && !"".equals(filterClassName)) {
filter = (ChangeScriptFilter) getClass().getClassLoader().loadClass(filterClassName).newInstance();
}
return filter;
} catch (Exception e) {
throw new RuntimeException(e);
}
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CREATE TABLE Test (id INTEGER);

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
INSERT INTO Test VALUES (6);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CREATE TABLE Test (id INTEGER);

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
INSERT INTO Test VALUES (6);
10 changes: 10 additions & 0 deletions dbdeploy-core/src/main/java/com/dbdeploy/ChangeScriptFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.dbdeploy;

import com.dbdeploy.scripts.ChangeScript;

import java.util.List;

public interface ChangeScriptFilter {

public void process(List<ChangeScript> changeScripts);
}
30 changes: 25 additions & 5 deletions dbdeploy-core/src/main/java/com/dbdeploy/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,32 @@ public class Controller {
private final AppliedChangesProvider appliedChangesProvider;
private final ChangeScriptApplier changeScriptApplier;
private final ChangeScriptApplier undoScriptApplier;
private ChangeScriptFilter changeScriptFilter;

private final PrettyPrinter prettyPrinter = new PrettyPrinter();
private final PrettyPrinter prettyPrinter = new PrettyPrinter();

public Controller(AvailableChangeScriptsProvider availableChangeScriptsProvider,
AppliedChangesProvider appliedChangesProvider,
ChangeScriptApplier changeScriptApplier, ChangeScriptApplier undoScriptApplier) {
AppliedChangesProvider appliedChangesProvider,
ChangeScriptApplier changeScriptApplier, ChangeScriptApplier undoScriptApplier, ChangeScriptFilter changeScriptFilter) {
this.availableChangeScriptsProvider = availableChangeScriptsProvider;
this.appliedChangesProvider = appliedChangesProvider;
this.changeScriptApplier = changeScriptApplier;
this.undoScriptApplier = undoScriptApplier;
}
this.changeScriptFilter = maskNull(changeScriptFilter);
}

private ChangeScriptFilter maskNull(ChangeScriptFilter changeScriptFilter) {
if (changeScriptFilter == null) {
return new ChangeScriptFilter() {
public void process(List<ChangeScript> changeScripts) {
//no op
}
};
}
return changeScriptFilter;
}

public void processChangeScripts(Long lastChangeToApply) throws DbDeployException, IOException {
public void processChangeScripts(Long lastChangeToApply) throws DbDeployException, IOException {
if (lastChangeToApply != Long.MAX_VALUE) {
info("Only applying changes up and including change script #" + lastChangeToApply);
}
Expand All @@ -35,6 +48,8 @@ public void processChangeScripts(Long lastChangeToApply) throws DbDeployExceptio
List<Long> applied = appliedChangesProvider.getAppliedChanges();
List<ChangeScript> toApply = identifyChangesToApply(lastChangeToApply, scripts, applied);

applyFilter(toApply);

logStatus(scripts, applied, toApply);

changeScriptApplier.apply(Collections.unmodifiableList(toApply));
Expand All @@ -46,6 +61,11 @@ public void processChangeScripts(Long lastChangeToApply) throws DbDeployExceptio
}
}

private void applyFilter(List<ChangeScript> toApply) {
changeScriptFilter.process(toApply);
}


private void logStatus(List<ChangeScript> scripts, List<Long> applied, List<ChangeScript> toApply) {
info("Changes currently applied to database:\n " + prettyPrinter.format(applied));
info("Scripts available:\n " + prettyPrinter.formatChangeScriptList(scripts));
Expand Down
85 changes: 53 additions & 32 deletions dbdeploy-core/src/main/java/com/dbdeploy/DbDeploy.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

import java.io.File;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class DbDeploy {
private String url;
Expand All @@ -31,8 +34,10 @@ public class DbDeploy {
private String delimiter = ";";
private DelimiterType delimiterType = DelimiterType.normal;
private File templatedir;
private ChangeScriptFilter changeScriptFilter;
private List<String> exceptionsToContinueExecutionOn = new ArrayList<String>();

public void setDriver(String driver) {
public void setDriver(String driver) {
this.driver = driver;
}

Expand Down Expand Up @@ -80,51 +85,52 @@ public void setLineEnding(LineEnding lineEnding) {
this.lineEnding = lineEnding;
}

public void go() throws Exception {
System.err.println(getWelcomeString());
public void go() throws Exception {
System.err.println(getWelcomeString());

validate();
validate();

Class.forName(driver);
Class.forName(driver);

QueryExecuter queryExecuter = new QueryExecuter(url, userid, password);
QueryExecuter queryExecuter = new QueryExecuter(url, userid, password);

DatabaseSchemaVersionManager databaseSchemaVersionManager =
new DatabaseSchemaVersionManager(queryExecuter, changeLogTableName);
DatabaseSchemaVersionManager databaseSchemaVersionManager =
new DatabaseSchemaVersionManager(queryExecuter, changeLogTableName);

ChangeScriptRepository changeScriptRepository =
new ChangeScriptRepository(new DirectoryScanner(encoding).getChangeScriptsForDirectory(scriptdirectory));
ChangeScriptRepository changeScriptRepository =
new ChangeScriptRepository(new DirectoryScanner(encoding).getChangeScriptsForDirectory(scriptdirectory));

ChangeScriptApplier doScriptApplier;
ChangeScriptApplier doScriptApplier;

if (outputfile != null) {
doScriptApplier = new TemplateBasedApplier(
new PrintWriter(outputfile, encoding), dbms,
changeLogTableName, delimiter, delimiterType, getTemplatedir());
} else {
QueryStatementSplitter splitter = new QueryStatementSplitter();
splitter.setDelimiter(getDelimiter());
splitter.setDelimiterType(getDelimiterType());
splitter.setOutputLineEnding(lineEnding);
doScriptApplier = new DirectToDbApplier(queryExecuter, databaseSchemaVersionManager, splitter);
}
if (outputfile != null) {
doScriptApplier = new TemplateBasedApplier(
new PrintWriter(outputfile, encoding), dbms,
changeLogTableName, delimiter, delimiterType, getTemplatedir());
} else {
QueryStatementSplitter splitter = new QueryStatementSplitter();
splitter.setDelimiter(getDelimiter());
splitter.setDelimiterType(getDelimiterType());
splitter.setOutputLineEnding(lineEnding);
doScriptApplier = new DirectToDbApplier(queryExecuter, databaseSchemaVersionManager, splitter, exceptionsToContinueExecutionOn);

ChangeScriptApplier undoScriptApplier = null;
}

if (undoOutputfile != null) {
undoScriptApplier = new UndoTemplateBasedApplier(
new PrintWriter(undoOutputfile), dbms, changeLogTableName, delimiter, delimiterType, templatedir);
ChangeScriptApplier undoScriptApplier = null;

}
if (undoOutputfile != null) {
undoScriptApplier = new UndoTemplateBasedApplier(
new PrintWriter(undoOutputfile), dbms, changeLogTableName, delimiter, delimiterType, templatedir);

Controller controller = new Controller(changeScriptRepository, databaseSchemaVersionManager, doScriptApplier, undoScriptApplier);
}

controller.processChangeScripts(lastChangeToApply);
Controller controller = new Controller(changeScriptRepository, databaseSchemaVersionManager, doScriptApplier, undoScriptApplier, changeScriptFilter);

queryExecuter.close();
}
controller.processChangeScripts(lastChangeToApply);

queryExecuter.close();
}

private void validate() throws UsageException {
private void validate() throws UsageException {
checkForRequiredParameter(userid, "userid");
checkForRequiredParameter(driver, "driver");
checkForRequiredParameter(url, "url");
Expand Down Expand Up @@ -224,4 +230,19 @@ public String getEncoding() {
public LineEnding getLineEnding() {
return lineEnding;
}

public void setChangeScriptFilter(ChangeScriptFilter changeScriptFilter) {
this.changeScriptFilter = changeScriptFilter;
}

public void setExceptionsToContinueExecutionOn(String exceptionsCsv) {
StringTokenizer tokenizer = new StringTokenizer(exceptionsCsv, ",");
while(tokenizer.hasMoreTokens()) {
exceptionsToContinueExecutionOn.add(tokenizer.nextToken());
}
}

public List<String> getExceptionsToContinueExecutionOn() {
return exceptionsToContinueExecutionOn;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,68 @@
import com.dbdeploy.database.QueryStatementSplitter;
import com.dbdeploy.database.changelog.DatabaseSchemaVersionManager;
import com.dbdeploy.database.changelog.QueryExecuter;
import com.dbdeploy.exceptions.ChangeScriptApplierException;
import com.dbdeploy.exceptions.ChangeScriptFailedException;
import com.dbdeploy.scripts.ChangeScript;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class DirectToDbApplier implements ChangeScriptApplier {
private final QueryExecuter queryExecuter;
private final DatabaseSchemaVersionManager schemaVersionManager;
private final QueryStatementSplitter splitter;
private List<String> exceptionsToContinueExecutionOn;

public DirectToDbApplier(QueryExecuter queryExecuter, DatabaseSchemaVersionManager schemaVersionManager, QueryStatementSplitter splitter) {
public DirectToDbApplier(QueryExecuter queryExecuter, DatabaseSchemaVersionManager schemaVersionManager, QueryStatementSplitter splitter, List<String> exceptionsToContinueExecutionOn) {
this.queryExecuter = queryExecuter;
this.schemaVersionManager = schemaVersionManager;
this.splitter = splitter;
this.exceptionsToContinueExecutionOn = exceptionsToContinueExecutionOn;
}

public void apply(List<ChangeScript> changeScript) {
begin();

List<ChangeScriptFailedException> scriptFailedExceptions = new ArrayList<ChangeScriptFailedException>();
for (ChangeScript script : changeScript) {
System.err.println("Applying " + script + "...");

applyChangeScript(script);
insertToSchemaVersionTable(script);
try {

commitTransaction();
apply(script);

} catch (ChangeScriptFailedException e) {
String errorMessage = e.getCause().getMessage();
scriptFailedExceptions.add(e);
if (!containsMessagePartToIgnore(exceptionsToContinueExecutionOn, errorMessage)) {
break;
}
}
}

if (!scriptFailedExceptions.isEmpty()) {
throw new ChangeScriptApplierException(scriptFailedExceptions);
}
}

private boolean containsMessagePartToIgnore(List<String> exceptionsToIgnore, String errorMessage) {
for (String ignoreToken : exceptionsToIgnore) {
if (errorMessage.contains(ignoreToken)) {
return true;
}
}
return false;
}

private void apply(ChangeScript script) {
applyChangeScript(script);
insertToSchemaVersionTable(script);
commitTransaction();
}

public void begin() {
public void begin() {
try {
queryExecuter.setAutoCommit(false);
} catch (SQLException e) {
Expand Down Expand Up @@ -69,6 +100,4 @@ protected void commitTransaction() {
throw new RuntimeException();
}
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.dbdeploy.exceptions;

import java.util.List;

public class ChangeScriptApplierException extends DbDeployException {
List<ChangeScriptFailedException> changeScriptExceptions;

public ChangeScriptApplierException(List<ChangeScriptFailedException> changeScriptExceptions) {
this.changeScriptExceptions = changeScriptExceptions;
}

public List<ChangeScriptFailedException> getChangeScriptExceptions() {
return changeScriptExceptions;
}

@Override
public String getMessage() {
StringBuilder message = new StringBuilder();
message.append(buildMessage());
message.append("\n");
message.append("\n");
message.append(buildSuggession());
return message.toString();

}

private String buildSuggession() {
StringBuilder suggession = new StringBuilder();
suggession.append("If these scripts are already executed, run following command");
suggession.append("\n");
suggession.append("gradle -PjdbcUrl=<JDBC_URL> -PjdbcUserName=<JDBC_USERNAME> -PjdbcPassword=<JDBC_PASSWORD> -Pmigrations=");
suggession.append(changeScriptNamesCsv());
suggession.append(" :consultingdb:putMigrationInVersionTable");
return suggession.toString();

}

private String changeScriptNamesCsv() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < changeScriptExceptions.size(); i++) {
String scriptName = changeScriptExceptions.get(i).getScript().getFile().getName();
sb.append(scriptName);
if (i != (changeScriptExceptions.size() - 1)) {
sb.append(",");
}
}
return sb.toString();
}

private String buildMessage() {
StringBuilder message = new StringBuilder();
for (ChangeScriptFailedException changeScriptException : changeScriptExceptions) {
message.append(changeScriptException.getMessage());
message.append("\n");
}
return message.toString();
}
}
Loading