1 19 package craftsman.spy; 20 21 import java.io.InputStream ; 22 import java.io.Reader ; 23 import java.math.BigDecimal ; 24 import java.net.URL ; 25 import java.sql.Array ; 26 import java.sql.Blob ; 27 import java.sql.Clob ; 28 import java.sql.Connection ; 29 import java.sql.Date ; 30 import java.sql.ParameterMetaData ; 31 import java.sql.PreparedStatement ; 32 import java.sql.Ref ; 33 import java.sql.ResultSet ; 34 import java.sql.ResultSetMetaData ; 35 import java.sql.SQLException ; 36 import java.sql.Time ; 37 import java.sql.Timestamp ; 38 import java.util.ArrayList ; 39 import java.util.Calendar ; 40 41 46 public class SpyPreparedStatement extends SpyStatement implements PreparedStatement { 47 50 private PreparedStatement real = null; 51 52 53 56 protected String preparedSql = null; 57 58 59 62 private ArrayList parameters = null; 63 64 65 72 protected SpyPreparedStatement ( Connection c, PreparedStatement pstm, String sql) { 73 super ( c, pstm); 74 real = pstm; 75 preparedSql = sql; 76 77 parameters = new ArrayList (1); 79 addParametersList(); 80 } 81 82 83 89 protected int getEstimatedParametersCount() { 90 int count = 0, index = 0; 91 while ( (index = preparedSql.indexOf('?', index+1)) != -1) count++; 92 93 return count; 94 } 95 96 97 100 private void addParametersList() { 101 parameters.add(new ArrayList (getEstimatedParametersCount()+1)); 103 104 ArrayList nextParameters = (ArrayList )parameters.get(parameters.size()-1); 106 if ( nextParameters!=null) { 107 for (int i = 0; i < getEstimatedParametersCount()+1; i++) nextParameters.add(i,null); 108 } else { 109 if ( log.isFatalEnabled()) log.fatal("the next parameters list is null (current size is "+parameters.size()+")"); 110 } 111 } 112 113 114 120 private void registerInputParameter (int paramIndex, Object parameter) { 121 if (parameters.size()==0 || parameters.get(parameters.size()-1)==null) { 123 addParametersList(); 124 } 125 126 ArrayList currentParameters = (ArrayList )parameters.get(parameters.size()-1); 127 if ( currentParameters!=null) { 128 if ( currentParameters.size()<=paramIndex) { 129 currentParameters.ensureCapacity(paramIndex+1); 130 for ( int i = currentParameters.size(); i < paramIndex; i++) currentParameters.add(i,null); 131 currentParameters.add(paramIndex,parameter); 132 } else { 133 currentParameters.set(paramIndex,parameter); 134 } 135 } else { 136 if ( log.isFatalEnabled()) log.fatal("the current parameters list is null (current size is "+parameters.size()+")"); 137 } 138 } 139 140 141 149 private String getDisplayableSql(int index) { 150 StringBuffer displayableSql = new StringBuffer (preparedSql.length()); 151 152 153 if ( parameters!=null) { 154 int i = 1, limit = 0, base = 0; 155 while ((limit = preparedSql.indexOf('?',limit)) != -1) { 156 displayableSql.append(preparedSql.substring(base,limit)); 157 if ( ((ArrayList )parameters.get(index)).get(i) instanceof String ) { 158 displayableSql.append("'"); 159 displayableSql.append(((ArrayList )parameters.get(index)).get(i)); 160 displayableSql.append("'"); 161 } else if ( ((ArrayList )parameters.get(index)).get(i)==null ) { 162 displayableSql.append("NULL"); 163 } else { 164 displayableSql.append(((ArrayList )parameters.get(index)).get(i)); 165 } 166 i++; 167 limit++; 168 base = limit; 169 } 170 171 if (base < preparedSql.length()) { 172 displayableSql.append(preparedSql.substring(base)); 173 } 174 } 175 176 return displayableSql.toString(); 177 } 178 179 180 186 private void logSql(String result, long time) { 187 if ( log.isInfoEnabled()) { 188 for (int i = 0; i < parameters.size(); i++) { 189 log.info(getId()+":"+getDisplayableSql(i)+" => "+result+" ("+(time)+" ms)"); 190 } 191 } 192 } 193 194 195 201 private void logSql(SQLException e, long time) { 202 if ( log.isErrorEnabled()) { 203 for (int i = 0; i < parameters.size(); i++) { 204 log.error(getId()+":"+getDisplayableSql(i)+" => state="+e.getSQLState()+",code="+e.getErrorCode()+" ("+(time)+" ms)",e); 205 } 206 } 207 } 208 209 210 213 public int executeUpdate() throws SQLException { 214 long end, start = System.currentTimeMillis(); 215 int result = 0; 216 217 218 try { 219 result = real.executeUpdate(); 220 end = System.currentTimeMillis(); 221 logSql(String.valueOf(result),end-start); 222 } catch ( SQLException e) { 223 end = System.currentTimeMillis(); 224 logSql(e,end-start); 225 throw e; 226 } 227 228 return result; 229 } 230 231 232 235 public void addBatch() throws SQLException { 236 addParametersList(); 237 real.addBatch(); 238 } 239 240 241 244 public void clearParameters() throws SQLException { 245 for ( int i = 0; i < parameters.size(); i++) parameters.remove(i); 246 real.clearParameters(); 247 } 248 249 250 253 public boolean execute() throws SQLException { 254 long end, start = System.currentTimeMillis(); 255 boolean result = false; 256 257 258 try { 259 result = real.execute(); 260 end = System.currentTimeMillis(); 261 logSql(String.valueOf(result),end-start); 262 } catch ( SQLException e) { 263 end = System.currentTimeMillis(); 264 logSql(e,end-start); 265 throw e; 266 } 267 268 return result; 269 } 270 271 272 275 public void setByte(int parameterIndex, byte x) throws SQLException { 276 registerInputParameter(parameterIndex,new Byte (x).toString()); 277 real.setByte(parameterIndex,x); 278 } 279 280 281 284 public void setDouble(int parameterIndex, double x) throws SQLException { 285 registerInputParameter(parameterIndex,new Double (x)); 286 real.setDouble(parameterIndex,x); 287 } 288 289 290 293 public void setFloat(int parameterIndex, float x) throws SQLException { 294 registerInputParameter(parameterIndex,new Float (x)); 295 real.setFloat(parameterIndex,x); 296 } 297 298 299 302 public void setInt(int parameterIndex, int x) throws SQLException { 303 registerInputParameter(parameterIndex,new Integer (x)); 304 real.setInt(parameterIndex,x); 305 } 306 307 308 311 public void setNull(int parameterIndex, int sqlType) throws SQLException { 312 registerInputParameter(parameterIndex,null); 313 real.setNull(parameterIndex,sqlType); 314 } 315 316 317 320 public void setLong(int parameterIndex, long x) throws SQLException { 321 registerInputParameter(parameterIndex,new Long (x)); 322 real.setLong(parameterIndex,x); 323 } 324 325 326 329 public void setShort(int parameterIndex, short x) throws SQLException { 330 registerInputParameter(parameterIndex,new Short (x)); 331 real.setShort(parameterIndex,x); 332 } 333 334 335 338 public void setBoolean(int parameterIndex, boolean x) throws SQLException { 339 registerInputParameter(parameterIndex,Boolean.valueOf(x).toString()); 340 real.setBoolean(parameterIndex,x); 341 } 342 343 344 347 public void setBytes(int parameterIndex, byte[] x) throws SQLException { 348 registerInputParameter(parameterIndex,x.toString()); 349 real.setBytes(parameterIndex,x); 350 } 351 352 353 356 public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { 357 registerInputParameter(parameterIndex,x.toString()); 358 real.setAsciiStream(parameterIndex,x,length); 359 } 360 361 362 365 public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { 366 registerInputParameter(parameterIndex,x.toString()); 367 real.setBinaryStream(parameterIndex,x,length); 368 } 369 370 371 374 public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { 375 registerInputParameter(parameterIndex,x.toString()); 376 real.setUnicodeStream(parameterIndex,x,length); 377 } 378 379 380 383 public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { 384 registerInputParameter(parameterIndex,reader.toString()); 385 real.setCharacterStream(parameterIndex,reader,length); 386 } 387 388 389 392 public void setObject(int parameterIndex, Object x) throws SQLException { 393 registerInputParameter(parameterIndex,x.toString()); 394 real.setObject(parameterIndex,x); 395 } 396 397 398 401 public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { 402 registerInputParameter(parameterIndex,x.toString()); 403 real.setObject(parameterIndex,x,targetSqlType); 404 } 405 406 407 410 public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException { 411 registerInputParameter(parameterIndex,x.toString()); 412 real.setObject(parameterIndex,x,targetSqlType,scale); 413 } 414 415 416 419 public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException { 420 registerInputParameter(paramIndex,null); 421 real.setNull(paramIndex,sqlType,typeName); 422 } 423 424 425 428 public void setString(int parameterIndex, String x) throws SQLException { 429 registerInputParameter(parameterIndex,x); 430 real.setString(parameterIndex,x); 431 } 432 433 434 437 public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { 438 registerInputParameter(parameterIndex,x.toString()); 439 real.setBigDecimal(parameterIndex,x); 440 } 441 442 443 446 public void setURL(int parameterIndex, URL x) throws SQLException { 447 registerInputParameter(parameterIndex,x.toString()); 448 real.setURL(parameterIndex,x); 449 } 450 451 452 455 public void setArray(int i, Array x) throws SQLException { 456 registerInputParameter(i,x.toString()); 457 real.setArray(i,x); 458 } 459 460 461 464 public void setBlob(int i, Blob x) throws SQLException { 465 registerInputParameter(i,x.toString()); 466 real.setBlob(i,x); 467 } 468 469 470 473 public void setClob(int i, Clob x) throws SQLException { 474 registerInputParameter(i,x.toString()); 475 real.setClob(i,x); 476 } 477 478 479 482 public void setDate(int parameterIndex, Date x) throws SQLException { 483 registerInputParameter(parameterIndex,x.toString()); 484 real.setDate(parameterIndex,x); 485 } 486 487 488 491 public ParameterMetaData getParameterMetaData() throws SQLException { 492 return real.getParameterMetaData(); 493 } 494 495 496 499 public void setRef(int i, Ref x) throws SQLException { 500 registerInputParameter(i,x.toString()); 501 real.setRef(i,x); 502 } 503 504 505 508 public ResultSet executeQuery() throws SQLException { 509 long end, start = System.currentTimeMillis(); 510 ResultSet result = null; 511 512 513 try { 514 result = new SpyResultSet ( getConnection(), this, real.executeQuery()); 515 end = System.currentTimeMillis(); 516 logSql("...",end-start); 517 } catch ( SQLException e) { 518 end = System.currentTimeMillis(); 519 logSql(e,end-start); 520 throw e; 521 } 522 523 return result; 524 } 525 526 527 530 public ResultSetMetaData getMetaData() throws SQLException { 531 return real.getMetaData(); 532 } 533 534 535 538 public void setTime(int parameterIndex, Time x) throws SQLException { 539 registerInputParameter(parameterIndex,x.toString()); 540 real.setTime(parameterIndex,x); 541 } 542 543 544 547 public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { 548 registerInputParameter(parameterIndex,x.toString()); 549 real.setTimestamp(parameterIndex,x); 550 } 551 552 553 556 public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { 557 registerInputParameter(parameterIndex,x.toString()); 558 real.setDate(parameterIndex,x,cal); 559 } 560 561 562 565 public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { 566 registerInputParameter(parameterIndex,x.toString()); 567 real.setTime(parameterIndex,x,cal); 568 } 569 570 571 574 public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { 575 registerInputParameter(parameterIndex,x.toString()); 576 real.setTimestamp(parameterIndex,x,cal); 577 } 578 579 580 583 public int[] executeBatch() throws SQLException { 584 for (int i = 0; i < parameters.size() - 1; i++) { 586 batch.add(getDisplayableSql(i)); 587 } 588 589 return super.executeBatch(); 591 } 592 } 593 | Popular Tags |