package com.dbdeploy; import com.dbdeploy.exceptions.DbDeployException; import com.dbdeploy.scripts.ChangeScript; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Controller { private final AvailableChangeScriptsProvider availableChangeScriptsProvider; private final AppliedChangesProvider appliedChangesProvider; private final ChangeScriptApplier changeScriptApplier; private final ChangeScriptApplier undoScriptApplier; private final PrettyPrinter prettyPrinter = new PrettyPrinter(); public Controller(AvailableChangeScriptsProvider availableChangeScriptsProvider, AppliedChangesProvider appliedChangesProvider, ChangeScriptApplier changeScriptApplier, ChangeScriptApplier undoScriptApplier) { this.availableChangeScriptsProvider = availableChangeScriptsProvider; this.appliedChangesProvider = appliedChangesProvider; this.changeScriptApplier = changeScriptApplier; this.undoScriptApplier = undoScriptApplier; } public void processChangeScripts(Long lastChangeToApply) throws DbDeployException, IOException { if (lastChangeToApply != Long.MAX_VALUE) { info("Only applying changes up and including change script #" + lastChangeToApply); } List<ChangeScript> scripts = availableChangeScriptsProvider.getAvailableChangeScripts(); List<Long> applied = appliedChangesProvider.getAppliedChanges(); List<ChangeScript> toApply = identifyChangesToApply(lastChangeToApply, scripts, applied); logStatus(scripts, applied, toApply); changeScriptApplier.apply(Collections.unmodifiableList(toApply)); if (undoScriptApplier != null) { info("Generating undo scripts..."); Collections.reverse(toApply); undoScriptApplier.apply(Collections.unmodifiableList(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)); info("To be applied:\n " + prettyPrinter.formatChangeScriptList(toApply)); } private List<ChangeScript> identifyChangesToApply(Long lastChangeToApply, List<ChangeScript> scripts, List<Long> applied) { List<ChangeScript> result = new ArrayList<ChangeScript>(); for (ChangeScript script : scripts) { if (script.getId() > lastChangeToApply) break; if (!applied.contains(script.getId())) { result.add(script); } } return result; } private void info(String string) { System.err.println(string); } }