1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.migration.operations;
17
18 import java.io.PrintStream;
19 import java.math.BigDecimal;
20 import java.sql.Connection;
21 import java.sql.SQLException;
22 import java.util.List;
23
24 import org.apache.ibatis.migration.Change;
25 import org.apache.ibatis.migration.ConnectionProvider;
26 import org.apache.ibatis.migration.MigrationException;
27 import org.apache.ibatis.migration.MigrationLoader;
28 import org.apache.ibatis.migration.hook.MigrationHook;
29 import org.apache.ibatis.migration.options.DatabaseOperationOption;
30
31 public final class VersionOperation extends DatabaseOperation {
32 private BigDecimal version;
33
34 public VersionOperation(BigDecimal version) {
35 this.version = version;
36 if (version == null) {
37 throw new IllegalArgumentException("The version must be null.");
38 }
39 }
40
41 public VersionOperation operate(ConnectionProvider connectionProvider, MigrationLoader migrationsLoader,
42 DatabaseOperationOption option, PrintStream printStream) {
43 return operate(connectionProvider, migrationsLoader, option, printStream, null, null);
44 }
45
46 public VersionOperation operate(ConnectionProvider connectionProvider, MigrationLoader migrationsLoader,
47 DatabaseOperationOption option, PrintStream printStream, MigrationHook upHook, MigrationHook downHook) {
48 if (option == null) {
49 option = new DatabaseOperationOption();
50 }
51 try (Connection con = connectionProvider.getConnection()) {
52 List<Change> changesInDb = changelogExists(con, option) ? getChangelog(con, option) : List.of();
53 List<Change> migrations = migrationsLoader.getMigrations();
54 Change specified = new Change(version);
55 if (!migrations.contains(specified)) {
56 throw new MigrationException("A migration for the specified version number does not exist.");
57 }
58 Change lastChangeInDb = changesInDb.isEmpty() ? null : changesInDb.get(changesInDb.size() - 1);
59 if (lastChangeInDb == null || specified.compareTo(lastChangeInDb) > 0) {
60 println(printStream, "Upgrading to: " + version);
61 int steps = 0;
62 for (Change change : migrations) {
63 if ((lastChangeInDb == null || change.compareTo(lastChangeInDb) > 0) && change.compareTo(specified) < 1) {
64 steps++;
65 }
66 }
67 new UpOperation(steps).operate(connectionProvider, migrationsLoader, option, printStream, upHook);
68 } else if (specified.compareTo(lastChangeInDb) < 0) {
69 println(printStream, "Downgrading to: " + version);
70 int steps = 0;
71 for (Change change : migrations) {
72 if (change.compareTo(specified) > -1 && change.compareTo(lastChangeInDb) < 0) {
73 steps++;
74 }
75 }
76 new DownOperation(steps).operate(connectionProvider, migrationsLoader, option, printStream, downHook);
77 } else {
78 println(printStream, "Already at version: " + version);
79 }
80 println(printStream);
81 return this;
82 } catch (SQLException e) {
83 throw new MigrationException("Error creating connection. Cause: " + e, e);
84 }
85 }
86 }