1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.bitrepository.service.database;
23
24 import java.io.IOException;
25 import java.io.LineNumberReader;
26 import java.io.Reader;
27 import java.sql.Connection;
28 import java.sql.ResultSet;
29 import java.sql.ResultSetMetaData;
30 import java.sql.SQLException;
31 import java.sql.Statement;
32
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36
37
38
39
40
41
42
43 public class SqlScriptRunner {
44 private static final String DEFAULT_DELIMITER = ";";
45 private static Logger log = LoggerFactory.getLogger(SqlScriptRunner.class);
46
47 private Connection connection;
48
49 private boolean stopOnError;
50 private boolean autoCommit;
51
52 private String delimiter = DEFAULT_DELIMITER;
53 private boolean fullLineDelimiter = false;
54
55
56
57
58
59
60
61 public SqlScriptRunner(Connection connection,
62 boolean autoCommit,
63 boolean stopOnError) {
64 this.connection = connection;
65 this.autoCommit = autoCommit;
66 this.stopOnError = stopOnError;
67 }
68
69
70
71
72
73 public void setDelimiter(String delimiter, boolean fullLineDelimiter) {
74 this.delimiter = delimiter;
75 this.fullLineDelimiter = fullLineDelimiter;
76 }
77
78
79
80
81
82
83
84 public void runScript(Reader reader) throws IOException, SQLException {
85 try {
86 boolean originalAutoCommit = connection.getAutoCommit();
87 if (originalAutoCommit != this.autoCommit) {
88 connection.setAutoCommit(this.autoCommit);
89 }
90 runScript(connection, reader);
91 connection.setAutoCommit(originalAutoCommit);
92 } catch (Exception e) {
93 throw new RuntimeException("Error running script. Cause: " + e, e);
94 }
95 }
96
97
98
99
100
101
102
103
104
105
106 private void runScript(Connection conn, Reader reader) throws IOException,
107 SQLException {
108 StringBuffer command = null;
109 try {
110 LineNumberReader lineReader = new LineNumberReader(reader);
111 String line = null;
112 while ((line = lineReader.readLine()) != null) {
113 if (command == null) {
114 command = new StringBuffer();
115 }
116 String trimmedLine = line.trim();
117 if (trimmedLine.startsWith("--") ||
118 trimmedLine.startsWith("//")) {
119
120 } else if (trimmedLine.length() == 0) {
121
122 } else if (trimmedLine.contains("connect")) {
123
124 } else if (!fullLineDelimiter
125 && trimmedLine.endsWith(getDelimiter())
126 || fullLineDelimiter
127 && trimmedLine.equals(getDelimiter())) {
128
129 command.append(trimLineForComment(line).substring(0, line
130 .lastIndexOf(getDelimiter())));
131 command.append(" ");
132
133 Statement statement = conn.createStatement();
134
135 log.debug("Executing statement: " + command.toString());
136
137 boolean hasResults = false;
138 if (stopOnError) {
139 hasResults = statement.execute(command.toString());
140 } else {
141 try {
142 statement.execute(command.toString());
143 } catch (SQLException e) {
144 e.fillInStackTrace();
145 log.error("Error executing: " + command, e);
146 }
147 }
148
149 if (autoCommit && !conn.getAutoCommit()) {
150 conn.commit();
151 }
152
153 ResultSet rs = statement.getResultSet();
154 StringBuilder resultSB = new StringBuilder();
155 if (hasResults && rs != null) {
156 ResultSetMetaData md = rs.getMetaData();
157 int cols = md.getColumnCount();
158 for (int i = 0; i < cols; i++) {
159 String name = md.getColumnLabel(i);
160 resultSB.append(name + "\t");
161 }
162 resultSB.append("\n");
163 while (rs.next()) {
164 for (int i = 0; i < cols; i++) {
165 String value = rs.getString(i);
166 resultSB.append(value + "\t");
167 }
168 resultSB.append("\n");
169 }
170 log.info("Result: " + resultSB.toString());
171 }
172
173 command = null;
174 try {
175 statement.close();
176 } catch (Exception e) {
177
178 }
179 Thread.yield();
180 } else {
181 command.append(trimLineForComment(line));
182 command.append(" ");
183 }
184 }
185 if (!autoCommit) {
186 conn.commit();
187 }
188 } catch (SQLException e) {
189 throw e;
190 } catch (IOException e) {
191 throw e;
192 }
193 }
194
195 private String trimLineForComment(String line) {
196 if (line.contains("--")) {
197 return line.substring(0, line.indexOf("--"));
198 } else {
199 return line;
200 }
201 }
202
203 private String getDelimiter() {
204 return delimiter;
205 }
206 }