Coverage Report - liquibase.precondition.core.PreconditionContainer
 
Classes in this File Line Coverage Branch Coverage Complexity
PreconditionContainer
50%
47/93
31%
17/54
3.278
PreconditionContainer$ErrorOption
83%
5/6
N/A
3.278
PreconditionContainer$FailOption
100%
6/6
N/A
3.278
PreconditionContainer$OnSqlOutputOption
83%
5/6
N/A
3.278
 
 1  
 package liquibase.precondition.core;
 2  
 
 3  
 import liquibase.util.StringUtils;
 4  
 import liquibase.util.StreamUtil;
 5  
 import liquibase.database.Database;
 6  
 import liquibase.changelog.DatabaseChangeLog;
 7  
 import liquibase.changelog.ChangeSet;
 8  
 import liquibase.exception.PreconditionFailedException;
 9  
 import liquibase.exception.PreconditionErrorException;
 10  
 import liquibase.exception.UnexpectedLiquibaseException;
 11  
 import liquibase.exception.ValidationFailedException;
 12  
 import liquibase.executor.Executor;
 13  
 import liquibase.executor.ExecutorService;
 14  
 import liquibase.logging.LogFactory;
 15  
 
 16  
 import java.util.ArrayList;
 17  
 import java.util.List;
 18  
 
 19  48
 public class PreconditionContainer extends AndPrecondition {
 20  
 
 21  4
     public enum FailOption {
 22  1
         HALT("HALT"), CONTINUE("CONTINUE"), MARK_RAN("MARK_RAN"), WARN("WARN");
 23  
 
 24  
         String key;
 25  
 
 26  4
         FailOption(String key) {
 27  4
             this.key = key;
 28  4
         }
 29  
 
 30  
         @Override
 31  
         public String toString() {
 32  3
             return key;
 33  
         }
 34  
     }
 35  
 
 36  1
     public enum ErrorOption {
 37  1
         HALT("HALT"), CONTINUE("CONTINUE"), MARK_RAN("MARK_RAN"), WARN("WARN");
 38  
 
 39  
         String key;
 40  
 
 41  4
         ErrorOption(String key) {
 42  4
             this.key = key;
 43  4
         }
 44  
 
 45  
         @Override
 46  
         public String toString() {
 47  0
             return key;
 48  
         }
 49  
     }
 50  
 
 51  1
     public enum OnSqlOutputOption {
 52  1
         IGNORE("IGNORE"), TEST("TEST"), FAIL("FAIL");
 53  
 
 54  
         String key;
 55  
 
 56  3
         OnSqlOutputOption(String key) {
 57  3
             this.key = key;
 58  3
         }
 59  
 
 60  
         @Override
 61  
         public String toString() {
 62  0
             return key;
 63  
         }
 64  
     }
 65  
 
 66  48
     private FailOption onFail = FailOption.HALT;
 67  48
     private ErrorOption onError = ErrorOption.HALT;
 68  48
     private OnSqlOutputOption onSqlOutput = OnSqlOutputOption.IGNORE;
 69  
     private String onFailMessage;
 70  
     private String onErrorMessage;
 71  
 
 72  
     public FailOption getOnFail() {
 73  1
         return onFail;
 74  
     }
 75  
 
 76  
     public void setOnFail(String onFail) {
 77  4
         if (onFail == null) {
 78  1
             this.onFail = FailOption.HALT;
 79  
         } else {
 80  9
             for (FailOption option : FailOption.values()) {
 81  9
                 if (option.key.equalsIgnoreCase(onFail)) {
 82  3
                     this.onFail = option;
 83  3
                     return;
 84  
                 }
 85  
             }
 86  0
             List<String> possibleOptions = new ArrayList<String>();
 87  0
             for (FailOption option : FailOption.values()) {
 88  0
                 possibleOptions.add(option.key);
 89  
             }
 90  0
             throw new RuntimeException("Unknown onFail attribute value '" + onFail + "'.  Possible values: "
 91  
                     + StringUtils.join(possibleOptions, ", "));
 92  
         }
 93  1
     }
 94  
 
 95  
     public ErrorOption getOnError() {
 96  0
         return onError;
 97  
     }
 98  
 
 99  
     public void setOnError(String onError) {
 100  1
         if (onError == null) {
 101  1
             this.onError = ErrorOption.HALT;
 102  
         } else {
 103  0
             for (ErrorOption option : ErrorOption.values()) {
 104  0
                 if (option.key.equalsIgnoreCase(onError)) {
 105  0
                     this.onError = option;
 106  0
                     return;
 107  
                 }
 108  
             }
 109  0
             List<String> possibleOptions = new ArrayList<String>();
 110  0
             for (ErrorOption option : ErrorOption.values()) {
 111  0
                 possibleOptions.add(option.key);
 112  
             }
 113  0
             throw new RuntimeException("Unknown onError attribute value '" + onError + "'.  Possible values: "
 114  
                     + StringUtils.join(possibleOptions, ", "));
 115  
         }
 116  1
     }
 117  
 
 118  
     public OnSqlOutputOption getOnSqlOutput() {
 119  0
         return onSqlOutput;
 120  
     }
 121  
 
 122  
     public void setOnSqlOutput(String onSqlOutput) {
 123  1
         if (onSqlOutput == null) {
 124  1
             setOnSqlOutput((OnSqlOutputOption) null);
 125  1
             return;
 126  
         }
 127  
 
 128  0
         for (OnSqlOutputOption option : OnSqlOutputOption.values()) {
 129  0
             if (option.key.equalsIgnoreCase(onSqlOutput)) {
 130  0
                 setOnSqlOutput(option);
 131  0
                 return;
 132  
             }
 133  
         }
 134  0
         List<String> possibleOptions = new ArrayList<String>();
 135  0
         for (OnSqlOutputOption option : OnSqlOutputOption.values()) {
 136  0
             possibleOptions.add(option.key);
 137  
         }
 138  0
         throw new RuntimeException("Unknown onSqlOutput attribute value '" + onSqlOutput + "'.  Possible values: "
 139  
                 + StringUtils.join(possibleOptions, ", "));
 140  
     }
 141  
 
 142  
     public void setOnSqlOutput(OnSqlOutputOption onSqlOutput) {
 143  1
         if (onSqlOutput == null) {
 144  1
             this.onSqlOutput = OnSqlOutputOption.IGNORE;
 145  
         } else {
 146  0
             this.onSqlOutput = onSqlOutput;
 147  
         }
 148  1
     }
 149  
 
 150  
     public String getOnFailMessage() {
 151  2
         return onFailMessage;
 152  
     }
 153  
 
 154  
     public void setOnFailMessage(String onFailMessage) {
 155  1
         this.onFailMessage = onFailMessage;
 156  1
     }
 157  
 
 158  
     public String getOnErrorMessage() {
 159  0
         return onErrorMessage;
 160  
     }
 161  
 
 162  
     public void setOnErrorMessage(String onErrorMessage) {
 163  1
         this.onErrorMessage = onErrorMessage;
 164  1
     }
 165  
 
 166  
     @Override
 167  
     public void check(Database database, DatabaseChangeLog changeLog, ChangeSet changeSet)
 168  
             throws PreconditionFailedException, PreconditionErrorException {
 169  3
         String ranOn = String.valueOf(changeLog);
 170  3
         if (changeSet != null) {
 171  1
             ranOn = String.valueOf(changeSet);
 172  
         }
 173  
 
 174  3
         Executor executor = ExecutorService.getInstance().getExecutor(database);
 175  
         try {
 176  
             // Three cases for preConditions onUpdateSQL:
 177  
             // 1. TEST: preConditions should be run, as in regular update mode
 178  
             // 2. FAIL: the preConditions should fail if there are any
 179  
             // 3. IGNORE: act as if preConditions don't exist
 180  3
             boolean testPrecondition = false;
 181  3
             if (executor.updatesDatabase()) {
 182  3
                 testPrecondition = true;
 183  
             } else {
 184  0
                 if (this.getOnSqlOutput().equals(PreconditionContainer.OnSqlOutputOption.TEST)) {
 185  0
                     testPrecondition = true;
 186  0
                 } else if (this.getOnSqlOutput().equals(PreconditionContainer.OnSqlOutputOption.FAIL)) {
 187  0
                     throw new PreconditionFailedException(
 188  
                             "Unexpected precondition in updateSQL mode with onUpdateSQL value: "
 189  
                                     + this.getOnSqlOutput(), changeLog, this);
 190  0
                 } else if (this.getOnSqlOutput().equals(PreconditionContainer.OnSqlOutputOption.IGNORE)) {
 191  0
                     testPrecondition = false;
 192  
                 }
 193  
             }
 194  
 
 195  3
             if (testPrecondition) {
 196  3
                 super.check(database, changeLog, changeSet);
 197  
             }
 198  1
         } catch (PreconditionFailedException e) {
 199  1
             StringBuffer message = new StringBuffer();
 200  1
             message.append("     ").append(e.getFailedPreconditions().size()).append(" preconditions failed")
 201  
                     .append(StreamUtil.getLineSeparator());
 202  1
             for (FailedPrecondition invalid : e.getFailedPreconditions()) {
 203  1
                 message.append("     ").append(invalid.toString());
 204  1
                 message.append(StreamUtil.getLineSeparator());
 205  
             }
 206  
 
 207  1
             if (getOnFailMessage() != null) {
 208  0
                 message = new StringBuffer(getOnFailMessage());
 209  
             }
 210  1
             if (this.getOnFail().equals(PreconditionContainer.FailOption.WARN)) {
 211  0
                 LogFactory.getLogger().info(
 212  
                         "Executing: " + ranOn + " despite precondition failure due to onFail='WARN':\n " + message);
 213  
             } else {
 214  1
                 if (getOnFailMessage() == null) {
 215  1
                     throw e;
 216  
                 } else {
 217  0
                     throw new PreconditionFailedException(getOnFailMessage(), changeLog, this);
 218  
                 }
 219  
             }
 220  0
         } catch (PreconditionErrorException e) {
 221  0
             StringBuffer message = new StringBuffer();
 222  0
             message.append("     ").append(e.getErrorPreconditions().size()).append(" preconditions failed")
 223  
                     .append(StreamUtil.getLineSeparator());
 224  0
             for (ErrorPrecondition invalid : e.getErrorPreconditions()) {
 225  0
                 message.append("     ").append(invalid.toString());
 226  0
                 message.append(StreamUtil.getLineSeparator());
 227  
             }
 228  
 
 229  0
             if (this.getOnError().equals(PreconditionContainer.ErrorOption.CONTINUE)) {
 230  0
                 LogFactory.getLogger().info(
 231  
                         "Continuing past: " + toString() + " despite precondition error:\n " + message);
 232  0
             } else if (this.getOnError().equals(PreconditionContainer.ErrorOption.WARN)) {
 233  0
                 LogFactory.getLogger().warning(
 234  
                         "Continuing past: " + toString() + " despite precondition error:\n " + message);
 235  
             } else {
 236  0
                 if (getOnErrorMessage() == null) {
 237  0
                     throw e;
 238  
                 } else {
 239  0
                     throw new PreconditionErrorException(getOnErrorMessage(), e.getErrorPreconditions());
 240  
                 }
 241  
             }
 242  2
         }
 243  2
     }
 244  
 }