001 /** 002 * Copyright 2007-2008 Arthur Blake 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package net.sf.log4jdbc; 017 018 import java.io.InputStream; 019 import java.io.Reader; 020 import java.math.BigDecimal; 021 import java.net.URL; 022 import java.sql.*; 023 import java.util.ArrayList; 024 import java.util.Calendar; 025 import java.util.StringTokenizer; 026 import java.util.List; 027 028 /** 029 * Wraps a PreparedStatement and reports method calls, returns and exceptions. 030 * 031 * @author Arthur Blake 032 */ 033 public class PreparedStatementSpy extends StatementSpy implements PreparedStatement 034 { 035 036 private final SpyLogDelegator log; 037 038 /** 039 * holds list of bind variables for tracing 040 */ 041 protected final List argTrace = new ArrayList(); 042 043 // a way to turn on and off type help... 044 // todo: make this a configurable parameter 045 // todo, debug arrays and streams in a more useful manner.... if possible 046 private static final boolean showTypeHelp = false; 047 048 /** 049 * Store an argument (bind variable) into the argTrace list (above) for later dumping. 050 * 051 * @param i index of argument being set. 052 * @param typeHelper optional additional info about the type that is being set in the arg 053 * @param arg argument being bound. 054 */ 055 protected void argTraceSet(int i, String typeHelper, Object arg) 056 { 057 i--; // make the index 0 based 058 synchronized (argTrace) 059 { 060 // if an object is being inserted out of sequence, fill up missing values with null... 061 while (i >= argTrace.size()) 062 { 063 argTrace.add(argTrace.size(), null); 064 } 065 if (!showTypeHelp || typeHelper == null) 066 { 067 typeHelper = ""; 068 } 069 if (arg != null) 070 { 071 argTrace.set(i, typeHelper + arg.toString()); 072 } 073 else 074 { 075 argTrace.set(i, typeHelper + "null"); 076 } 077 } 078 } 079 080 private String sql; 081 082 protected String dumpedSql() 083 { 084 StringBuffer dumpSql = new StringBuffer(); 085 int lastPos = 0; 086 int Qpos = sql.indexOf('?', lastPos); // find position of first question mark 087 int argIdx = 0; 088 String arg; 089 090 while (Qpos != -1) 091 { 092 // get stored argument 093 synchronized (argTrace) 094 { 095 try 096 { 097 arg = (String) argTrace.get(argIdx); 098 } 099 catch (IndexOutOfBoundsException e) 100 { 101 arg = "?"; 102 } 103 } 104 if (arg == null) 105 { 106 arg = "?"; 107 } 108 109 argIdx++; 110 111 dumpSql.append(sql.substring(lastPos, Qpos)); // dump segment of sql up to question mark. 112 lastPos = Qpos + 1; 113 Qpos = sql.indexOf('?', lastPos); 114 dumpSql.append(arg); 115 } 116 if (lastPos < sql.length()) 117 { 118 dumpSql.append(sql.substring(lastPos, sql.length())); // dump last segment 119 } 120 121 // insert line breaks into sql to make it more readable 122 StringBuffer output = new StringBuffer(); 123 StringTokenizer st = new StringTokenizer(dumpSql.toString()); 124 125 String token; 126 int linelength = 0; 127 128 while (st.hasMoreElements()) 129 { 130 token = (String) st.nextElement(); 131 132 output.append(token); 133 linelength += token.length(); 134 output.append(" "); 135 linelength++; 136 if (linelength > 90) 137 { 138 output.append("\n"); 139 linelength = 0; 140 } 141 } 142 143 return output.toString(); 144 } 145 146 protected void reportAllReturns(String methodCall, String msg) 147 { 148 log.methodReturned(this, methodCall, msg); 149 } 150 151 /** 152 * The real PreparedStatement that this PreparedStatementSpy wraps. 153 */ 154 protected PreparedStatement realPreparedStatement; 155 156 /** 157 * RdbmsSpecifics for formatting SQL for the given RDBMS. 158 */ 159 protected RdbmsSpecifics rdbmsSpecifics; 160 161 /** 162 * Create a PreparedStatementSpy (JDBC 4.0 version) for logging activity of another PreparedStatement. 163 * 164 * @param sql SQL for the prepared statement that is being spied upon. 165 * @param connectionSpy ConnectionSpy that was called to produce this PreparedStatement. 166 * @param realPreparedStatement The actual PreparedStatement that is being spied upon. 167 */ 168 public PreparedStatementSpy(String sql, ConnectionSpy connectionSpy, PreparedStatement realPreparedStatement) 169 { 170 super(connectionSpy, realPreparedStatement); // does null check for us 171 this.sql = sql; 172 this.realPreparedStatement = realPreparedStatement; 173 log = SpyLogFactory.getSpyLogDelegator(); 174 rdbmsSpecifics = connectionSpy.getRdbmsSpecifics(); 175 } 176 177 public String getClassType() 178 { 179 return "PreparedStatement"; 180 } 181 182 // forwarding methods 183 184 public void setTime(int parameterIndex, Time x) throws SQLException 185 { 186 String methodCall = "setTime(" + parameterIndex + ", " + x + ")"; 187 argTraceSet(parameterIndex, "(Time)", x); 188 try 189 { 190 realPreparedStatement.setTime(parameterIndex, x); 191 } 192 catch (SQLException s) 193 { 194 reportException(methodCall, s); 195 throw s; 196 } 197 reportReturn(methodCall); 198 } 199 200 public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException 201 { 202 String methodCall = "setTime(" + parameterIndex + ", " + x + ", " + cal + ")"; 203 argTraceSet(parameterIndex, "(Time)", x); 204 try 205 { 206 realPreparedStatement.setTime(parameterIndex, x, cal); 207 } 208 catch (SQLException s) 209 { 210 reportException(methodCall, s); 211 throw s; 212 } 213 reportReturn(methodCall); 214 } 215 216 public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException 217 { 218 String methodCall = "setCharacterStream(" + parameterIndex + ", " + reader + ", " + length + ")"; 219 argTraceSet(parameterIndex, "(Reader)", "<Reader of length " + length + ">"); 220 try 221 { 222 realPreparedStatement.setCharacterStream(parameterIndex, reader, length); 223 } 224 catch (SQLException s) 225 { 226 reportException(methodCall, s); 227 throw s; 228 } 229 reportReturn(methodCall); 230 } 231 232 public void setNull(int parameterIndex, int sqlType) throws SQLException 233 { 234 String methodCall = "setNull(" + parameterIndex + ", " + sqlType + ")"; 235 argTraceSet(parameterIndex, null, "null"); 236 try 237 { 238 realPreparedStatement.setNull(parameterIndex, sqlType); 239 } 240 catch (SQLException s) 241 { 242 reportException(methodCall, s); 243 throw s; 244 } 245 reportReturn(methodCall); 246 } 247 248 public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException 249 { 250 String methodCall = "setNull(" + paramIndex + ", " + sqlType + ", " + typeName + ")"; 251 argTraceSet(paramIndex, null, "null"); 252 try 253 { 254 realPreparedStatement.setNull(paramIndex, sqlType, typeName); 255 } 256 catch (SQLException s) 257 { 258 reportException(methodCall, s); 259 throw s; 260 } 261 reportReturn(methodCall); 262 } 263 264 public void setRef(int i, Ref x) throws SQLException 265 { 266 String methodCall = "setRef(" + i + ", " + x + ")"; 267 argTraceSet(i, "(Ref)", x); 268 try 269 { 270 realPreparedStatement.setRef(i, x); 271 } 272 catch (SQLException s) 273 { 274 reportException(methodCall, s); 275 throw s; 276 } 277 reportReturn(methodCall); 278 } 279 280 public void setBoolean(int parameterIndex, boolean x) throws SQLException 281 { 282 String methodCall = "setBoolean(" + parameterIndex + ", " + x + ")"; 283 argTraceSet(parameterIndex, "(boolean)", Boolean.toString(x)); 284 try 285 { 286 realPreparedStatement.setBoolean(parameterIndex, x); 287 } 288 catch (SQLException s) 289 { 290 reportException(methodCall, s); 291 throw s; 292 } 293 reportReturn(methodCall); 294 } 295 296 public void setBlob(int i, Blob x) throws SQLException 297 { 298 String methodCall = "setBlob(" + i + ", " + x + ")"; 299 argTraceSet(i, "(Blob)", "<Blob of size " + x.length() + ">"); 300 try 301 { 302 realPreparedStatement.setBlob(i, x); 303 } 304 catch (SQLException s) 305 { 306 reportException(methodCall, s); 307 throw s; 308 } 309 reportReturn(methodCall); 310 } 311 312 public void setClob(int i, Clob x) throws SQLException 313 { 314 String methodCall = "setClob(" + i + ", " + x + ")"; 315 argTraceSet(i, "(Clob)", "<Clob of size " + x.length() + ">"); 316 try 317 { 318 realPreparedStatement.setClob(i, x); 319 } 320 catch (SQLException s) 321 { 322 reportException(methodCall, s); 323 throw s; 324 } 325 reportReturn(methodCall); 326 } 327 328 public void setArray(int i, Array x) throws SQLException 329 { 330 String methodCall = "setArray(" + i + ", " + x + ")"; 331 argTraceSet(i, "(Array)", "<Array>"); 332 try 333 { 334 realPreparedStatement.setArray(i, x); 335 } 336 catch (SQLException s) 337 { 338 reportException(methodCall, s); 339 throw s; 340 } 341 reportReturn(methodCall); 342 } 343 344 public void setByte(int parameterIndex, byte x) throws SQLException 345 { 346 String methodCall = "setByte(" + parameterIndex + ", " + x + ")"; 347 argTraceSet(parameterIndex, "(byte)", Byte.toString(x)); 348 try 349 { 350 realPreparedStatement.setByte(parameterIndex, x); 351 } 352 catch (SQLException s) 353 { 354 reportException(methodCall, s); 355 throw s; 356 } 357 reportReturn(methodCall); 358 } 359 360 /** 361 * @deprecated 362 */ 363 public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException 364 { 365 String methodCall = "setUnicodeStream(" + parameterIndex + ", " + x + ", " + length + ")"; 366 argTraceSet(parameterIndex, "(Unicode InputStream)", "<Unicode InputStream of length " + length + ">"); 367 try 368 { 369 realPreparedStatement.setUnicodeStream(parameterIndex, x, length); 370 } 371 catch (SQLException s) 372 { 373 reportException(methodCall, s); 374 throw s; 375 } 376 reportReturn(methodCall); 377 } 378 379 public void setShort(int parameterIndex, short x) throws SQLException 380 { 381 String methodCall = "setShort(" + parameterIndex + ", " + x + ")"; 382 argTraceSet(parameterIndex, "(short)", Short.toString(x)); 383 try 384 { 385 realPreparedStatement.setShort(parameterIndex, x); 386 } 387 catch (SQLException s) 388 { 389 reportException(methodCall, s); 390 throw s; 391 } 392 reportReturn(methodCall); 393 } 394 395 public boolean execute() throws SQLException 396 { 397 String methodCall = "execute()"; 398 String dumpedSql = dumpedSql(); 399 reportSql(dumpedSql, methodCall); 400 long tstart = System.currentTimeMillis(); 401 try 402 { 403 boolean result = realPreparedStatement.execute(); 404 reportSqlTiming(System.currentTimeMillis() - tstart, dumpedSql, methodCall); 405 return reportReturn(methodCall, result); 406 } 407 catch (SQLException s) 408 { 409 reportException(methodCall, s, dumpedSql, System.currentTimeMillis() - tstart); 410 throw s; 411 } 412 } 413 414 public void setInt(int parameterIndex, int x) throws SQLException 415 { 416 String methodCall = "setInt(" + parameterIndex + ", " + x + ")"; 417 argTraceSet(parameterIndex, "(int)", Integer.toString(x)); 418 try 419 { 420 realPreparedStatement.setInt(parameterIndex, x); 421 } 422 catch (SQLException s) 423 { 424 reportException(methodCall, s); 425 throw s; 426 } 427 reportReturn(methodCall); 428 } 429 430 public void setLong(int parameterIndex, long x) throws SQLException 431 { 432 String methodCall = "setLong(" + parameterIndex + ", " + x + ")"; 433 argTraceSet(parameterIndex, "(long)", Long.toString(x)); 434 try 435 { 436 realPreparedStatement.setLong(parameterIndex, x); 437 } 438 catch (SQLException s) 439 { 440 reportException(methodCall, s); 441 throw s; 442 } 443 reportReturn(methodCall); 444 } 445 446 public void setFloat(int parameterIndex, float x) throws SQLException 447 { 448 String methodCall = "setFloat(" + parameterIndex + ", " + x + ")"; 449 argTraceSet(parameterIndex, "(float)", Float.toString(x)); 450 try 451 { 452 realPreparedStatement.setFloat(parameterIndex, x); 453 } 454 catch (SQLException s) 455 { 456 reportException(methodCall, s); 457 throw s; 458 } 459 reportReturn(methodCall); 460 } 461 462 public void setDouble(int parameterIndex, double x) throws SQLException 463 { 464 String methodCall = "setDouble(" + parameterIndex + ", " + x + ")"; 465 argTraceSet(parameterIndex, "(double)", Double.toString(x)); 466 try 467 { 468 realPreparedStatement.setDouble(parameterIndex, x); 469 } 470 catch (SQLException s) 471 { 472 reportException(methodCall, s); 473 throw s; 474 } 475 reportReturn(methodCall); 476 } 477 478 public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException 479 { 480 String methodCall = "setBigDecimal(" + parameterIndex + ", " + x + ")"; 481 argTraceSet(parameterIndex, "(BigDecimal)", x); 482 try 483 { 484 realPreparedStatement.setBigDecimal(parameterIndex, x); 485 } 486 catch (SQLException s) 487 { 488 reportException(methodCall, s); 489 throw s; 490 } 491 reportReturn(methodCall); 492 } 493 494 public void setURL(int parameterIndex, URL x) throws SQLException 495 { 496 String methodCall = "setURL(" + parameterIndex + ", " + x + ")"; 497 argTraceSet(parameterIndex, "(URL)", x); 498 499 try 500 { 501 realPreparedStatement.setURL(parameterIndex, x); 502 } 503 catch (SQLException s) 504 { 505 reportException(methodCall, s); 506 throw s; 507 } 508 reportReturn(methodCall); 509 } 510 511 public void setString(int parameterIndex, String x) throws SQLException 512 { 513 String methodCall = "setString(" + parameterIndex + ", \"" + x + "\")"; 514 argTraceSet(parameterIndex, "(String)", rdbmsSpecifics.formatParameterObject(x)); 515 try 516 { 517 realPreparedStatement.setString(parameterIndex, x); 518 } 519 catch (SQLException s) 520 { 521 reportException(methodCall, s); 522 throw s; 523 } 524 reportReturn(methodCall); 525 } 526 527 public void setBytes(int parameterIndex, byte[] x) throws SQLException 528 { 529 //todo: dump array? 530 String methodCall = "setBytes(" + parameterIndex + ", " + x + ")"; 531 argTraceSet(parameterIndex, "(byte[])", "<byte[]>"); 532 try 533 { 534 realPreparedStatement.setBytes(parameterIndex, x); 535 } 536 catch (SQLException s) 537 { 538 reportException(methodCall, s); 539 throw s; 540 } 541 reportReturn(methodCall); 542 } 543 544 public void setDate(int parameterIndex, Date x) throws SQLException 545 { 546 String methodCall = "setDate(" + parameterIndex + ", " + x + ")"; 547 argTraceSet(parameterIndex, "(Date)", rdbmsSpecifics.formatParameterObject(x)); 548 try 549 { 550 realPreparedStatement.setDate(parameterIndex, x); 551 } 552 catch (SQLException s) 553 { 554 reportException(methodCall, s); 555 throw s; 556 } 557 reportReturn(methodCall); 558 } 559 560 public ParameterMetaData getParameterMetaData() throws SQLException 561 { 562 String methodCall = "getParameterMetaData()"; 563 try 564 { 565 return (ParameterMetaData) reportReturn(methodCall, realPreparedStatement.getParameterMetaData()); 566 } 567 catch (SQLException s) 568 { 569 reportException(methodCall, s); 570 throw s; 571 } 572 } 573 574 public void setRowId(int parameterIndex, RowId x) throws SQLException { 575 String methodCall = "setRowId(" + parameterIndex + ", " + x + ")"; 576 argTraceSet(parameterIndex, "(RowId)", rdbmsSpecifics.formatParameterObject(x)); 577 try 578 { 579 realPreparedStatement.setRowId(parameterIndex, x); 580 } 581 catch (SQLException s) 582 { 583 reportException(methodCall, s); 584 throw s; 585 } 586 reportReturn(methodCall); 587 } 588 589 public void setNString(int parameterIndex, String value) throws SQLException { 590 String methodCall = "setNString(" + parameterIndex + ", " + value + ")"; 591 argTraceSet(parameterIndex, "(String)", rdbmsSpecifics.formatParameterObject(value)); 592 try 593 { 594 realPreparedStatement.setNString(parameterIndex, value); 595 } 596 catch (SQLException s) 597 { 598 reportException(methodCall, s); 599 throw s; 600 } 601 reportReturn(methodCall); 602 } 603 604 public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { 605 String methodCall = "setNCharacterStream(" + parameterIndex + ", " + value + ", " + length + ")"; 606 argTraceSet(parameterIndex, "(Reader)", "<Reader of length " + length + ">"); 607 try 608 { 609 realPreparedStatement.setNCharacterStream(parameterIndex, value, length); 610 } 611 catch (SQLException s) 612 { 613 reportException(methodCall, s); 614 throw s; 615 } 616 reportReturn(methodCall); 617 } 618 619 public void setNClob(int parameterIndex, NClob value) throws SQLException { 620 String methodCall = "setNClob(" + parameterIndex + ", " + value + ")"; 621 argTraceSet(parameterIndex, "(NClob)", "<NClob>"); 622 try 623 { 624 realPreparedStatement.setNClob(parameterIndex, value); 625 } 626 catch (SQLException s) 627 { 628 reportException(methodCall, s); 629 throw s; 630 } 631 reportReturn(methodCall); 632 } 633 634 public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { 635 String methodCall = "setClob(" + parameterIndex + ", " + reader + ", " + length + ")"; 636 argTraceSet(parameterIndex, "(Reader)", "<Reader of length " + length + ">"); 637 try 638 { 639 realPreparedStatement.setClob(parameterIndex, reader, length); 640 } 641 catch (SQLException s) 642 { 643 reportException(methodCall, s); 644 throw s; 645 } 646 reportReturn(methodCall); 647 } 648 649 public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { 650 String methodCall = "setBlob(" + parameterIndex + ", " + inputStream + ", " + length + ")"; 651 argTraceSet(parameterIndex, "(InputStream)", "<InputStream of length " + length + ">"); 652 try 653 { 654 realPreparedStatement.setBlob(parameterIndex, inputStream, length); 655 } 656 catch (SQLException s) 657 { 658 reportException(methodCall, s); 659 throw s; 660 } 661 reportReturn(methodCall); 662 } 663 664 public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { 665 String methodCall = "setNClob(" + parameterIndex + ", " + reader + ", " + length + ")"; 666 argTraceSet(parameterIndex, "(Reader)", "<Reader of length " + length + ">"); 667 try 668 { 669 realPreparedStatement.setNClob(parameterIndex, reader, length); 670 } 671 catch (SQLException s) 672 { 673 reportException(methodCall, s); 674 throw s; 675 } 676 reportReturn(methodCall); 677 } 678 679 public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { 680 String methodCall = "setSQLXML(" + parameterIndex + ", " + xmlObject + ")"; 681 argTraceSet(parameterIndex, "(SQLXML)", rdbmsSpecifics.formatParameterObject(xmlObject)); 682 try 683 { 684 realPreparedStatement.setSQLXML(parameterIndex, xmlObject); 685 } 686 catch (SQLException s) 687 { 688 reportException(methodCall, s); 689 throw s; 690 } 691 reportReturn(methodCall); 692 } 693 694 public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException 695 { 696 String methodCall = "setDate(" + parameterIndex + ", " + x + ", " + cal + ")"; 697 argTraceSet(parameterIndex, "(Date)", rdbmsSpecifics.formatParameterObject(x)); 698 699 try 700 { 701 realPreparedStatement.setDate(parameterIndex, x, cal); 702 } 703 catch (SQLException s) 704 { 705 reportException(methodCall, s); 706 throw s; 707 } 708 reportReturn(methodCall); 709 } 710 711 public ResultSet executeQuery() throws SQLException 712 { 713 String methodCall = "executeQuery()"; 714 String dumpedSql = dumpedSql(); 715 reportSql(dumpedSql, methodCall); 716 long tstart = System.currentTimeMillis(); 717 try 718 { 719 ResultSet r = realPreparedStatement.executeQuery(); 720 reportSqlTiming(System.currentTimeMillis() - tstart, dumpedSql, methodCall); 721 ResultSetSpy rsp = new ResultSetSpy(this, r); 722 return (ResultSet) reportReturn(methodCall, rsp); 723 } 724 catch (SQLException s) 725 { 726 reportException(methodCall, s, dumpedSql, System.currentTimeMillis() - tstart); 727 throw s; 728 } 729 } 730 731 private String getTypeHelp(Object x) 732 { 733 if (x==null) 734 { 735 return "(null)"; 736 } 737 else 738 { 739 return "(" + x.getClass().getName() + ")"; 740 } 741 } 742 743 public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException 744 { 745 String methodCall = "setObject(" + parameterIndex + ", " + x + ", " + targetSqlType + ", " + scale + ")"; 746 argTraceSet(parameterIndex, getTypeHelp(x), rdbmsSpecifics.formatParameterObject(x)); 747 748 try 749 { 750 realPreparedStatement.setObject(parameterIndex, x, targetSqlType, scale); 751 } 752 catch (SQLException s) 753 { 754 reportException(methodCall, s); 755 throw s; 756 } 757 reportReturn(methodCall); 758 } 759 760 /** 761 * Sets the designated parameter to the given input stream, which will have 762 * the specified number of bytes. 763 * When a very large ASCII value is input to a <code>LONGVARCHAR</code> 764 * parameter, it may be more practical to send it via a 765 * <code>java.io.InputStream</code>. Data will be read from the stream 766 * as needed until end-of-file is reached. The JDBC driver will 767 * do any necessary conversion from ASCII to the database char format. 768 * <p/> 769 * <P><B>Note:</B> This stream object can either be a standard 770 * Java stream object or your own subclass that implements the 771 * standard interface. 772 * 773 * @param parameterIndex the first parameter is 1, the second is 2, ... 774 * @param x the Java input stream that contains the ASCII parameter value 775 * @param length the number of bytes in the stream 776 * @throws java.sql.SQLException if parameterIndex does not correspond to a parameter 777 * marker in the SQL statement; if a database access error occurs or 778 * this method is called on a closed <code>PreparedStatement</code> 779 * @since 1.6 780 */ 781 public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { 782 String methodCall = "setAsciiStream(" + parameterIndex + ", " + x + ", " + length + ")"; 783 argTraceSet(parameterIndex, "(Ascii InputStream)", "<Ascii InputStream of length " + length + ">"); 784 try 785 { 786 realPreparedStatement.setAsciiStream(parameterIndex, x, length); 787 } 788 catch (SQLException s) 789 { 790 reportException(methodCall, s); 791 throw s; 792 } 793 reportReturn(methodCall); 794 } 795 796 public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { 797 String methodCall = "setBinaryStream(" + parameterIndex + ", " + x + ", " + length + ")"; 798 argTraceSet(parameterIndex, "(Binary InputStream)", "<Binary InputStream of length " + length + ">"); 799 try 800 { 801 realPreparedStatement.setBinaryStream(parameterIndex, x, length); 802 } 803 catch (SQLException s) 804 { 805 reportException(methodCall, s); 806 throw s; 807 } 808 reportReturn(methodCall); 809 } 810 811 public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { 812 String methodCall = "setCharacterStream(" + parameterIndex + ", " + reader + ", " + length + ")"; 813 argTraceSet(parameterIndex, "(Reader)", "<Reader of length " + length + ">"); 814 try 815 { 816 realPreparedStatement.setCharacterStream(parameterIndex, reader, length); 817 } 818 catch (SQLException s) 819 { 820 reportException(methodCall, s); 821 throw s; 822 } 823 reportReturn(methodCall); 824 825 } 826 827 public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { 828 String methodCall = "setAsciiStream(" + parameterIndex + ", " + x + ")"; 829 argTraceSet(parameterIndex, "(Ascii InputStream)", "<Ascii InputStream>"); 830 try 831 { 832 realPreparedStatement.setAsciiStream(parameterIndex, x); 833 } 834 catch (SQLException s) 835 { 836 reportException(methodCall, s); 837 throw s; 838 } 839 reportReturn(methodCall); 840 } 841 842 public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { 843 String methodCall = "setBinaryStream(" + parameterIndex + ", " + x + ")"; 844 argTraceSet(parameterIndex, "(Binary InputStream)", "<Binary InputStream>"); 845 try 846 { 847 realPreparedStatement.setBinaryStream(parameterIndex, x); 848 } 849 catch (SQLException s) 850 { 851 reportException(methodCall, s); 852 throw s; 853 } 854 reportReturn(methodCall); 855 856 } 857 858 public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { 859 String methodCall = "setCharacterStream(" + parameterIndex + ", " + reader + ")"; 860 argTraceSet(parameterIndex, "(Reader)", "<Reader>"); 861 try 862 { 863 realPreparedStatement.setCharacterStream(parameterIndex, reader); 864 } 865 catch (SQLException s) 866 { 867 reportException(methodCall, s); 868 throw s; 869 } 870 reportReturn(methodCall); 871 } 872 873 public void setNCharacterStream(int parameterIndex, Reader reader) throws SQLException { 874 String methodCall = "setNCharacterStream(" + parameterIndex + ", " + reader + ")"; 875 argTraceSet(parameterIndex, "(Reader)", "<Reader>"); 876 try 877 { 878 realPreparedStatement.setNCharacterStream(parameterIndex, reader); 879 } 880 catch (SQLException s) 881 { 882 reportException(methodCall, s); 883 throw s; 884 } 885 reportReturn(methodCall); 886 } 887 888 public void setClob(int parameterIndex, Reader reader) throws SQLException { 889 String methodCall = "setClob(" + parameterIndex + ", " + reader + ")"; 890 argTraceSet(parameterIndex, "(Reader)", "<Reader>"); 891 try 892 { 893 realPreparedStatement.setClob(parameterIndex, reader); 894 } 895 catch (SQLException s) 896 { 897 reportException(methodCall, s); 898 throw s; 899 } 900 reportReturn(methodCall); 901 } 902 903 public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { 904 String methodCall = "setBlob(" + parameterIndex + ", " + inputStream + ")"; 905 argTraceSet(parameterIndex, "(InputStream)", "<InputStream>"); 906 try 907 { 908 realPreparedStatement.setBlob(parameterIndex, inputStream); 909 } 910 catch (SQLException s) 911 { 912 reportException(methodCall, s); 913 throw s; 914 } 915 reportReturn(methodCall); 916 } 917 918 public void setNClob(int parameterIndex, Reader reader) throws SQLException { 919 String methodCall = "setNClob(" + parameterIndex + ", " + reader + ")"; 920 argTraceSet(parameterIndex, "(Reader)", "<Reader>"); 921 try 922 { 923 realPreparedStatement.setNClob(parameterIndex, reader); 924 } 925 catch (SQLException s) 926 { 927 reportException(methodCall, s); 928 throw s; 929 } 930 reportReturn(methodCall); 931 932 } 933 934 public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException 935 { 936 String methodCall = "setObject(" + parameterIndex + ", " + x + ", " + targetSqlType + ")"; 937 argTraceSet(parameterIndex, getTypeHelp(x), rdbmsSpecifics.formatParameterObject(x)); 938 try 939 { 940 realPreparedStatement.setObject(parameterIndex, x, targetSqlType); 941 } 942 catch (SQLException s) 943 { 944 reportException(methodCall, s); 945 throw s; 946 } 947 reportReturn(methodCall); 948 } 949 950 public void setObject(int parameterIndex, Object x) throws SQLException 951 { 952 String methodCall = "setObject(" + parameterIndex + ", " + x + ")"; 953 argTraceSet(parameterIndex, getTypeHelp(x), rdbmsSpecifics.formatParameterObject(x)); 954 try 955 { 956 realPreparedStatement.setObject(parameterIndex, x); 957 } 958 catch (SQLException s) 959 { 960 reportException(methodCall, s); 961 throw s; 962 } 963 reportReturn(methodCall); 964 } 965 966 public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException 967 { 968 String methodCall = "setTimestamp(" + parameterIndex + ", " + x + ")"; 969 argTraceSet(parameterIndex, "(Date)", rdbmsSpecifics.formatParameterObject(x)); 970 try 971 { 972 realPreparedStatement.setTimestamp(parameterIndex, x); 973 } 974 catch (SQLException s) 975 { 976 reportException(methodCall, s); 977 throw s; 978 } 979 reportReturn(methodCall); 980 } 981 982 public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException 983 { 984 String methodCall = "setTimestamp(" + parameterIndex + ", " + x + ", " + cal + ")"; 985 argTraceSet(parameterIndex, "(Timestamp)", rdbmsSpecifics.formatParameterObject(x)); 986 try 987 { 988 realPreparedStatement.setTimestamp(parameterIndex, x, cal); 989 } 990 catch (SQLException s) 991 { 992 reportException(methodCall, s); 993 throw s; 994 } 995 reportReturn(methodCall); 996 } 997 998 public int executeUpdate() throws SQLException 999 { 1000 String methodCall = "executeUpdate()"; 1001 String dumpedSql = dumpedSql(); 1002 reportSql(dumpedSql, methodCall); 1003 long tstart = System.currentTimeMillis(); 1004 try 1005 { 1006 int result = realPreparedStatement.executeUpdate(); 1007 reportSqlTiming(System.currentTimeMillis() - tstart, dumpedSql, methodCall); 1008 return reportReturn(methodCall, result); 1009 } 1010 catch (SQLException s) 1011 { 1012 reportException(methodCall, s, dumpedSql, System.currentTimeMillis() - tstart); 1013 throw s; 1014 } 1015 } 1016 1017 public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException 1018 { 1019 String methodCall = "setAsciiStream(" + parameterIndex + ", " + x + ", " + length + ")"; 1020 argTraceSet(parameterIndex, "(Ascii InputStream)", "<Ascii InputStream of length " + length + ">"); 1021 try 1022 { 1023 realPreparedStatement.setAsciiStream(parameterIndex, x, length); 1024 } 1025 catch (SQLException s) 1026 { 1027 reportException(methodCall, s); 1028 throw s; 1029 } 1030 reportReturn(methodCall); 1031 } 1032 1033 public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException 1034 { 1035 String methodCall = "setBinaryStream(" + parameterIndex + ", " + x + ", " + length + ")"; 1036 argTraceSet(parameterIndex, "(Binary InputStream)", "<Binary InputStream of length " + length + ">"); 1037 try 1038 { 1039 realPreparedStatement.setBinaryStream(parameterIndex, x, length); 1040 } 1041 catch (SQLException s) 1042 { 1043 reportException(methodCall, s); 1044 throw s; 1045 } 1046 reportReturn(methodCall); 1047 } 1048 1049 public void clearParameters() throws SQLException 1050 { 1051 String methodCall = "clearParameters()"; 1052 1053 synchronized (argTrace) 1054 { 1055 argTrace.clear(); 1056 } 1057 1058 try 1059 { 1060 realPreparedStatement.clearParameters(); 1061 } 1062 catch (SQLException s) 1063 { 1064 reportException(methodCall, s); 1065 throw s; 1066 } 1067 reportReturn(methodCall); 1068 } 1069 1070 public ResultSetMetaData getMetaData() throws SQLException 1071 { 1072 String methodCall = "getMetaData()"; 1073 try 1074 { 1075 return (ResultSetMetaData) reportReturn(methodCall, realPreparedStatement.getMetaData()); 1076 } 1077 catch (SQLException s) 1078 { 1079 reportException(methodCall, s); 1080 throw s; 1081 } 1082 } 1083 1084 public void addBatch() throws SQLException 1085 { 1086 String methodCall = "addBatch()"; 1087 currentBatch.add(dumpedSql()); 1088 try 1089 { 1090 realPreparedStatement.addBatch(); 1091 } 1092 catch (SQLException s) 1093 { 1094 reportException(methodCall, s); 1095 throw s; 1096 } 1097 reportReturn(methodCall); 1098 } 1099 1100 public <T> T unwrap(Class<T> iface) throws SQLException { 1101 String methodCall = "unwrap(" + (iface==null?"null":iface.getName()) + ")"; 1102 try 1103 { 1104 //todo: double check this logic 1105 //NOTE: could call super.isWrapperFor to simplify this logic, but it would result in extra log output 1106 //because the super classes would be invoked, thus executing their logging methods too... 1107 return (T)reportReturn(methodCall, 1108 (iface != null && (iface==PreparedStatement.class||iface==Statement.class||iface==Spy.class))? 1109 (T)this: 1110 realPreparedStatement.unwrap(iface)); 1111 } 1112 catch (SQLException s) 1113 { 1114 reportException(methodCall,s); 1115 throw s; 1116 } 1117 } 1118 1119 public boolean isWrapperFor(Class<?> iface) throws SQLException 1120 { 1121 String methodCall = "isWrapperFor(" + (iface==null?"null":iface.getName()) + ")"; 1122 try 1123 { 1124 //NOTE: could call super.isWrapperFor to simplify this logic, but it would result in extra log output 1125 //when the super classes would be invoked.. 1126 return reportReturn(methodCall, 1127 (iface != null && (iface==PreparedStatement.class||iface==Statement.class||iface==Spy.class)) || 1128 realPreparedStatement.isWrapperFor(iface)); 1129 } 1130 catch (SQLException s) 1131 { 1132 reportException(methodCall,s); 1133 throw s; 1134 } 1135 } 1136 1137 }