001 package com.mockrunner.mock.jdbc;
002
003 import java.sql.BatchUpdateException;
004 import java.sql.Connection;
005 import java.sql.ResultSet;
006 import java.sql.SQLException;
007 import java.sql.SQLWarning;
008 import java.sql.Statement;
009 import java.util.ArrayList;
010 import java.util.List;
011
012 import com.mockrunner.base.NestedApplicationException;
013 import com.mockrunner.jdbc.AbstractResultSetHandler;
014 import com.mockrunner.jdbc.SQLUtil;
015
016 /**
017 * Mock implementation of <code>Statement</code>.
018 */
019 public class MockStatement implements Statement
020 {
021 private AbstractResultSetHandler resultSetHandler;
022 private ResultSet nextResultSet = null;
023 private int nextUpdateCount = -1;
024 private List batches = new ArrayList();
025 private String cursorName = "";
026 private int querySeconds = 0;
027 private int maxRows = 0;
028 private int maxFieldSize = 0;
029 private int fetchDirection = ResultSet.FETCH_FORWARD;
030 private int fetchSize = 0;
031 private int resultSetType = ResultSet.TYPE_FORWARD_ONLY;
032 private int resultSetConcurrency = ResultSet.CONCUR_READ_ONLY;
033 private int resultSetHoldability = ResultSet.HOLD_CURSORS_OVER_COMMIT;
034 private boolean closed = false;
035 private Connection connection;
036
037 public MockStatement(Connection connection)
038 {
039 this.connection = connection;
040 this.resultSetType = ResultSet.TYPE_FORWARD_ONLY;
041 this.resultSetConcurrency = ResultSet.CONCUR_READ_ONLY;
042 try
043 {
044 this.resultSetHoldability = connection.getMetaData().getResultSetHoldability();
045 }
046 catch(SQLException exc)
047 {
048 throw new NestedApplicationException(exc);
049 }
050 }
051
052 public MockStatement(Connection connection, int resultSetType, int resultSetConcurrency)
053 {
054 this.connection = connection;
055 this.resultSetType = resultSetType;
056 this.resultSetConcurrency = resultSetConcurrency;
057 try
058 {
059 this.resultSetHoldability = connection.getMetaData().getResultSetHoldability();
060 }
061 catch(SQLException exc)
062 {
063 throw new NestedApplicationException(exc);
064 }
065 }
066
067 public MockStatement(Connection connection, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
068 {
069 this.connection = connection;
070 this.resultSetType = resultSetType;
071 this.resultSetConcurrency = resultSetConcurrency;
072 this.resultSetHoldability = resultSetHoldability;
073 }
074
075 public boolean isClosed()
076 {
077 return closed;
078 }
079
080 public void setResultSetHandler(AbstractResultSetHandler resultSetHandler)
081 {
082 this.resultSetHandler = resultSetHandler;
083 }
084
085 protected void setNextResultSet(ResultSet resultSet)
086 {
087 this.nextResultSet = resultSet;
088 }
089
090 protected void setNextUpdateCount(int updateCount)
091 {
092 this.nextUpdateCount = updateCount;
093 }
094
095 public String getCursorName()
096 {
097 return cursorName;
098 }
099
100 public ResultSet executeQuery(String sql) throws SQLException
101 {
102 if(resultSetHandler.getThrowsSQLException(sql))
103 {
104 throw new SQLException("Statement " + sql + " was specified to throw an exception");
105 }
106 resultSetHandler.addExecutedStatement(sql);
107 MockResultSet result = resultSetHandler.getResultSet(sql);
108 if(null != result)
109 {
110 result = cloneResultSet(result);
111 resultSetHandler.addReturnedResultSet(result);
112 setNextResultSet(result);
113 return result;
114 }
115 result = cloneResultSet(resultSetHandler.getGlobalResultSet());
116 resultSetHandler.addReturnedResultSet(result);
117 setNextResultSet(result);
118 return result;
119 }
120
121 public int executeUpdate(String sql) throws SQLException
122 {
123 if(resultSetHandler.getThrowsSQLException(sql))
124 {
125 throw new SQLException("Statement " + sql + " was specified to throw an exception");
126 }
127 resultSetHandler.addExecutedStatement(sql);
128 Integer returnValue = resultSetHandler.getUpdateCount(sql);
129 if(null != returnValue)
130 {
131 int updateCount = returnValue.intValue();
132 setNextUpdateCount(updateCount);
133 return updateCount;
134 }
135 int updateCount = resultSetHandler.getGlobalUpdateCount();
136 setNextUpdateCount(updateCount);
137 return updateCount;
138 }
139
140 public void close() throws SQLException
141 {
142 closed = true;
143 }
144
145 public int getMaxFieldSize() throws SQLException
146 {
147 return maxFieldSize;
148 }
149
150 public void setMaxFieldSize(int maxFieldSize) throws SQLException
151 {
152 this.maxFieldSize = maxFieldSize;
153 }
154
155 public int getMaxRows() throws SQLException
156 {
157 return maxRows;
158 }
159
160 public void setMaxRows(int maxRows) throws SQLException
161 {
162 this.maxRows = maxRows;
163 }
164
165 public void setEscapeProcessing(boolean enable) throws SQLException
166 {
167
168 }
169
170 public int getQueryTimeout() throws SQLException
171 {
172 return querySeconds;
173 }
174
175 public void setQueryTimeout(int querySeconds) throws SQLException
176 {
177 this.querySeconds = querySeconds;
178 }
179
180 public void cancel() throws SQLException
181 {
182
183 }
184
185 public SQLWarning getWarnings() throws SQLException
186 {
187 return null;
188 }
189
190 public void clearWarnings() throws SQLException
191 {
192
193 }
194
195 public void setCursorName(String cursorName) throws SQLException
196 {
197 this.cursorName = cursorName;
198 }
199
200 public boolean execute(String sql) throws SQLException
201 {
202 boolean callExecuteQuery = isQuery(sql);
203 if(callExecuteQuery)
204 {
205 executeQuery(sql);
206 }
207 else
208 {
209 executeUpdate(sql);
210 }
211 return callExecuteQuery;
212 }
213
214 protected boolean isQuery(String sql)
215 {
216 boolean isQuery;
217 Boolean returnsResultSet = resultSetHandler.getReturnsResultSet(sql);
218 if(null != returnsResultSet)
219 {
220 isQuery = returnsResultSet.booleanValue();
221 }
222 else
223 {
224 isQuery = SQLUtil.isSelect(sql);
225 }
226 return isQuery;
227 }
228
229 public ResultSet getResultSet() throws SQLException
230 {
231 ResultSet tempResultSet = nextResultSet;
232 nextResultSet = null;
233 return tempResultSet;
234 }
235
236 public int getUpdateCount() throws SQLException
237 {
238 int tempUpdateCount = nextUpdateCount;
239 nextUpdateCount = -1;
240 return tempUpdateCount;
241 }
242
243 public boolean getMoreResults() throws SQLException
244 {
245 if(null != nextResultSet) return true;
246 return false;
247 }
248
249 public void setFetchDirection(int fetchDirection) throws SQLException
250 {
251 this.fetchDirection = fetchDirection;
252 }
253
254 public int getFetchDirection() throws SQLException
255 {
256 return fetchDirection;
257 }
258
259 public void setFetchSize(int fetchSize) throws SQLException
260 {
261 this.fetchSize = fetchSize;
262 }
263
264 public int getFetchSize() throws SQLException
265 {
266 return fetchSize;
267 }
268
269 public void addBatch(String sql) throws SQLException
270 {
271 batches.add(sql);
272 }
273
274 public void clearBatch() throws SQLException
275 {
276 batches.clear();
277 }
278
279 public int[] executeBatch() throws SQLException
280 {
281 int[] results = new int[batches.size()];
282 for(int ii = 0; ii < results.length; ii++)
283 {
284 String nextSQL = (String)batches.get(ii);
285 if(isQuery(nextSQL))
286 {
287 throw new BatchUpdateException("SQL " + batches.get(ii) + " in the list of batches returned a ResultSet.", null);
288 }
289 results[ii] = executeUpdate(nextSQL);
290 }
291 return results;
292 }
293
294 public Connection getConnection() throws SQLException
295 {
296 return connection;
297 }
298
299 public boolean getMoreResults(int current) throws SQLException
300 {
301 return getMoreResults();
302 }
303
304 public ResultSet getGeneratedKeys() throws SQLException
305 {
306 return null;
307 }
308
309 public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException
310 {
311 return executeUpdate(sql);
312 }
313
314 public int executeUpdate(String sql, int[] columnIndexes) throws SQLException
315 {
316 return executeUpdate(sql);
317 }
318
319 public int executeUpdate(String sql, String[] columnNames) throws SQLException
320 {
321 return executeUpdate(sql);
322 }
323
324 public boolean execute(String sql, int autoGeneratedKeys) throws SQLException
325 {
326 return execute(sql);
327 }
328
329 public boolean execute(String sql, int[] columnIndexes) throws SQLException
330 {
331 return execute(sql);
332 }
333
334 public boolean execute(String sql, String[] columnNames) throws SQLException
335 {
336 return execute(sql);
337 }
338
339 public int getResultSetType() throws SQLException
340 {
341 return resultSetType;
342 }
343
344 public int getResultSetConcurrency() throws SQLException
345 {
346 return resultSetConcurrency;
347 }
348
349 public int getResultSetHoldability() throws SQLException
350 {
351 return resultSetHoldability;
352 }
353
354 protected MockResultSet cloneResultSet(MockResultSet resultSet) throws SQLException
355 {
356 if(null == resultSet) return null;
357 MockResultSet clone = (MockResultSet)resultSet.clone();
358 clone.setStatement(this);
359 return clone;
360 }
361 }