Package craftsman.spy

Source Code of craftsman.spy.SpyPreparedStatement

/*
* Craftsman Spy.
* Copyright (C) 2005  S�bastien LECACHEUR
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package craftsman.spy;

import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.Date;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;

/**
* The classe used to represent a precompiled SQL statement.
*
* @author S�bastien LECACHEUR
*/
public class SpyPreparedStatement extends SpyStatement implements PreparedStatement {
  /**
   * The real prepared statement instance.
   */
  private PreparedStatement real = null;


  /**
   * The current prepared SQL.
   */
  protected String preparedSql = null;


  /**
   * The list of all the parameters.
   */
  private ArrayList parameters = null;


  /**
   * Constructs a new Spy JDBC prepared statement.
   *
   * @param c Connection The used connection.
   * @param pstm PreparedStatement The real JDBC prepared statement.
   * @param sql String The prepared SQL.
   */
  protected SpyPreparedStatement ( Connection c, PreparedStatement pstm, String sql) {
    super ( c, pstm);
    real = pstm;
    preparedSql = sql;

    // Initializes capacity with the number of '?' in sql string
    parameters = new ArrayList(1);
    addParametersList();
  }


  /**
   * Retrieves the estimation of the number of parameters for
   * the prepared SQL.
   *
   * @return int The number of parameters.
   */
  protected int getEstimatedParametersCount() {
    int count = 0, index = 0;
    while ( (index = preparedSql.indexOf('?', index+1)) != -1) count++;

    return count;
  }


  /**
   * Adds a new parameters list for the next SQL or batch.
   */
  private void addParametersList() {
    // Adds a new parameters list for the next batch
    parameters.add(new ArrayList(getEstimatedParametersCount()+1));

    // Initializes the new parameters list
    ArrayList nextParameters = (ArrayList)parameters.get(parameters.size()-1);
    if ( nextParameters!=null) {
      for (int i = 0; i < getEstimatedParametersCount()+1; i++) nextParameters.add(i,null);
    } else {
      if ( log.isFatalEnabled()) log.fatal("the next parameters list is null (current size is "+parameters.size()+")");
    }
  }


  /**
   * Registers the given input parameter.
   *
   * @param paramIndex int The index position of the parameter.
   * @param parameter Object The value of the parameter.
   */
  private void registerInputParameter (int paramIndex, Object parameter) {
    // Check if the current parameters list is initialized
    if (parameters.size()==0 || parameters.get(parameters.size()-1)==null) {
      addParametersList();
    }

    ArrayList currentParameters = (ArrayList)parameters.get(parameters.size()-1);
    if ( currentParameters!=null) {
      if ( currentParameters.size()<=paramIndex) {
        currentParameters.ensureCapacity(paramIndex+1);
        for ( int i = currentParameters.size(); i < paramIndex; i++) currentParameters.add(i,null);
          currentParameters.add(paramIndex,parameter);
      } else {
        currentParameters.set(paramIndex,parameter);
      }
    } else {
      if ( log.isFatalEnabled()) log.fatal("the current parameters list is null (current size is "+parameters.size()+")");
    }
  }


  /**
   * Retrieves the string representation with parameters of
   * a prepared SQL.
   *
   * @param index int The index of the prepared SQL.
   * @return String The string representation with parameters
   * of the prepared SQL.
   */
  private String getDisplayableSql(int index) {
    StringBuffer displayableSql = new StringBuffer(preparedSql.length());


    if ( parameters!=null) {
      int i = 1, limit = 0, base = 0;
      while ((limit = preparedSql.indexOf('?',limit)) != -1) {
        displayableSql.append(preparedSql.substring(base,limit));
        if ( ((ArrayList)parameters.get(index)).get(i) instanceof String ) {
          displayableSql.append("'");
          displayableSql.append(((ArrayList)parameters.get(index)).get(i));
          displayableSql.append("'");
        } else if ( ((ArrayList)parameters.get(index)).get(i)==null ) {
          displayableSql.append("NULL");
        } else {
          displayableSql.append(((ArrayList)parameters.get(index)).get(i));
        }
        i++;
        limit++;
        base = limit;
      }

      if (base < preparedSql.length()) {
        displayableSql.append(preparedSql.substring(base));
      }
    }
   
    return displayableSql.toString();
  }


