All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.log4jdbc.StatementSpy Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2007-2010 Arthur Blake
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.sf.log4jdbc;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.List;
import java.util.ArrayList;

/**
 * Wraps a Statement and reports method calls, returns and exceptions.
 *
 * jdbc 4 version
 *
 * @author Arthur Blake
 * @author Tim Azzopardi changes to support result set logging and custom sql formatting
 */
public class StatementSpy implements Statement, Spy
{
  protected final SpyLogDelegator log;

  /**
   * The Connection that created this Statement.
   */
  protected ConnectionSpy connectionSpy;

  /**
   * The real statement that this StatementSpy wraps.
   */
  protected Statement realStatement;

  /**
   * Get the real Statement that this StatementSpy wraps.
   *
   * @return the real Statement that this StatementSpy wraps.
   */
  public Statement getRealStatement()
  {
    return realStatement;
  }

  /**
   * Create a StatementSpy that wraps another Statement
   * for the purpose of logging all method calls, sql, exceptions and return values.
   *
   * @param connectionSpy Connection that created this Statement.
   * @param realStatement real underlying Statement that this StatementSpy wraps.
   */
  public StatementSpy(ConnectionSpy connectionSpy, Statement realStatement)
  {
    if (realStatement == null)
    {
      throw new IllegalArgumentException("Must pass in a non null real Statement");
    }
    if (connectionSpy == null)
    {
      throw new IllegalArgumentException("Must pass in a non null ConnectionSpy");
    }
    this.realStatement = realStatement;
    this.connectionSpy = connectionSpy;

    log = SpyLogFactory.getSpyLogDelegator();

    if (realStatement instanceof CallableStatement)
    {
      reportReturn("new CallableStatement");
    }
    else if (realStatement instanceof PreparedStatement)
    {
      reportReturn("new PreparedStatement");
    }
    else
    {
      reportReturn("new Statement");
    }
  }

  public String getClassType()
  {
    return "Statement";
  }

  public Integer getConnectionNumber()
  {
    return connectionSpy.getConnectionNumber();
  }

  /**
   * Report an exception to be logged which includes timing data on a sql failure.
   * @param methodCall description of method call and arguments passed to it that generated the exception.
   * @param exception exception that was generated
   * @param sql SQL associated with the call.
   * @param execTime amount of time that the jdbc driver was chugging on the SQL before it threw an exception.
   */
  protected void reportException(String methodCall, SQLException exception, String sql, long execTime)
  {
    log.exceptionOccured(this, methodCall, exception, sql, execTime);
  }

  /**
   * Report an exception to be logged.
   * @param methodCall description of method call and arguments passed to it that generated the exception.
   * @param exception exception that was generated
   * @param sql SQL associated with the call.
   */
  protected void reportException(String methodCall, SQLException exception, String sql)
  {
    log.exceptionOccured(this, methodCall, exception, sql, -1L);
  }

  /**
   * Report an exception to be logged.
   *
   * @param methodCall description of method call and arguments passed to it that generated the exception.
   * @param exception exception that was generated
   */
  protected void reportException(String methodCall, SQLException exception)
  {
    log.exceptionOccured(this, methodCall, exception, null, -1L);
  }

  /**
   * Report (for logging) that a method returned.  All the other reportReturn methods are conveniance methods that call this method.
   *
   * @param methodCall description of method call and arguments passed to it that returned.
   * @param msg description of what the return value that was returned.  may be an empty String for void return types.
   */
  protected void reportAllReturns(String methodCall, String msg)
  {
    log.methodReturned(this, methodCall, msg, getRealStatement(), (Object[])null);
  }

  /**
   * Conveniance method to report (for logging) that a method returned a boolean value.
   *
   * @param methodCall description of method call and arguments passed to it that returned.
   * @param value boolean return value.
   * @return the boolean return value as passed in.
   */
  protected boolean reportReturn(String methodCall, boolean value)
  {
    reportAllReturns(methodCall, "" + value);
    return value;
  }

  /**
   * Conveniance method to report (for logging) that a method returned a byte value.
   *
   * @param methodCall description of method call and arguments passed to it that returned.
   * @param value byte return value.
   * @return the byte return value as passed in.
   */
  protected byte reportReturn(String methodCall, byte value)
  {
    reportAllReturns(methodCall, "" + value);
    return value;
  }

  /**
   * Conveniance method to report (for logging) that a method returned a int value.
   *
   * @param methodCall description of method call and arguments passed to it that returned.
   * @param value int return value.
   * @return the int return value as passed in.
   */
  protected int reportReturn(String methodCall, int value)
  {
    reportAllReturns(methodCall, "" + value);
    return value;
  }

