• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mybatis / ibatis-2 / 730

28 Dec 2025 10:16PM UTC coverage: 65.615% (+0.5%) from 65.146%
730

push

github

web-flow
Update README.md

1602 of 2802 branches covered (57.17%)

5053 of 7701 relevant lines covered (65.61%)

0.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.76
/src/main/java/com/ibatis/common/jdbc/ScriptRunner.java
1
/*
2
 * Copyright 2004-2025 the original author or authors.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *    https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package com.ibatis.common.jdbc;
17

18
import com.ibatis.common.resources.Resources;
19

20
import java.io.IOException;
21
import java.io.LineNumberReader;
22
import java.io.PrintWriter;
23
import java.io.Reader;
24
import java.sql.Connection;
25
import java.sql.Driver;
26
import java.sql.DriverManager;
27
import java.sql.ResultSet;
28
import java.sql.ResultSetMetaData;
29
import java.sql.SQLException;
30
import java.sql.Statement;
31

32
/**
33
 * Tool to run database scripts.
34
 */
35
public class ScriptRunner {
36

37
  /** The Constant DEFAULT_DELIMITER. */
38
  private static final String DEFAULT_DELIMITER = ";";
39

40
  /** The connection. */
41
  private Connection connection;
42

43
  /** The driver. */
44
  private String driver;
45

46
  /** The url. */
47
  private String url;
48

49
  /** The username. */
50
  private String username;
51

52
  /** The password. */
53
  private String password;
54

55
  /** The stop on error. */
56
  private boolean stopOnError;
57

58
  /** The auto commit. */
59
  private boolean autoCommit;
60

61
  /** The log writer. */
62
  private PrintWriter logWriter = new PrintWriter(System.out);
1✔
63

64
  /** The error log writer. */
65
  private PrintWriter errorLogWriter = new PrintWriter(System.err);
1✔
66

67
  /** The delimiter. */
68
  private String delimiter = DEFAULT_DELIMITER;
1✔
69

70
  /** The full line delimiter. */
71
  private boolean fullLineDelimiter;
72

73
  /**
74
   * Default constructor.
75
   *
76
   * @param connection
77
   *          the connection
78
   * @param autoCommit
79
   *          the auto commit
80
   * @param stopOnError
81
   *          the stop on error
82
   */
83
  public ScriptRunner(Connection connection, boolean autoCommit, boolean stopOnError) {
1✔
84
    this.connection = connection;
1✔
85
    this.autoCommit = autoCommit;
1✔
86
    this.stopOnError = stopOnError;
1✔
87
  }
1✔
88

89
  /**
90
   * Sets the delimiter.
91
   *
92
   * @param delimiter
93
   *          the delimiter
94
   * @param fullLineDelimiter
95
   *          the full line delimiter
96
   */
97
  public void setDelimiter(String delimiter, boolean fullLineDelimiter) {
98
    this.delimiter = delimiter;
×
99
    this.fullLineDelimiter = fullLineDelimiter;
×
100
  }
×
101

102
  /**
103
   * Instantiates a new script runner.
104
   *
105
   * @param driver
106
   *          the driver
107
   * @param url
108
   *          the url
109
   * @param username
110
   *          the username
111
   * @param password
112
   *          the password
113
   * @param autoCommit
114
   *          the auto commit
115
   * @param stopOnError
116
   *          the stop on error
117
   */
118
  public ScriptRunner(String driver, String url, String username, String password, boolean autoCommit,
119
      boolean stopOnError) {
×
120
    this.driver = driver;
×
121
    this.url = url;
×
122
    this.username = username;
×
123
    this.password = password;
×
124
    this.autoCommit = autoCommit;
×
125
    this.stopOnError = stopOnError;
×
126
  }
×
127

128
  /**
129
   * Setter for logWriter property.
130
   *
131
   * @param logWriter
132
   *          - the new value of the logWriter property
133
   */
134
  public void setLogWriter(PrintWriter logWriter) {
135
    this.logWriter = logWriter;
1✔
136
  }
1✔
137

138
  /**
139
   * Setter for errorLogWriter property.
140
   *
141
   * @param errorLogWriter
142
   *          - the new value of the errorLogWriter property
143
   */
144
  public void setErrorLogWriter(PrintWriter errorLogWriter) {
145
    this.errorLogWriter = errorLogWriter;
1✔
146
  }
1✔
147

148
  /**
149
   * Runs an SQL script (read in using the Reader parameter).
150
   *
151
   * @param reader
152
   *          - the source of the script
153
   *
154
   * @throws IOException
155
   *           Signals that an I/O exception has occurred.
156
   * @throws SQLException
157
   *           the SQL exception
158
   */
159
  public void runScript(Reader reader) throws IOException, SQLException {
160
    try {
161
      if (connection == null) {
1!
162
        DriverManager.registerDriver((Driver) Resources.instantiate(driver));
×
163
        Connection conn = DriverManager.getConnection(url, username, password);
×
164
        try {
165
          if (conn.getAutoCommit() != autoCommit) {
×
166
            conn.setAutoCommit(autoCommit);
×
167
          }
168
          runScript(conn, reader);
×
169
        } finally {
170
          conn.close();
×
171
        }
172
      } else {
×
173
        boolean originalAutoCommit = connection.getAutoCommit();
1✔
174
        try {
175
          if (originalAutoCommit != this.autoCommit) {
1✔
176
            connection.setAutoCommit(this.autoCommit);
1✔
177
          }
178
          runScript(connection, reader);
1✔
179
        } finally {
180
          connection.setAutoCommit(originalAutoCommit);
1✔
181
        }
182
      }
183
    } catch (IOException | SQLException e) {
×
184
      throw e;
×
185
    } catch (Exception e) {
×
186
      throw new RuntimeException("Error running script.  Cause: " + e, e);
×
187
    }
1✔
188
  }
1✔
189

190
  /**
191
   * Runs an SQL script (read in using the Reader parameter) using the connection passed in.
192
   *
193
   * @param conn
194
   *          - the connection to use for the script
195
   * @param reader
196
   *          - the source of the script
197
   *
198
   * @throws IOException
199
   *           if there is an error reading from the Reader
200
   * @throws SQLException
201
   *           if any SQL errors occur
202
   */
203
  private void runScript(Connection conn, Reader reader) throws IOException, SQLException {
204
    StringBuilder command = null;
1✔
205
    try {
206
      LineNumberReader lineReader = new LineNumberReader(reader);
1✔
207
      String line = null;
1✔
208
      while ((line = lineReader.readLine()) != null) {
1✔
209
        if (command == null) {
1✔
210
          command = new StringBuilder();
1✔
211
        }
212
        String trimmedLine = line.trim();
1✔
213
        if (trimmedLine.startsWith("--")) {
1✔
214
          println(trimmedLine);
1✔
215
        } else if (trimmedLine.isEmpty() || trimmedLine.startsWith("//") || trimmedLine.startsWith("--")) {
1!
216
          // Do nothing
217
        } else if (!fullLineDelimiter && trimmedLine.endsWith(getDelimiter())
1!
218
            || fullLineDelimiter && trimmedLine.equals(getDelimiter())) {
×
219
          command.append(line.substring(0, line.lastIndexOf(getDelimiter())));
1✔
220
          command.append(" ");
1✔
221
          Statement statement = conn.createStatement();
1✔
222

223
          println(command);
1✔
224

225
          boolean hasResults = false;
1✔
226
          if (stopOnError) {
1!
227
            hasResults = statement.execute(command.toString());
×
228
          } else {
229
            try {
230
              statement.execute(command.toString());
1✔
231
            } catch (SQLException e) {
1✔
232
              e.fillInStackTrace();
1✔
233
              printlnError("Error executing: " + command);
1✔
234
              printlnError(e);
1✔
235
            }
1✔
236
          }
237

238
          if (autoCommit && !conn.getAutoCommit()) {
1!
239
            conn.commit();
×
240
          }
241

242
          ResultSet rs = statement.getResultSet();
1✔
243
          if (hasResults && rs != null) {
1!
244
            ResultSetMetaData md = rs.getMetaData();
×
245
            int cols = md.getColumnCount();
×
246
            for (int i = 0; i < cols; i++) {
×
247
              String name = md.getColumnLabel(i + 1);
×
248
              print(name + "\t");
×
249
            }
250
            println("");
×
251
            while (rs.next()) {
×
252
              for (int i = 0; i < cols; i++) {
×
253
                String value = rs.getString(i + 1);
×
254
                print(value + "\t");
×
255
              }
256
              println("");
×
257
            }
258
          }
259

260
          command = null;
1✔
261
          try {
262
            statement.close();
1✔
263
          } catch (Exception e) {
×
264
            // Ignore to workaround a bug in Jakarta DBCP
265
          }
1✔
266
          Thread.yield();
1✔
267
        } else {
1✔
268
          command.append(line);
1✔
269
          command.append(" ");
1✔
270
        }
271
      }
1✔
272
      if (!autoCommit) {
1!
273
        conn.commit();
1✔
274
      }
275
    } catch (IOException | SQLException e) {
×
276
      e.fillInStackTrace();
×
277
      printlnError("Error executing: " + command);
×
278
      printlnError(e);
×
279
      throw e;
×
280
    } finally {
281
      conn.rollback();
1✔
282
      flush();
1✔
283
    }
284
  }
1✔
285

286
  /**
287
   * Gets the delimiter.
288
   *
289
   * @return the delimiter
290
   */
291
  private String getDelimiter() {
292
    return delimiter;
1✔
293
  }
294

295
  /**
296
   * Prints the.
297
   *
298
   * @param o
299
   *          the o
300
   */
301
  private void print(Object o) {
302
    if (logWriter != null) {
×
303
      System.out.print(o);
×
304
    }
305
  }
×
306

307
  /**
308
   * Println.
309
   *
310
   * @param o
311
   *          the o
312
   */
313
  private void println(Object o) {
314
    if (logWriter != null) {
1!
315
      logWriter.println(o);
×
316
    }
317
  }
1✔
318

319
  /**
320
   * Println error.
321
   *
322
   * @param o
323
   *          the o
324
   */
325
  private void printlnError(Object o) {
326
    if (errorLogWriter != null) {
1!
327
      errorLogWriter.println(o);
×
328
    }
329
  }
1✔
330

331
  /**
332
   * Flush.
333
   */
334
  private void flush() {
335
    if (logWriter != null) {
1!
336
      logWriter.flush();
×
337
    }
338
    if (errorLogWriter != null) {
1!
339
      errorLogWriter.flush();
×
340
    }
341
  }
1✔
342

343
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc