001package org.javasimon.jdbc4; 002 003import java.io.InputStream; 004import java.io.Reader; 005import java.math.BigDecimal; 006import java.net.URL; 007import java.sql.Array; 008import java.sql.Blob; 009import java.sql.Clob; 010import java.sql.Connection; 011import java.sql.Date; 012import java.sql.NClob; 013import java.sql.ParameterMetaData; 014import java.sql.PreparedStatement; 015import java.sql.Ref; 016import java.sql.ResultSet; 017import java.sql.ResultSetMetaData; 018import java.sql.RowId; 019import java.sql.SQLException; 020import java.sql.SQLXML; 021import java.sql.Time; 022import java.sql.Timestamp; 023import java.util.Calendar; 024 025import org.javasimon.Split; 026 027/** 028 * Simon JDBC proxy prepared statement implementation class. 029 * 030 * @author Radovan Sninsky 031 * @author <a href="mailto:virgo47@gmail.com">Richard "Virgo" Richter</a> 032 * @see java.sql.PreparedStatement 033 * @since 2.4 034 */ 035@SuppressWarnings("deprecation") 036public class SimonPreparedStatement extends SimonStatement implements PreparedStatement { 037 /** 038 * SQL string. 039 */ 040 protected String sql; 041 042 private PreparedStatement stmt; 043 044 private final SqlNormalizerFactory sqlNormalizerFactory; 045 046 /** 047 * Class constructor, initializes Simons (lifespan, active) related to statement. 048 * @param conn database connection (simon impl.) 049 * @param stmt real prepared statement 050 * @param sql sql command 051 * @param prefix hierarchy prefix for statement Simons 052 * @param sqlNormalizerFactory factory to map queries to Simon keys 053 */ 054 SimonPreparedStatement(Connection conn, PreparedStatement stmt, String sql, String prefix, SqlNormalizerFactory sqlNormalizerFactory) { 055 super(conn, stmt, prefix, sqlNormalizerFactory); 056 057 this.stmt = stmt; 058 this.sql = sql; 059 this.sqlNormalizerFactory = sqlNormalizerFactory; 060 } 061 062 /** 063 * Called before each prepared SQL command execution. Prepares (obtains and starts) 064 * {@link org.javasimon.Stopwatch Stopwatch Simon} for measure SQL operation. 065 * 066 * @return Simon stopwatch object or null if sql is null or empty 067 */ 068 private Split prepare() { 069 if (sql != null && !sql.equals("")) { 070 sqlNormalizer = sqlNormalizerFactory.getNormalizer(sql); 071 sqlCmdLabel = prefix + ".sql." + sqlNormalizer.getType(); 072 return startSplit(); 073 } else { 074 return null; 075 } 076 } 077 078 /** 079 * Measure and execute prepared SQL operation. 080 * 081 * @return database rows and columns 082 * @throws java.sql.SQLException if real calls fails 083 */ 084 @Override 085 public final ResultSet executeQuery() throws SQLException { 086 Split split = prepare(); 087 try { 088 return new SimonResultSet(stmt.executeQuery(), this, prefix, split.getStopwatch().getName()); 089 } finally { 090 finish(split); 091 } 092 } 093 094 /** 095 * Measure and execute prepared SQL operation. 096 * 097 * @return count of updated rows 098 * @throws java.sql.SQLException if real calls fails 099 */ 100 @Override 101 public final int executeUpdate() throws SQLException { 102 Split split = prepare(); 103 try { 104 return stmt.executeUpdate(); 105 } finally { 106 finish(split); 107 } 108 } 109 110 /** 111 * Measure and execute prepared SQL operation. 112 * 113 * @return <code>true</code> if the first result is a <code>ResultSet</code> object; 114 * <code>false</code> if it is an update count or there are no results 115 * @throws java.sql.SQLException if real calls fails 116 */ 117 @Override 118 public final boolean execute() throws SQLException { 119 Split split = prepare(); 120 try { 121 return stmt.execute(); 122 } finally { 123 finish(split); 124 } 125 } 126 127 /** 128 * Adds prepared SQL command into batch list of sql and also into real batch. 129 * 130 * @throws java.sql.SQLException if real calls fails 131 */ 132 @Override 133 public final void addBatch() throws SQLException { 134 batchSql.add(sql); 135 136 stmt.addBatch(); 137 } 138 139 //// NOT MONITORED 140 141 @Override 142 public final void setNull(int i, int i1) throws SQLException { 143 stmt.setNull(i, i1); 144 } 145 146 @Override 147 public final void setBoolean(int i, boolean b) throws SQLException { 148 stmt.setBoolean(i, b); 149 } 150 151 @Override 152 public final void setByte(int i, byte b) throws SQLException { 153 stmt.setByte(i, b); 154 } 155 156 @Override 157 public final void setShort(int i, short i1) throws SQLException { 158 stmt.setShort(i, i1); 159 } 160 161 @Override 162 public final void setInt(int i, int i1) throws SQLException { 163 stmt.setInt(i, i1); 164 } 165 166 @Override 167 public final void setLong(int i, long l) throws SQLException { 168 stmt.setLong(i, l); 169 } 170 171 @Override 172 public final void setFloat(int i, float v) throws SQLException { 173 stmt.setFloat(i, v); 174 } 175 176 @Override 177 public final void setDouble(int i, double v) throws SQLException { 178 stmt.setDouble(i, v); 179 } 180 181 @Override 182 public final void setBigDecimal(int i, BigDecimal bigDecimal) throws SQLException { 183 stmt.setBigDecimal(i, bigDecimal); 184 } 185 186 @Override 187 public final void setString(int i, String s) throws SQLException { 188 stmt.setString(i, s); 189 } 190 191 @Override 192 public final void setBytes(int i, byte[] bytes) throws SQLException { 193 stmt.setBytes(i, bytes); 194 } 195 196 @Override 197 public final void setDate(int i, Date date) throws SQLException { 198 stmt.setDate(i, date); 199 } 200 201 @Override 202 public final void setTime(int i, Time time) throws SQLException { 203 stmt.setTime(i, time); 204 } 205 206 @Override 207 public final void setTimestamp(int i, Timestamp timestamp) throws SQLException { 208 stmt.setTimestamp(i, timestamp); 209 } 210 211 @Override 212 public final void setAsciiStream(int i, InputStream inputStream, int i1) throws SQLException { 213 stmt.setAsciiStream(i, inputStream, i1); 214 } 215 216 @Deprecated 217 @Override 218 public final void setUnicodeStream(int i, InputStream inputStream, int i1) throws SQLException { 219 stmt.setUnicodeStream(i, inputStream, i1); 220 } 221 222 @Override 223 public final void setBinaryStream(int i, InputStream inputStream, int i1) throws SQLException { 224 stmt.setBinaryStream(i, inputStream, i1); 225 } 226 227 @Override 228 public final void clearParameters() throws SQLException { 229 stmt.clearParameters(); 230 } 231 232 @Override 233 public final void setObject(int i, Object o, int i1) throws SQLException { 234 stmt.setObject(i, o, i1); 235 } 236 237 @Override 238 public final void setObject(int i, Object o) throws SQLException { 239 stmt.setObject(i, o); 240 } 241 242 @Override 243 public final void setObject(int i, Object o, int i1, int i2) throws SQLException { 244 stmt.setObject(i, o, i1, i2); 245 } 246 247 @Override 248 public final void setCharacterStream(int i, Reader reader, int i1) throws SQLException { 249 stmt.setCharacterStream(i, reader, i1); 250 } 251 252 @Override 253 public final void setRef(int i, Ref ref) throws SQLException { 254 stmt.setRef(i, ref); 255 } 256 257 @Override 258 public final void setBlob(int i, Blob blob) throws SQLException { 259 stmt.setBlob(i, blob); 260 } 261 262 @Override 263 public final void setClob(int i, Clob clob) throws SQLException { 264 stmt.setClob(i, clob); 265 } 266 267 @Override 268 public final void setArray(int i, Array array) throws SQLException { 269 stmt.setArray(i, array); 270 } 271 272 @Override 273 public final ResultSetMetaData getMetaData() throws SQLException { 274 return stmt.getMetaData(); 275 } 276 277 public final void setDate(int i, Date date, Calendar calendar) throws SQLException { 278 stmt.setDate(i, date, calendar); 279 } 280 281 @Override 282 public final void setTime(int i, Time time, Calendar calendar) throws SQLException { 283 stmt.setTime(i, time, calendar); 284 } 285 286 @Override 287 public final void setTimestamp(int i, Timestamp timestamp, Calendar calendar) throws SQLException { 288 stmt.setTimestamp(i, timestamp, calendar); 289 } 290 291 @Override 292 public final void setNull(int i, int i1, String s) throws SQLException { 293 stmt.setNull(i, i1, s); 294 } 295 296 @Override 297 public final void setURL(int i, URL url) throws SQLException { 298 stmt.setURL(i, url); 299 } 300 301 @Override 302 public final ParameterMetaData getParameterMetaData() throws SQLException { 303 return stmt.getParameterMetaData(); 304 } 305 306 @Override 307 public final void setRowId(int i, RowId rowId) throws SQLException { 308 stmt.setRowId(i, rowId); 309 } 310 311 @Override 312 public final void setNString(int i, String s) throws SQLException { 313 stmt.setNString(i, s); 314 } 315 316 @Override 317 public final void setNCharacterStream(int i, Reader reader, long l) throws SQLException { 318 stmt.setNCharacterStream(i, reader, l); 319 } 320 321 @Override 322 public final void setNClob(int i, NClob nClob) throws SQLException { 323 stmt.setNClob(i, nClob); 324 } 325 326 @Override 327 public final void setClob(int i, Reader reader, long l) throws SQLException { 328 stmt.setClob(i, reader, l); 329 } 330 331 @Override 332 public final void setBlob(int i, InputStream inputStream, long l) throws SQLException { 333 stmt.setBlob(i, inputStream, l); 334 } 335 336 @Override 337 public final void setNClob(int i, Reader reader, long l) throws SQLException { 338 stmt.setNClob(i, reader, l); 339 } 340 341 @Override 342 public final void setSQLXML(int i, SQLXML sqlxml) throws SQLException { 343 stmt.setSQLXML(i, sqlxml); 344 } 345 346 @Override 347 public final void setAsciiStream(int i, InputStream inputStream, long l) throws SQLException { 348 stmt.setAsciiStream(i, inputStream, l); 349 } 350 351 @Override 352 public final void setBinaryStream(int i, InputStream inputStream, long l) throws SQLException { 353 stmt.setBinaryStream(i, inputStream); 354 } 355 356 @Override 357 public final void setCharacterStream(int i, Reader reader, long l) throws SQLException { 358 stmt.setCharacterStream(i, reader, l); 359 } 360 361 @Override 362 public final void setAsciiStream(int i, InputStream inputStream) throws SQLException { 363 stmt.setAsciiStream(i, inputStream); 364 } 365 366 @Override 367 public final void setBinaryStream(int i, InputStream inputStream) throws SQLException { 368 stmt.setBinaryStream(i, inputStream); 369 } 370 371 @Override 372 public final void setCharacterStream(int i, Reader reader) throws SQLException { 373 stmt.setCharacterStream(i, reader); 374 } 375 376 @Override 377 public final void setNCharacterStream(int i, Reader reader) throws SQLException { 378 stmt.setNCharacterStream(i, reader); 379 } 380 381 @Override 382 public final void setClob(int i, Reader reader) throws SQLException { 383 stmt.setClob(i, reader); 384 } 385 386 @Override 387 public final void setBlob(int i, InputStream inputStream) throws SQLException { 388 stmt.setBlob(i, inputStream); 389 } 390 391 @Override 392 public final void setNClob(int i, Reader reader) throws SQLException { 393 stmt.setNClob(i, reader); 394 } 395 396}