  /**
   * Conveniance method to report (for logging) that a method returned a double value.
   *
   * @param methodCall description of method call and arguments passed to it that returned.
   * @param value double return value.
   * @return the double return value as passed in.
   */
  protected double reportReturn(String methodCall, double value)
  {
    reportAllReturns(methodCall, "" + value);
    return value;
  }

  /**
   * Conveniance method to report (for logging) that a method returned a short value.
   *
   * @param methodCall description of method call and arguments passed to it that returned.
   * @param value short return value.
   * @return the short return value as passed in.
   */
  protected short reportReturn(String methodCall, short value)
  {
    reportAllReturns(methodCall, "" + value);
    return value;
  }

  /**
   * Conveniance method to report (for logging) that a method returned a long value.
   *
   * @param methodCall description of method call and arguments passed to it that returned.
   * @param value long return value.
   * @return the long return value as passed in.
   */
  protected long reportReturn(String methodCall, long value)
  {
    reportAllReturns(methodCall, "" + value);
    return value;
  }

  /**
   * Conveniance method to report (for logging) that a method returned a float value.
   *
   * @param methodCall description of method call and arguments passed to it that returned.
   * @param value float return value.
   * @return the float return value as passed in.
   */
  protected float reportReturn(String methodCall, float value)
  {
    reportAllReturns(methodCall, "" + value);
    return value;
  }

  /**
   * Conveniance method to report (for logging) that a method returned an Object.
   *
   * @param methodCall description of method call and arguments passed to it that returned.
   * @param value return Object.
   * @return the return Object as passed in.
   */
  protected Object reportReturn(String methodCall, Object value)
  {
    reportAllReturns(methodCall, "" + value);
    return value;
  }

  /**
   * Conveniance method to report (for logging) that a method returned (void return type).
   *
   * @param methodCall description of method call and arguments passed to it that returned.
   */
  protected void reportReturn(String methodCall)
  {
    reportAllReturns(methodCall, "");
  }

  /**
   * Running one-off statement sql is generally inefficient and a bad idea for various reasons,
   * so give a warning when this is done.
   */
  private static final String StatementSqlWarning = "{WARNING: Statement used to run SQL} ";

  /**
   * Report SQL for logging with a warning that it was generated from a statement.
   *
   * @param sql        the SQL being run
   * @param methodCall the name of the method that was running the SQL
   */
  protected void reportStatementSql(String sql, String methodCall)
  {
    // redirect to one more method call ONLY so that stack trace search is consistent
    // with the reportReturn calls
    _reportSql((DriverSpy.StatementUsageWarn?StatementSqlWarning:"") +
      sql, methodCall);
  }

  /**
   * Report SQL for logging with a warning that it was generated from a statement.
   *
   * @param execTime   execution time in msec.
   * @param sql        the SQL being run
   * @param methodCall the name of the method that was running the SQL
   */
  protected void reportStatementSqlTiming(long execTime, String sql, String methodCall)
  {
    // redirect to one more method call ONLY so that stack trace search is consistent
    // with the reportReturn calls
    _reportSqlTiming(execTime, (DriverSpy.StatementUsageWarn?StatementSqlWarning:"") +
      sql, methodCall);
  }

  /**
   * Report SQL for logging.
   *
   * @param execTime   execution time in msec.
   * @param sql        the SQL being run
   * @param methodCall the name of the method that was running the SQL
   */
  protected void reportSqlTiming(long execTime, String sql, String methodCall)
  {
    // redirect to one more method call ONLY so that stack trace search is consistent
    // with the reportReturn calls
    _reportSqlTiming(execTime, sql, methodCall);
  }

  /**
   * Report SQL for logging.
   *
   * @param sql        the SQL being run
   * @param methodCall the name of the method that was running the SQL
   */
  protected void reportSql(String sql, String methodCall)
  {
    // redirect to one more method call ONLY so that stack trace search is consistent
    // with the reportReturn calls
    _reportSql(sql, methodCall);
  }

  private void _reportSql(String sql, String methodCall)
  {
    log.sqlOccured(this, methodCall, sql);
  }
  
  /**
   * Report SQL batch for logging.
   *
   * @param sqls       the SQL being run
   * @param methodCall the name of the method that was running the SQL
    * @return string representation of batch
   */
  private String reportSqlBatch(String[] sqls, String methodCall) {
      return log.sqlOccured(this, methodCall, sqls);
  }

