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