View Javadoc
1   /*
2    *
3    * The DbUnit Database Testing Framework
4    * Copyright (C)2002-2017, DbUnit.org
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2.1 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   *
20   */
21  package org.dbunit;
22  
23  import org.dbunit.testutil.TestUtils;
24  import org.slf4j.Logger;
25  import org.slf4j.LoggerFactory;
26  
27  import java.io.BufferedReader;
28  import java.io.File;
29  import java.io.FileReader;
30  import java.io.IOException;
31  import java.sql.Connection;
32  import java.sql.SQLException;
33  import java.sql.SQLSyntaxErrorException;
34  import java.sql.Statement;
35  import java.util.StringTokenizer;
36  
37  /**
38   * Test Helper class for Executing DDL.
39   *
40   * @author Andrew Landsverk
41   * @version $Revision$
42   * @since DbUnit 2.6.0
43   */
44  public final class DdlExecutor
45  {
46      private static final Logger LOG =
47              LoggerFactory.getLogger(DdlExecutor.class);
48  
49      private DdlExecutor()
50      {
51          // no instances
52      }
53  
54      /**
55       * Execute DDL from the file (by name) against the given {@link Connection},
56       * dispatches to executeDdlFile and passes false for ignoreErrors.
57       * 
58       * @param ddlFileName
59       *            The name of the DDL file to execute.
60       * @param connection
61       *            The {@link Connection} to execute the DDL against.
62       * @param multiLineSupport
63       *            If this DataSource supports passing in all the lines at once
64       *            or if it needs to separate on ';'.
65       * @throws Exception
66       */
67      public static void execute(final String ddlFileName,
68              final Connection connection, final boolean multiLineSupport)
69              throws Exception
70      {
71          execute(ddlFileName, connection, multiLineSupport, false);
72      }
73  
74      /**
75       * Execute DDL from the file (by name) against the given {@link Connection},
76       * dispatches to executeDdlFile.
77       * 
78       * @param ddlFileName
79       *            The name of the DDL file to execute.
80       * @param connection
81       *            The {@link Connection} to execute the DDL against.
82       * @param multiLineSupport
83       *            If this DataSource supports passing in all the lines at once
84       *            or if it needs to separate on ';'.
85       * @param ignoreErrors
86       *            Set this to true if you want syntax errors to be ignored.
87       * @throws Exception
88       */
89      public static void execute(final String ddlFileName,
90              final Connection connection, final boolean multiLineSupport,
91              final boolean ignoreErrors) throws Exception
92      {
93          final File ddlFile = TestUtils.getFile(ddlFileName);
94          executeDdlFile(ddlFile, connection, multiLineSupport, ignoreErrors);
95      }
96  
97      /**
98       * Executes DDL from the {@link File} against the given {@link Connection}.
99       * Retrieves the multiLineSupport parameter from the profile.
100      * 
101      * @param ddlFile
102      *            The {@link File} object of the DDL file to execute.
103      * @param connection
104      *            The {@link Connection} to execute the DDL against.
105      * @throws Exception
106      */
107     public static void executeDdlFile(final File ddlFile,
108             final Connection connection) throws Exception
109     {
110         final boolean multiLineSupport = DatabaseEnvironment.getInstance()
111                 .getProfile().getProfileMultilineSupport();
112 
113         LOG.debug("Executing DDL from file={}, multiLineSupport={}", ddlFile,
114                 multiLineSupport);
115 
116         executeDdlFile(ddlFile, connection, multiLineSupport);
117     }
118 
119     /**
120      * Executes DDL from the {@link File} against the given {@link Connection}.
121      * Retrieves the multiLineSupport parameter from the profile and passes
122      * false for ignoreErrors.
123      * 
124      * @param ddlFile
125      *            The {@link File} object of the DDL file to execute.
126      * @param connection
127      *            The {@link Connection} to execute the DDL against.
128      * @param multiLineSupport
129      *            If this DataSource supports passing in all the lines at once
130      *            or if it needs to separate on ';'.
131      * @throws Exception
132      */
133     public static void executeDdlFile(final File ddlFile,
134             final Connection connection, final boolean multiLineSupport)
135             throws Exception
136     {
137         executeDdlFile(ddlFile, connection, multiLineSupport, false);
138     }
139 
140     /**
141      * Execute DDL from the {@link File} against the given {@link Connection}.
142      * 
143      * @param ddlFile
144      *            The {@link File} object of the DDL file to execute.
145      * @param connection
146      *            The {@link Connection} to execute the DDL against.
147      * @param multiLineSupport
148      *            If this DataSource supports passing in all the lines at once
149      *            or if it needs to separate on ';'.
150      * @param ignoreErrors
151      *            Set this to true if you want syntax errors to be ignored.
152      * @throws Exception
153      */
154     public static void executeDdlFile(final File ddlFile,
155             final Connection connection, final boolean multiLineSupport,
156             final boolean ignoreErrors) throws Exception
157     {
158         final String sql = readSqlFromFile(ddlFile);
159 
160         if (!multiLineSupport)
161         {
162             StringTokenizer tokenizer = new StringTokenizer(sql, ";");
163             while (tokenizer.hasMoreTokens())
164             {
165                 String token = tokenizer.nextToken();
166                 token = token.trim();
167                 if (token.length() > 0)
168                 {
169                     executeSql(connection, token, ignoreErrors);
170                 }
171             }
172         } else
173         {
174             executeSql(connection, sql, ignoreErrors);
175         }
176     }
177 
178     /**
179      * Execute an un-prepared SQL statement against the given
180      * {@link Connection}, passes false to ignoreErrors.
181      *
182      * @param connection
183      *            The {@link Connection} to execute against
184      * @param sql
185      *            The SQL {@link String} to execute
186      * @throws SQLException
187      */
188     public static void executeSql(final Connection connection, final String sql)
189             throws SQLException
190     {
191         executeSql(connection, sql, false);
192     }
193 
194     /**
195      * Execute an un-prepared SQL statement against the given
196      * {@link Connection}.
197      *
198      * @param connection
199      *            The {@link Connection} to execute against
200      * @param sql
201      *            The SQL {@link String} to execute
202      * @param ignoreErrors
203      *            Set this to true if you want syntax errors to be ignored.
204      * @throws SQLException
205      */
206     public static void executeSql(final Connection connection, final String sql,
207             final boolean ignoreErrors) throws SQLException
208     {
209         final Statement statement = connection.createStatement();
210         try
211         {
212             LOG.debug("Executing SQL={}", sql);
213             statement.execute(sql);
214         } catch (SQLSyntaxErrorException exception)
215         {
216             if (!ignoreErrors)
217             {
218                 throw exception;
219             }
220             LOG.debug("Ignoring error executing DDL={}",
221                     exception.getMessage());
222         } finally
223         {
224             statement.close();
225         }
226     }
227 
228     private static String readSqlFromFile(final File ddlFile) throws IOException
229     {
230         final BufferedReader sqlReader =
231                 new BufferedReader(new FileReader(ddlFile));
232         final StringBuilder sqlBuffer = new StringBuilder();
233         while (sqlReader.ready())
234         {
235             String line = sqlReader.readLine();
236             if (!line.startsWith("-"))
237             {
238                 sqlBuffer.append(line);
239             }
240         }
241 
242         sqlReader.close();
243 
244         final String sql = sqlBuffer.toString();
245         return sql;
246     }
247 
248 }