  private void _reportSqlTiming(long execTime, String sql, String methodCall)
  {
    log.sqlTimingOccured(this, execTime, methodCall, sql);
  }

  // implementation of interface methods
  public SQLWarning getWarnings() throws SQLException
  {
    String methodCall = "getWarnings()";
    try
    {
      return (SQLWarning) reportReturn(methodCall, realStatement.getWarnings());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public int executeUpdate(String sql, String[] columnNames) throws SQLException
  {
    String methodCall = "executeUpdate(" + sql + ", " + columnNames + ")";
    reportStatementSql(sql, methodCall);
    long tstart = System.currentTimeMillis();
    try
    {
      int result = realStatement.executeUpdate(sql, columnNames);
      reportStatementSqlTiming(System.currentTimeMillis() - tstart, sql, methodCall);
      return reportReturn(methodCall, result);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s, sql, System.currentTimeMillis() - tstart);
      throw s;
    }
  }

  public boolean execute(String sql, String[] columnNames) throws SQLException
  {
    String methodCall = "execute(" + sql + ", " + columnNames + ")";
    reportStatementSql(sql, methodCall);
    long tstart = System.currentTimeMillis();
    try
    {
      boolean result = realStatement.execute(sql, columnNames);
      reportStatementSqlTiming(System.currentTimeMillis() - tstart, sql, methodCall);
      return reportReturn(methodCall, result);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s, sql, System.currentTimeMillis() - tstart);
      throw s;
    }
  }

