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 }