  /**
   * Logs the success of a SQL execution.
   *
   * @param result String The string representation of the SQL result.
   * @param time long The execution time.
   */
  private void logSql(String result, long time) {
    if ( log.isInfoEnabled()) {
      for (int i = 0; i < parameters.size(); i++) {
        log.info(getId()+":"+getDisplayableSql(i)+" => "+result+" ("+(time)+" ms)");
      }
    }
  }


  /**
   * Logs the failure of a SQL execution.
   *
   * @param e SQLException The throwed SQL exception by the execution.
   * @param time long The execution time.
   */
  private void logSql(SQLException e, long time) {
    if ( log.isErrorEnabled()) {
      for (int i = 0; i < parameters.size(); i++) {
        log.error(getId()+":"+getDisplayableSql(i)+" => state="+e.getSQLState()+",code="+e.getErrorCode()+" ("+(time)+" ms)",e);
      }
    }
  }


  /**
   * @see PreparedStatement#executeUpdate()
   */
  public int executeUpdate() throws SQLException {
    long end, start = System.currentTimeMillis();
    int result = 0;


    try {
      result = real.executeUpdate();
      end = System.currentTimeMillis();
      logSql(String.valueOf(result),end-start);
    } catch ( SQLException e) {
      end = System.currentTimeMillis();
      logSql(e,end-start);
      throw e;
    }

    return result;
  }


  /**
   * @see PreparedStatement#addBatch()
   */
  public void addBatch() throws SQLException {
    addParametersList();
    real.addBatch();
  }


  /**
   * @see PreparedStatement#clearParameters()
   */
  public void clearParameters() throws SQLException {
    for ( int i = 0; i < parameters.size(); i++) parameters.remove(i);
    real.clearParameters();
  }


  /**
   * @see PreparedStatement#execute()
   */
  public boolean execute() throws SQLException {
    long end, start = System.currentTimeMillis();
    boolean result = false;


    try {
      result = real.execute();
      end = System.currentTimeMillis();
      logSql(String.valueOf(result),end-start);
    } catch ( SQLException e) {
      end = System.currentTimeMillis();
      logSql(e,end-start);
      throw e;
    }

    return result;
  }