  public void setMaxRows(int max) throws SQLException
  {
    String methodCall = "setMaxRows(" + max + ")";
    try
    {
      realStatement.setMaxRows(max);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
    reportReturn(methodCall);
  }

  public boolean getMoreResults() throws SQLException
  {
    String methodCall = "getMoreResults()";

    try
    {
      return reportReturn(methodCall, realStatement.getMoreResults());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public void clearWarnings() throws SQLException
  {
    String methodCall = "clearWarnings()";
    try
    {
      realStatement.clearWarnings();
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
    reportReturn(methodCall);
  }

  /**
   * Tracking of current batch (see addBatch, clearBatch and executeBatch)
   * //todo: should access to this List be synchronized?
   */
  protected List currentBatch = new ArrayList();

  public void addBatch(String sql) throws SQLException
  {
    String methodCall = "addBatch(" + sql + ")";

    currentBatch.add(DriverSpy.StatementUsageWarn?StatementSqlWarning:"" + sql);
    try
    {
      realStatement.addBatch(sql);
    }
    catch (SQLException s)
    {
      reportException(methodCall,s);
      throw s;
    }
    reportReturn(methodCall);
  }

  public int getResultSetType() throws SQLException
  {
    String methodCall = "getResultSetType()";
    try
    {
      return reportReturn(methodCall, realStatement.getResultSetType());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public void clearBatch() throws SQLException
  {
    String methodCall = "clearBatch()";
    try
    {
      realStatement.clearBatch();
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
    currentBatch.clear();
    reportReturn(methodCall);
  }

  public void setFetchDirection(int direction) throws SQLException
  {
    String methodCall = "setFetchDirection(" + direction + ")";
    try
    {
      realStatement.setFetchDirection(direction);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
    reportReturn(methodCall);
  }

  public int[] executeBatch() throws SQLException
  {
    String methodCall = "executeBatch()";

    String sql = reportSqlBatch((String[])currentBatch.toArray(new String[0]), methodCall);
    
    long tstart = System.currentTimeMillis();

    int[] updateResults;
    try
    {
      updateResults = realStatement.executeBatch();
      reportSqlTiming(System.currentTimeMillis()-tstart, sql, methodCall);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s, sql, System.currentTimeMillis()-tstart);
      throw s;
    }
    currentBatch.clear();
    return (int[])reportReturn(methodCall,updateResults);
  }

  public void setFetchSize(int rows) throws SQLException
  {
    String methodCall = "setFetchSize(" + rows + ")";
    try
    {
      realStatement.setFetchSize(rows);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
    reportReturn(methodCall);
  }

  public int getQueryTimeout() throws SQLException
  {
    String methodCall = "getQueryTimeout()";
    try
    {
      return reportReturn(methodCall, realStatement.getQueryTimeout());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public Connection getConnection() throws SQLException
  {
    String methodCall = "getConnection()";
    return (Connection) reportReturn(methodCall, connectionSpy);
  }

  public ResultSet getGeneratedKeys() throws SQLException
  {
    String methodCall = "getGeneratedKeys()";
    try
    {
      ResultSet r = realStatement.getGeneratedKeys();
      if (r == null)
      {
        return (ResultSet) reportReturn(methodCall, r);
      }
      else
      {
        return (ResultSet) reportReturn(methodCall, new ResultSetSpy(this, r));
      }
    }
    catch (SQLException s)
    {
      if (!DriverSpy.SuppressGetGeneratedKeysException)
      {
        reportException(methodCall, s);
      }
      throw s;
    }
  }

  public void setEscapeProcessing(boolean enable) throws SQLException
  {
    String methodCall = "setEscapeProcessing(" + enable + ")";
    try
    {
      realStatement.setEscapeProcessing(enable);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
    reportReturn(methodCall);
  }

  public int getFetchDirection() throws SQLException
  {
    String methodCall = "getFetchDirection()";
    try
    {
      return reportReturn(methodCall, realStatement.getFetchDirection());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public void setQueryTimeout(int seconds) throws SQLException
  {
    String methodCall = "setQueryTimeout(" + seconds + ")";
    try
    {
      realStatement.setQueryTimeout(seconds);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
    reportReturn(methodCall);
  }

  public boolean getMoreResults(int current) throws SQLException
  {
    String methodCall = "getMoreResults(" + current + ")";

    try
    {
      return reportReturn(methodCall, realStatement.getMoreResults(current));
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public ResultSet executeQuery(String sql) throws SQLException
  {
    String methodCall = "executeQuery(" + sql + ")";
    reportStatementSql(sql, methodCall);
    long tstart = System.currentTimeMillis();
    try
    {
      ResultSet result = realStatement.executeQuery(sql);
      reportStatementSqlTiming(System.currentTimeMillis() - tstart, sql, methodCall);
      ResultSetSpy r = new ResultSetSpy(this, result);
      return (ResultSet) reportReturn(methodCall, r);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s, sql, System.currentTimeMillis() - tstart);
      throw s;
    }
  }

  public int getMaxFieldSize() throws SQLException
  {
    String methodCall = "getMaxFieldSize()";
    try
    {
      return reportReturn(methodCall, realStatement.getMaxFieldSize());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public int executeUpdate(String sql) throws SQLException
  {
    String methodCall = "executeUpdate(" + sql + ")";
    reportStatementSql(sql, methodCall);
    long tstart = System.currentTimeMillis();
    try
    {
      int result = realStatement.executeUpdate(sql);
      reportStatementSqlTiming(System.currentTimeMillis() - tstart, sql, methodCall);
      return reportReturn(methodCall, result);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s, sql, System.currentTimeMillis() - tstart);
      throw s;
    }
  }

  public void cancel() throws SQLException
  {
    String methodCall = "cancel()";
    try
    {
      realStatement.cancel();
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
    reportReturn(methodCall);
  }

  public void setCursorName(String name) throws SQLException
  {
    String methodCall = "setCursorName(" + name + ")";
    try
    {
      realStatement.setCursorName(name);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
    reportReturn(methodCall);
  }

  public int getFetchSize() throws SQLException
  {
    String methodCall = "getFetchSize()";
    try
    {
      return reportReturn(methodCall, realStatement.getFetchSize());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public int getResultSetConcurrency() throws SQLException
  {
    String methodCall = "getResultSetConcurrency()";
    try
    {
      return reportReturn(methodCall, realStatement.getResultSetConcurrency());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public int getResultSetHoldability() throws SQLException
  {
    String methodCall = "getResultSetHoldability()";
    try
    {
      return reportReturn(methodCall, realStatement.getResultSetHoldability());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public boolean isClosed() throws SQLException {
    String methodCall = "isClosed()";
    try
    {
      return reportReturn(methodCall, realStatement.isClosed());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public void setPoolable(boolean poolable) throws SQLException {
    String methodCall = "setPoolable(" + poolable + ")";
    try
    {
      realStatement.setPoolable(poolable);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
    reportReturn(methodCall);
  }

  public boolean isPoolable() throws SQLException {
    String methodCall = "isPoolable()";
    try
    {
      return reportReturn(methodCall, realStatement.isPoolable());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public void setMaxFieldSize(int max) throws SQLException
  {
    String methodCall = "setMaxFieldSize(" + max + ")";
    try
    {
      realStatement.setMaxFieldSize(max);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
    reportReturn(methodCall);
  }

  public boolean execute(String sql) throws SQLException
  {
    String methodCall = "execute(" + sql + ")";
    reportStatementSql(sql, methodCall);
    long tstart = System.currentTimeMillis();
    try
    {
      boolean result = realStatement.execute(sql);
      reportStatementSqlTiming(System.currentTimeMillis() - tstart, sql, methodCall);
      return reportReturn(methodCall, result);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s, sql, System.currentTimeMillis() - tstart);
      throw s;
    }
  }

  public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException
  {
    String methodCall = "executeUpdate(" + sql + ", " + autoGeneratedKeys + ")";
    reportStatementSql(sql, methodCall);
    long tstart = System.currentTimeMillis();
    try
    {
      int result = realStatement.executeUpdate(sql, autoGeneratedKeys);
      reportStatementSqlTiming(System.currentTimeMillis() - tstart, sql, methodCall);
      return reportReturn(methodCall, result);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s, sql, System.currentTimeMillis() - tstart);
      throw s;
    }
  }

  public boolean execute(String sql, int autoGeneratedKeys) throws SQLException
  {
    String methodCall = "execute(" + sql + ", " + autoGeneratedKeys + ")";
    reportStatementSql(sql, methodCall);
    long tstart = System.currentTimeMillis();
    try
    {
      boolean result = realStatement.execute(sql, autoGeneratedKeys);
      reportStatementSqlTiming(System.currentTimeMillis() - tstart, sql, methodCall);
      return reportReturn(methodCall, result);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s, sql, System.currentTimeMillis() - tstart);
      throw s;
    }
  }

  public int executeUpdate(String sql, int[] columnIndexes) throws SQLException
  {
    String methodCall = "executeUpdate(" + sql + ", " + columnIndexes + ")";
    reportStatementSql(sql, methodCall);
    long tstart = System.currentTimeMillis();
    try
    {
      int result = realStatement.executeUpdate(sql, columnIndexes);
      reportStatementSqlTiming(System.currentTimeMillis() - tstart, sql, methodCall);
      return reportReturn(methodCall, result);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s, sql, System.currentTimeMillis() - tstart);
      throw s;
    }
  }

  public boolean execute(String sql, int[] columnIndexes) throws SQLException
  {
    String methodCall = "execute(" + sql + ", " + columnIndexes + ")";
    reportStatementSql(sql, methodCall);
    long tstart = System.currentTimeMillis();
    try
    {
      boolean result = realStatement.execute(sql, columnIndexes);
      reportStatementSqlTiming(System.currentTimeMillis() - tstart, sql, methodCall);
      return reportReturn(methodCall, result);
    }
    catch (SQLException s)
    {
      reportException(methodCall, s, sql, System.currentTimeMillis() - tstart);
      throw s;
    }
  }

  public ResultSet getResultSet() throws SQLException
  {
    String methodCall = "getResultSet()";
    try
    {
      ResultSet r = realStatement.getResultSet();
      if (r == null)
      {
        return (ResultSet) reportReturn(methodCall, r);
      }
      else
      {
        return (ResultSet) reportReturn(methodCall, new ResultSetSpy(this, r));
      }
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public int getMaxRows() throws SQLException
  {
    String methodCall = "getMaxRows()";
    try
    {
      return reportReturn(methodCall, realStatement.getMaxRows());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public void close() throws SQLException
  {
    String methodCall = "close()";
    try
    {
      realStatement.close();
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
    reportReturn(methodCall);
  }

  public int getUpdateCount() throws SQLException
  {
    String methodCall = "getUpdateCount()";
    try
    {
      return reportReturn(methodCall, realStatement.getUpdateCount());
    }
    catch (SQLException s)
    {
      reportException(methodCall, s);
      throw s;
    }
  }

  public  T unwrap(Class iface) throws SQLException {
    String methodCall = "unwrap(" + (iface==null?"null":iface.getName()) + ")";
    try
    {
      //todo: double check this logic
      return (T)reportReturn(methodCall, (iface != null && (iface == Connection.class || iface == Spy.class))?(T)this:realStatement.unwrap(iface));
    }
    catch (SQLException s)
    {
      reportException(methodCall,s);
      throw s;
    }
  }

  public boolean isWrapperFor(Class iface) throws SQLException
  {
    String methodCall = "isWrapperFor(" + (iface==null?"null":iface.getName()) + ")";
    try
    {
      return reportReturn(methodCall, (iface != null && (iface == Statement.class || iface == Spy.class)) ||
          realStatement.isWrapperFor(iface));
    }
    catch (SQLException s)
    {
      reportException(methodCall,s);
      throw s;
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy