View Javadoc
1   /*
2    *    Copyright 2010-2023 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.apache.ibatis.migration.operations;
17  
18  import java.io.PrintStream;
19  import java.io.PrintWriter;
20  import java.sql.Connection;
21  import java.sql.SQLException;
22  import java.text.SimpleDateFormat;
23  import java.util.List;
24  
25  import org.apache.ibatis.migration.Change;
26  import org.apache.ibatis.migration.MigrationException;
27  import org.apache.ibatis.migration.options.DatabaseOperationOption;
28  
29  public abstract class DatabaseOperation {
30  
31    protected void insertChangelog(Change change, Connection con, DatabaseOperationOption option) {
32      try {
33        ChangelogOperation operation = new ChangelogOperation(con, option);
34        change.setAppliedTimestamp(generateAppliedTimeStampAsString());
35        operation.insert(change);
36      } catch (SQLException e) {
37        throw new MigrationException("Error querying last applied migration.  Cause: " + e, e);
38      }
39    }
40  
41    protected List<Change> getChangelog(Connection con, DatabaseOperationOption option) {
42      try {
43        ChangelogOperation operation = new ChangelogOperation(con, option);
44        return operation.selectAll();
45      } catch (SQLException e) {
46        throw new MigrationException("Error querying last applied migration.  Cause: " + e, e);
47      }
48    }
49  
50    protected boolean changelogExists(Connection con, DatabaseOperationOption option) {
51      ChangelogOperation operation = new ChangelogOperation(con, option);
52      return operation.tableExists();
53    }
54  
55    protected String checkSkippedOrMissing(List<Change> changesInDb, List<Change> migrations) {
56      StringBuilder warnings = new StringBuilder();
57      String separator = System.lineSeparator();
58      int adjust = 0;
59      for (int i = 0; i < changesInDb.size(); i++) {
60        Change changeInDb = changesInDb.get(i);
61        int migrationIndex = migrations.indexOf(changeInDb);
62        if (migrationIndex == -1) {
63          // no corresponding migration script.
64          warnings.append("WARNING: Missing migration script. id='").append(changeInDb.getId()).append("', description='")
65              .append(changeInDb.getDescription()).append("'.").append(separator);
66          adjust++;
67        } else if (migrationIndex != i - adjust) {
68          // Unapplied migration script(s).
69          for (int j = i - adjust; j < migrationIndex; j++) {
70            adjust--;
71            warnings.append("WARNING: Migration script '").append(migrations.get(j).getFilename())
72                .append("' was not applied to the database.").append(separator);
73          }
74        }
75      }
76      return warnings.toString();
77    }
78  
79    protected ScriptRunner getScriptRunner(Connection connection, DatabaseOperationOption option,
80        PrintStream printStream) {
81      try {
82        PrintWriter outWriter = printStream == null ? null : new PrintWriter(printStream);
83        ScriptRunner scriptRunner = new ScriptRunner(connection);
84        scriptRunner.setLogWriter(outWriter);
85        scriptRunner.setErrorLogWriter(outWriter);
86        scriptRunner.setStopOnError(option.isStopOnError());
87        scriptRunner.setThrowWarning(option.isThrowWarning());
88        scriptRunner.setEscapeProcessing(false);
89        scriptRunner.setAutoCommit(option.isAutoCommit());
90        scriptRunner.setDelimiter(option.getDelimiter());
91        scriptRunner.setFullLineDelimiter(option.isFullLineDelimiter());
92        scriptRunner.setSendFullScript(option.isSendFullScript());
93        scriptRunner.setRemoveCRs(option.isRemoveCRs());
94        return scriptRunner;
95      } catch (Exception e) {
96        throw new MigrationException("Error creating ScriptRunner.  Cause: " + e, e);
97      }
98    }
99  
100   public static String generateAppliedTimeStampAsString() {
101     return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.sql.Date(System.currentTimeMillis()));
102   }
103 
104   protected void println(PrintStream printStream) {
105     if (printStream != null) {
106       printStream.println();
107     }
108   }
109 
110   protected void println(PrintStream printStream, String text) {
111     if (printStream != null) {
112       printStream.println(text);
113     }
114   }
115 }