  /**
   * @see PreparedStatement#setByte(int, byte)
   */
  public void setByte(int parameterIndex, byte x) throws SQLException {
    registerInputParameter(parameterIndex,new Byte(x).toString());
    real.setByte(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setDouble(int, double)
   */
  public void setDouble(int parameterIndex, double x) throws SQLException {
    registerInputParameter(parameterIndex,new Double(x));
    real.setDouble(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setFloat(int, float)
   */
  public void setFloat(int parameterIndex, float x) throws SQLException {
    registerInputParameter(parameterIndex,new Float(x));
    real.setFloat(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setInt(int, int)
   */
  public void setInt(int parameterIndex, int x) throws SQLException {
    registerInputParameter(parameterIndex,new Integer(x));
    real.setInt(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setNull(int, int)
   */
  public void setNull(int parameterIndex, int sqlType) throws SQLException {
    registerInputParameter(parameterIndex,null);
    real.setNull(parameterIndex,sqlType);
  }


  /**
   * @see PreparedStatement#setLong(int, long)
   */
  public void setLong(int parameterIndex, long x) throws SQLException {
    registerInputParameter(parameterIndex,new Long(x));
    real.setLong(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setShort(int, short)
   */
  public void setShort(int parameterIndex, short x) throws SQLException {
    registerInputParameter(parameterIndex,new Short(x));
    real.setShort(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setBoolean(int, boolean)
   */
  public void setBoolean(int parameterIndex, boolean x) throws SQLException {
    registerInputParameter(parameterIndex,Boolean.valueOf(x).toString());
    real.setBoolean(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setBytes(int, byte[])
   */
  public void setBytes(int parameterIndex, byte[] x) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setBytes(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setAsciiStream(int, java.io.InputStream, int)
   */
  public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setAsciiStream(parameterIndex,x,length);
  }


  /**
   * @see PreparedStatement#setBinaryStream(int, java.io.InputStream, int)
   */
  public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setBinaryStream(parameterIndex,x,length);
  }


  /**
   * @see PreparedStatement#setUnicodeStream(int, java.io.InputStream, int)
   */
  public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setUnicodeStream(parameterIndex,x,length);
  }


  /**
   * @see PreparedStatement#setCharacterStream(int, java.io.Reader, int)
   */
  public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
    registerInputParameter(parameterIndex,reader.toString());
    real.setCharacterStream(parameterIndex,reader,length);
  }


  /**
   * @see PreparedStatement#setObject(int, Object)
   */
  public void setObject(int parameterIndex, Object x) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setObject(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setObject(int, Object, int)
   */
  public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setObject(parameterIndex,x,targetSqlType);
  }


  /**
   * @see PreparedStatement#setObject(int, Object, int, int)
   */
  public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setObject(parameterIndex,x,targetSqlType,scale);
  }


  /**
   * @see PreparedStatement#setNull(int, int, String)
   */
  public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException {
    registerInputParameter(paramIndex,null);
    real.setNull(paramIndex,sqlType,typeName);
  }


  /**
   * @see PreparedStatement#setString(int, String)
   */
  public void setString(int parameterIndex, String x) throws SQLException {
    registerInputParameter(parameterIndex,x);
    real.setString(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setBigDecimal(int, java.math.BigDecimal)
   */
  public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setBigDecimal(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setURL(int, java.net.URL)
   */
  public void setURL(int parameterIndex, URL x) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setURL(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setArray(int, Array)
   */
  public void setArray(int i, Array x) throws SQLException {
    registerInputParameter(i,x.toString());
    real.setArray(i,x);
  }


  /**
   * @see PreparedStatement#setBlob(int, Blob)
   */
  public void setBlob(int i, Blob x) throws SQLException {
    registerInputParameter(i,x.toString());
    real.setBlob(i,x);
  }


  /**
   * @see PreparedStatement#setClob(int, Clob)
   */
  public void setClob(int i, Clob x) throws SQLException {
    registerInputParameter(i,x.toString());
    real.setClob(i,x);
  }


  /**
   * @see PreparedStatement#setDate(int, Date)
   */
  public void setDate(int parameterIndex, Date x) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setDate(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#getParameterMetaData()
   */
  public ParameterMetaData getParameterMetaData() throws SQLException {
    return real.getParameterMetaData();
  }


  /**
   * @see PreparedStatement#setRef(int, Ref)
   */
  public void setRef(int i, Ref x) throws SQLException {
    registerInputParameter(i,x.toString());
    real.setRef(i,x);
  }


  /**
   * @see PreparedStatement#executeQuery()
   */
  public ResultSet executeQuery() throws SQLException {
    long end, start = System.currentTimeMillis();
    ResultSet result = null;


    try {
      result = new SpyResultSet ( getConnection(), this, real.executeQuery());
      end = System.currentTimeMillis();
      logSql("...",end-start);
    } catch ( SQLException e) {
      end = System.currentTimeMillis();
      logSql(e,end-start);
      throw e;
    }

    return result;
  }


  /**
   * @see PreparedStatement#getMetaData()
   */
  public ResultSetMetaData getMetaData() throws SQLException {
    return real.getMetaData();
  }


  /**
   * @see PreparedStatement#setTime(int, Time)
   */
  public void setTime(int parameterIndex, Time x) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setTime(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setTimestamp(int, Timestamp)
   */
  public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setTimestamp(parameterIndex,x);
  }


  /**
   * @see PreparedStatement#setDate(int, Date, Calendar)
   */
  public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setDate(parameterIndex,x,cal);
  }


  /**
   * @see PreparedStatement#setTime(int, Time, Calendar)
   */
  public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setTime(parameterIndex,x,cal);
  }


  /**
   * @see PreparedStatement#setTimestamp(int, Timestamp, Calendar)
   */
  public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
    registerInputParameter(parameterIndex,x.toString());
    real.setTimestamp(parameterIndex,x,cal);
  }


  /**
   * @see java.sql.Statement#executeBatch()
   */
  public int[] executeBatch() throws SQLException {
    // Adds all the prepared statements in the logged batches
    for (int i = 0; i < parameters.size() - 1; i++) {
      batch.add(getDisplayableSql(i));
    }

    // Executes (and logs) all the batches
    return super.executeBatch();
  }
}
TOP

Related Classes of craftsman.spy.SpyPreparedStatement

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.