1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.migration;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.io.Reader;
21 import java.math.BigDecimal;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
25 import java.util.Properties;
26
27 import org.apache.ibatis.migration.utils.Util;
28
29 public class FileMigrationLoader implements MigrationLoader {
30 protected final File scriptsDir;
31
32 protected final String charset;
33
34 protected final Properties variables;
35
36 public FileMigrationLoader(File scriptsDir, String charset, Properties variables) {
37 this.scriptsDir = scriptsDir;
38 this.charset = charset;
39 this.variables = variables;
40 }
41
42 @Override
43 public List<Change> getMigrations() {
44 List<Change> migrations = new ArrayList<>();
45 if (scriptsDir.isDirectory()) {
46 String[] filenames = scriptsDir.list();
47 if (filenames == null) {
48 throw new MigrationException(scriptsDir + " does not exist.");
49 }
50 Arrays.sort(filenames);
51 for (String filename : filenames) {
52 if (filename.endsWith(".sql") && !isSpecialFile(filename)) {
53 Change change = parseChangeFromFilename(filename);
54 migrations.add(change);
55 }
56 }
57 }
58 return migrations;
59 }
60
61 protected boolean isSpecialFile(String filename) {
62 return "bootstrap.sql".equals(filename) || "onabort.sql".equals(filename);
63 }
64
65 protected Change parseChangeFromFilename(String filename) {
66 try {
67 Change change = new Change();
68 int lastIndexOfDot = filename.lastIndexOf('.');
69 String[] parts = filename.substring(0, lastIndexOfDot).split("_");
70 change.setId(new BigDecimal(parts[0]));
71 StringBuilder builder = new StringBuilder();
72 for (int i = 1; i < parts.length; i++) {
73 if (i > 1) {
74 builder.append(" ");
75 }
76 builder.append(parts[i]);
77 }
78 change.setDescription(builder.toString());
79 change.setFilename(filename);
80 return change;
81 } catch (Exception e) {
82 throw new MigrationException("Error parsing change from file. Cause: " + e, e);
83 }
84 }
85
86 @Override
87 public Reader getScriptReader(Change change, boolean undo) {
88 try {
89 return new MigrationReader(Util.file(scriptsDir, change.getFilename()), charset, undo, variables);
90 } catch (IOException e) {
91 throw new MigrationException("Error reading " + change.getFilename(), e);
92 }
93 }
94
95 @Override
96 public Reader getBootstrapReader() {
97 String fileName = "bootstrap.sql";
98 return getSoleScriptReader(fileName);
99 }
100
101 @Override
102 public Reader getOnAbortReader() {
103 String fileName = "onabort.sql";
104 return getSoleScriptReader(fileName);
105 }
106
107 protected Reader getSoleScriptReader(String fileName) {
108 try {
109 File scriptFile = Util.file(scriptsDir, fileName);
110 if (scriptFile.exists()) {
111 return new MigrationReader(scriptFile, charset, false, variables);
112 }
113 return null;
114 } catch (IOException e) {
115 throw new MigrationException("Error reading " + fileName, e);
116 }
117 }
118 }