View Javadoc
1   /*
2    *
3    * The DbUnit Database Testing Framework
4    * Copyright (C)2002-2004, 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.database;
22  
23  import java.sql.Connection;
24  import java.sql.ResultSet;
25  import java.sql.SQLException;
26  import java.sql.Statement;
27  
28  import org.dbunit.dataset.AbstractTable;
29  import org.dbunit.dataset.DataSetException;
30  import org.dbunit.dataset.ITableMetaData;
31  import org.slf4j.Logger;
32  import org.slf4j.LoggerFactory;
33  
34  /**
35   * @author Manuel Laflamme
36   * @since Apr 10, 2003
37   * @version $Revision$
38   */
39  public abstract class AbstractResultSetTable extends AbstractTable
40          implements IResultSetTable
41  {
42  
43      /**
44       * Logger for this class
45       */
46      private static final Logger logger = LoggerFactory.getLogger(AbstractResultSetTable.class);
47  
48      protected ITableMetaData _metaData;
49      private Statement _statement;
50      protected ResultSet _resultSet;
51  
52      public AbstractResultSetTable(ITableMetaData metaData, ResultSet resultSet)
53              throws SQLException, DataSetException
54      {
55          _metaData = metaData;
56          _resultSet = resultSet;
57      }
58  
59      public AbstractResultSetTable(String tableName, String selectStatement,
60              IDatabaseConnection connection)
61              throws DataSetException, SQLException
62      {
63          this(tableName, selectStatement, connection, false);
64      }
65      
66      /**
67       * @param tableName the table name.
68       * @param selectStatement the SQL select statement.
69       * @param connection the database connection.
70       * @param caseSensitiveTableNames whether table names are case-sensitive.
71       * @throws DataSetException if metadata retrieval fails.
72       * @throws SQLException if statement creation or execution fails.
73       * @since 2.4.1
74       */
75      public AbstractResultSetTable(String tableName, String selectStatement,
76              IDatabaseConnection connection, boolean caseSensitiveTableNames)
77              throws DataSetException, SQLException
78      {
79          this(tableName, selectStatement, connection, caseSensitiveTableNames, ResultSet.TYPE_FORWARD_ONLY);
80      }
81  
82      /**
83       * Creates a table from a table name, SQL, and connection using the given ResultSet type.
84       *
85       * @param tableName the table name.
86       * @param selectStatement the SQL select statement.
87       * @param connection the database connection.
88       * @param caseSensitiveTableNames whether table names are case-sensitive.
89       * @param resultSetType the JDBC ResultSet type (e.g. {@link ResultSet#TYPE_SCROLL_INSENSITIVE}).
90       * @throws DataSetException if metadata retrieval fails.
91       * @throws SQLException if statement creation or execution fails.
92       */
93      protected AbstractResultSetTable(String tableName, String selectStatement,
94              IDatabaseConnection connection, boolean caseSensitiveTableNames, int resultSetType)
95              throws DataSetException, SQLException
96      {
97          _statement = createStatement(connection, resultSetType);
98  
99          try
100         {
101             _resultSet = _statement.executeQuery(selectStatement);
102             _metaData = new ResultSetTableMetaData(tableName, _resultSet, connection, caseSensitiveTableNames);
103         }
104         catch (SQLException e)
105         {
106             _statement.close();
107             _statement = null;
108             throw e;
109         }
110     }
111 
112     public AbstractResultSetTable(ITableMetaData metaData,
113             IDatabaseConnection connection) throws DataSetException, SQLException
114     {
115         this(metaData, connection, ResultSet.TYPE_FORWARD_ONLY);
116     }
117 
118     /**
119      * Creates a table from a metadata descriptor and a connection using the given ResultSet type.
120      *
121      * @param metaData the table metadata.
122      * @param connection the database connection.
123      * @param resultSetType the JDBC ResultSet type (e.g. {@link ResultSet#TYPE_SCROLL_INSENSITIVE}).
124      * @throws DataSetException if metadata retrieval fails.
125      * @throws SQLException if statement creation or execution fails.
126      */
127     protected AbstractResultSetTable(ITableMetaData metaData,
128             IDatabaseConnection connection, int resultSetType)
129             throws DataSetException, SQLException
130     {
131         _statement = createStatement(connection, resultSetType);
132 
133         String escapePattern = (String) connection.getConfig()
134                 .getProperty(DatabaseConfig.PROPERTY_ESCAPE_PATTERN);
135 
136         try
137         {
138             String schema = connection.getSchema();
139             String selectStatement = getSelectStatement(schema, metaData, escapePattern);
140 
141             if (logger.isDebugEnabled())
142             {
143                 logger.debug("Query: {}", selectStatement);
144             }
145 
146             _resultSet = _statement.executeQuery(selectStatement);
147             _metaData = metaData;
148         }
149         catch (SQLException e)
150         {
151             _statement.close();
152             _statement = null;
153             throw e;
154         }
155     }
156 
157     private Statement createStatement(IDatabaseConnection connection) throws SQLException
158     {
159         return createStatement(connection, ResultSet.TYPE_FORWARD_ONLY);
160     }
161 
162     /**
163      * Creates a {@link Statement} with the specified ResultSet type.
164      * Subclasses use this to request scrollable result sets.
165      *
166      * @param connection the database connection.
167      * @param resultSetType one of {@link ResultSet#TYPE_FORWARD_ONLY},
168      *            {@link ResultSet#TYPE_SCROLL_INSENSITIVE}, or
169      *            {@link ResultSet#TYPE_SCROLL_SENSITIVE}.
170      * @return a configured statement.
171      * @throws SQLException if statement creation fails.
172      */
173     protected Statement createStatement(IDatabaseConnection connection, int resultSetType)
174             throws SQLException
175     {
176         logger.trace("createStatement(resultSetType={}) - start", resultSetType);
177 
178         Connection jdbcConnection = connection.getConnection();
179         Statement stmt = jdbcConnection.createStatement(resultSetType, ResultSet.CONCUR_READ_ONLY);
180         connection.getConfig().getConfigurator().configureStatement(stmt);
181         return stmt;
182     }
183 
184     static String getSelectStatement(String schema, ITableMetaData metaData, String escapePattern)
185             throws DataSetException
186     {
187         return DatabaseDataSet.getSelectStatement(schema, metaData, escapePattern);
188     }
189 
190     ////////////////////////////////////////////////////////////////////////////
191     // ITable interface
192 
193     public ITableMetaData getTableMetaData()
194     {
195         return _metaData;
196     }
197 
198     ////////////////////////////////////////////////////////////////////////////
199     // IResultSetTable interface
200 
201     public void close() throws DataSetException
202     {
203         logger.trace("close() - start");
204 
205         try
206         {
207             if (_resultSet != null)
208             {
209                 _resultSet.close();
210                 _resultSet = null;
211             }
212 
213             if (_statement != null)
214             {
215                 _statement.close();
216                 _statement = null;
217             }
218         }
219         catch (SQLException e)
220         {
221             throw new DataSetException(e);
222         }
223     }
224 
225     /**
226      * {@inheritDoc}
227      */
228     public String toString()
229     {
230         StringBuilder sb = new StringBuilder(2000);
231 
232         sb.append(getClass().getName()).append("[");
233         sb.append("_metaData=[").append(_metaData).append("], ");
234         sb.append("_resultSet=[").append(_resultSet).append("], ");
235         sb.append("_statement=[").append(_statement).append("]");
236         sb.append("]");
237 
238         return sb.toString();
239     }
240 }