-
Notifications
You must be signed in to change notification settings - Fork 77
/
DatabaseOperation.java
146 lines (134 loc) · 5.88 KB
/
DatabaseOperation.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/**
* Copyright 2010-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.migration.operations;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.apache.ibatis.jdbc.SqlRunner;
import org.apache.ibatis.migration.Change;
import org.apache.ibatis.migration.ConnectionProvider;
import org.apache.ibatis.migration.MigrationException;
import org.apache.ibatis.migration.options.DatabaseOperationOption;
public abstract class DatabaseOperation {
protected void insertChangelog(Change change, ConnectionProvider connectionProvider, DatabaseOperationOption option) {
SqlRunner runner = getSqlRunner(connectionProvider);
change.setAppliedTimestamp(generateAppliedTimeStampAsString());
try {
runner.insert("insert into " + option.getChangelogTable() + " (ID, APPLIED_AT, DESCRIPTION) values (?,?,?)",
change.getId(), change.getAppliedTimestamp(), change.getDescription());
} catch (SQLException e) {
throw new MigrationException("Error querying last applied migration. Cause: " + e, e);
} finally {
runner.closeConnection();
}
}
protected List<Change> getChangelog(ConnectionProvider connectionProvider, DatabaseOperationOption option) {
SqlRunner runner = getSqlRunner(connectionProvider);
try {
List<Map<String, Object>> changelog = runner
.selectAll("select ID, APPLIED_AT, DESCRIPTION from " + option.getChangelogTable() + " order by ID");
List<Change> changes = new ArrayList<Change>();
for (Map<String, Object> change : changelog) {
String id = change.get("ID") == null ? null : change.get("ID").toString();
String appliedAt = change.get("APPLIED_AT") == null ? null : change.get("APPLIED_AT").toString();
String description = change.get("DESCRIPTION") == null ? null : change.get("DESCRIPTION").toString();
changes.add(new Change(new BigDecimal(id), appliedAt, description));
}
return changes;
} catch (SQLException e) {
throw new MigrationException("Error querying last applied migration. Cause: " + e, e);
} finally {
runner.closeConnection();
}
}
protected boolean changelogExists(ConnectionProvider connectionProvider, DatabaseOperationOption option) {
SqlRunner runner = getSqlRunner(connectionProvider);
try {
runner.selectAll("select ID, APPLIED_AT, DESCRIPTION from " + option.getChangelogTable());
return true;
} catch (SQLException e) {
return false;
} finally {
runner.closeConnection();
}
}
protected void checkSkippedOrMissing(List<Change> changesInDb, List<Change> migrations, PrintStream printStream) {
int adjust = 0;
for (int i = 0; i < changesInDb.size(); i++) {
Change changeInDb = changesInDb.get(i);
int migrationIndex = migrations.indexOf(changeInDb);
if (migrationIndex == -1) {
// no corresponding migration script.
println(printStream, "WARNING: Missing migration script. id='" + changeInDb.getId() + "', description='"
+ changeInDb.getDescription() + "'.");
adjust++;
} else if (migrationIndex != (i - adjust)) {
// Unapplied migration script(s).
for (int j = i - adjust; j < migrationIndex; j++) {
adjust--;
println(printStream,
"WARNING: Migration script '" + migrations.get(j).getFilename() + "' was not applied to the database.");
}
}
}
}
protected SqlRunner getSqlRunner(ConnectionProvider connectionProvider) {
try {
return new SqlRunner(connectionProvider.getConnection());
} catch (SQLException e) {
throw new MigrationException("Could not create SqlRunner. Cause: " + e, e);
}
}
protected ScriptRunner getScriptRunner(ConnectionProvider connectionProvider, DatabaseOperationOption option,
PrintStream printStream) {
try {
PrintWriter outWriter = printStream == null ? null : new PrintWriter(printStream);
ScriptRunner scriptRunner = new ScriptRunner(connectionProvider.getConnection());
scriptRunner.setLogWriter(outWriter);
scriptRunner.setErrorLogWriter(outWriter);
scriptRunner.setStopOnError(option.isStopOnError());
scriptRunner.setThrowWarning(option.isThrowWarning());
scriptRunner.setEscapeProcessing(false);
scriptRunner.setAutoCommit(option.isAutoCommit());
scriptRunner.setDelimiter(option.getDelimiter());
scriptRunner.setFullLineDelimiter(option.isFullLineDelimiter());
scriptRunner.setSendFullScript(option.isSendFullScript());
scriptRunner.setRemoveCRs(option.isRemoveCRs());
return scriptRunner;
} catch (Exception e) {
throw new MigrationException("Error creating ScriptRunner. Cause: " + e, e);
}
}
public static String generateAppliedTimeStampAsString() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.sql.Date(System.currentTimeMillis()));
}
protected void println(PrintStream printStream) {
if (printStream != null) {
printStream.println();
}
}
protected void println(PrintStream printStream, String text) {
if (printStream != null) {
printStream.println(text);
}
}
}