Advertisement
Guest User

SQL ScriptRunner - Latest modification: Cater for NPE while parsing

a guest
Feb 11th, 2011
2,568
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.79 KB | None | 0 0
  1. /*
  2.  * Modified by Pantelis Sopasakis <chvng@mail.ntua.gr> to take care of DILIMITER
  3.  * statements. This way you can execute scripts that contain some TRIGGER creation
  4.  * code. New version using REGEXPs!
  5.  * Latest modification: Cater for a NullPointerException while parsing.
  6.  */
  7. /*
  8.  * Slightly modified version of the com.ibatis.common.jdbc.ScriptRunner class
  9.  * from the iBATIS Apache project. Only removed dependency on Resource class
  10.  * and a constructor
  11.  */
  12. /*
  13.  *  Copyright 2004 Clinton Begin
  14.  *
  15.  *  Licensed under the Apache License, Version 2.0 (the "License");
  16.  *  you may not use this file except in compliance with the License.
  17.  *  You may obtain a copy of the License at
  18.  *
  19.  *      http://www.apache.org/licenses/LICENSE-2.0
  20.  *
  21.  *  Unless required by applicable law or agreed to in writing, software
  22.  *  distributed under the License is distributed on an "AS IS" BASIS,
  23.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  24.  *  See the License for the specific language governing permissions and
  25.  *  limitations under the License.
  26.  */
  27.  
  28. import java.io.IOException;
  29. import java.io.LineNumberReader;
  30. import java.io.PrintWriter;
  31. import java.io.Reader;
  32. import java.sql.Connection;
  33. import java.sql.ResultSet;
  34. import java.sql.ResultSetMetaData;
  35. import java.sql.SQLException;
  36. import java.sql.Statement;
  37. import java.util.regex.Matcher;
  38. import java.util.regex.Pattern;
  39.  
  40. /**
  41.  * Tool to run database scripts
  42.  */
  43. public class ScriptRunner {
  44.  
  45.     private static final String DEFAULT_DELIMITER = ";";
  46.     private Connection connection;
  47.     private boolean stopOnError;
  48.     private boolean autoCommit;
  49.     private PrintWriter logWriter = new PrintWriter(System.out);
  50.     private PrintWriter errorLogWriter = new PrintWriter(System.err);
  51.     private String delimiter = DEFAULT_DELIMITER;
  52.     private boolean fullLineDelimiter = false;
  53.     private static final String DELIMITER_LINE_REGEX = "(?i)DELIMITER.+";
  54.     private static final String DELIMITER_LINE_SPLIT_REGEX = "(?i)DELIMITER";
  55.  
  56.     /**
  57.      * Default constructor
  58.      */
  59.     public ScriptRunner(Connection connection, boolean autoCommit,
  60.             boolean stopOnError) {
  61.         this.connection = connection;
  62.         this.autoCommit = autoCommit;
  63.         this.stopOnError = stopOnError;
  64.     }
  65.  
  66.     public void setDelimiter(String delimiter, boolean fullLineDelimiter) {
  67.         this.delimiter = delimiter;
  68.         this.fullLineDelimiter = fullLineDelimiter;
  69.     }
  70.  
  71.     /**
  72.      * Setter for logWriter property
  73.      *
  74.      * @param logWriter
  75.      *            - the new value of the logWriter property
  76.      */
  77.     public void setLogWriter(PrintWriter logWriter) {
  78.         this.logWriter = logWriter;
  79.     }
  80.  
  81.     /**
  82.      * Setter for errorLogWriter property
  83.      *
  84.      * @param errorLogWriter
  85.      *            - the new value of the errorLogWriter property
  86.      */
  87.     public void setErrorLogWriter(PrintWriter errorLogWriter) {
  88.         this.errorLogWriter = errorLogWriter;
  89.     }
  90.  
  91.     /**
  92.      * Runs an SQL script (read in using the Reader parameter)
  93.      *
  94.      * @param reader
  95.      *            - the source of the script
  96.      */
  97.     public void runScript(Reader reader) throws IOException, SQLException {
  98.         try {
  99.             boolean originalAutoCommit = connection.getAutoCommit();
  100.             try {
  101.                 if (originalAutoCommit != this.autoCommit) {
  102.                     connection.setAutoCommit(this.autoCommit);
  103.                 }
  104.                 runScript(connection, reader);
  105.             } finally {
  106.                 connection.setAutoCommit(originalAutoCommit);
  107.             }
  108.         } catch (IOException e) {
  109.             throw e;
  110.         } catch (SQLException e) {
  111.             throw e;
  112.         } catch (Exception e) {
  113.             throw new RuntimeException("Error running script.  Cause: " + e, e);
  114.         }
  115.     }
  116.  
  117.     /**
  118.      * Runs an SQL script (read in using the Reader parameter) using the
  119.      * connection passed in
  120.      *
  121.      * @param conn
  122.      *            - the connection to use for the script
  123.      * @param reader
  124.      *            - the source of the script
  125.      * @throws SQLException
  126.      *             if any SQL errors occur
  127.      * @throws IOException
  128.      *             if there is an error reading from the Reader
  129.      */
  130.     private void runScript(Connection conn, Reader reader) throws IOException,
  131.             SQLException {
  132.         StringBuffer command = null;
  133.         try {
  134.             LineNumberReader lineReader = new LineNumberReader(reader);
  135.             String line = null;
  136.             while ((line = lineReader.readLine()) != null) {
  137.                 if (command == null) {
  138.                     command = new StringBuffer();
  139.                 }
  140.                 String trimmedLine = line.trim();
  141.                 if (trimmedLine.startsWith("--")) {
  142.                     println(trimmedLine);
  143.                 } else if (trimmedLine.length() < 1
  144.                         || trimmedLine.startsWith("//")) {
  145.                     // Do nothing
  146.                 } else if (trimmedLine.length() < 1
  147.                         || trimmedLine.startsWith("--")) {
  148.                     // Do nothing
  149.                 } else if (!fullLineDelimiter
  150.                         && trimmedLine.endsWith(getDelimiter())
  151.                         || fullLineDelimiter
  152.                         && trimmedLine.equals(getDelimiter())) {
  153.  
  154.  
  155.                     Pattern pattern = Pattern.compile(DELIMITER_LINE_REGEX);
  156.                     Matcher matcher = pattern.matcher(trimmedLine);
  157.                     if (matcher.matches()) {
  158.                         setDelimiter(trimmedLine.split(DELIMITER_LINE_SPLIT_REGEX)[1].trim(), fullLineDelimiter);
  159.                         line = lineReader.readLine();
  160.                         if (line == null) {
  161.                             break;
  162.                         }
  163.                         trimmedLine = line.trim();
  164.                     }
  165.  
  166.                     command.append(line.substring(0, line.lastIndexOf(getDelimiter())));
  167.                     command.append(" ");
  168.                     Statement statement = conn.createStatement();
  169.  
  170.                     println(command);
  171.  
  172.                     boolean hasResults = false;
  173.                     if (stopOnError) {
  174.                         hasResults = statement.execute(command.toString());
  175.                     } else {
  176.                         try {
  177.                             statement.execute(command.toString());
  178.                         } catch (SQLException e) {
  179.                             e.fillInStackTrace();
  180.                             printlnError("Error executing: " + command);
  181.                             printlnError(e);
  182.                         }
  183.                     }
  184.  
  185.                     if (autoCommit && !conn.getAutoCommit()) {
  186.                         conn.commit();
  187.                     }
  188.  
  189.                     ResultSet rs = statement.getResultSet();
  190.                     if (hasResults && rs != null) {
  191.                         ResultSetMetaData md = rs.getMetaData();
  192.                         int cols = md.getColumnCount();
  193.                         for (int i = 0; i < cols; i++) {
  194.                             String name = md.getColumnLabel(i);
  195.                             print(name + "\t");
  196.                         }
  197.                         println("");
  198.                         while (rs.next()) {
  199.                             for (int i = 0; i < cols; i++) {
  200.                                 String value = rs.getString(i);
  201.                                 print(value + "\t");
  202.                             }
  203.                             println("");
  204.                         }
  205.                     }
  206.  
  207.                     command = null;
  208.                     try {
  209.                         statement.close();
  210.                     } catch (Exception e) {
  211.                         e.printStackTrace();
  212.                         // Ignore to workaround a bug in Jakarta DBCP
  213.                     }
  214.                     Thread.yield();
  215.                 } else {
  216.                     Pattern pattern = Pattern.compile(DELIMITER_LINE_REGEX);
  217.                     Matcher matcher = pattern.matcher(trimmedLine);
  218.                     if (matcher.matches()) {
  219.                         setDelimiter(trimmedLine.split(DELIMITER_LINE_SPLIT_REGEX)[1].trim(), fullLineDelimiter);
  220.                         line = lineReader.readLine();
  221.                         if (line == null) {
  222.                             break;
  223.                         }
  224.                         trimmedLine = line.trim();
  225.                     }
  226.                     command.append(line);
  227.                     command.append(" ");
  228.                 }
  229.             }
  230.             if (!autoCommit) {
  231.                 conn.commit();
  232.             }
  233.         } catch (SQLException e) {
  234.             e.fillInStackTrace();
  235.             printlnError("Error executing: " + command);
  236.             printlnError(e);
  237.             throw e;
  238.         } catch (IOException e) {
  239.             e.fillInStackTrace();
  240.             printlnError("Error executing: " + command);
  241.             printlnError(e);
  242.             throw e;
  243.         } finally {
  244.             conn.rollback();
  245.             flush();
  246.         }
  247.     }
  248.  
  249.     private String getDelimiter() {
  250.         return delimiter;
  251.     }
  252.  
  253.     private void print(Object o) {
  254.         if (logWriter != null) {
  255.             System.out.print(o);
  256.         }
  257.     }
  258.  
  259.     private void println(Object o) {
  260.         if (logWriter != null) {
  261.             logWriter.println(o);
  262.         }
  263.     }
  264.  
  265.     private void printlnError(Object o) {
  266.         if (errorLogWriter != null) {
  267.             errorLogWriter.println(o);
  268.         }
  269.     }
  270.  
  271.     private void flush() {
  272.         if (logWriter != null) {
  273.             logWriter.flush();
  274.         }
  275.         if (errorLogWriter != null) {
  276.             errorLogWriter.flush();
  277.         }
  278.     }
  279. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement