Boilerplate JDBC Wrapper

We use JDBC to connect to our database, but most of our code doesn’t connect directly to JDBC. Instead, we go through Hibernate, which is great for most purposes, but can make it difficult to do low level tweaks. We might want to do things like:

  1. Generate performance metrics per-thread, to get a SQL oriented performance profile for individual controllers
  2. Provide a single, central location to tweak SQL before running it
  3. Write unit tests that make assertions about the number or type of SQL statements that higher level code runs
  4. Trace Queries and ResultSet sizes
  5. Debug the SQL generated by third party libraries, and how those libraries use JDBC

I wrote wrappers for the most relevant interfaces (Driver, Connection, Statement, CallableStatement, PreparedStatement, ResultSet.) It’s 100% boilerplate (I didn’t implement any USEFUL functionality- that’s for you to do!) It took me a few hours, so I thought I’d share- no point in us all writing the same boilerplate over and over! Obviously, you’ll have to tweak this code for your own purposes.

To use it, you would use ‘redfin’ in your JDBC URL scheme, like this: ‘jdbc:redfin://blahblah’. You’d also set your JDBC driver class to ‘redfin.util.jdbc.DriverWrapper’. The exact mechanism you use to do this is obviously dependent on your environment.

[Click through to the full post for the code.]

DriverWrapper.java:

package redfin.util.jdbc;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.util.Properties;

public class DriverWrapper implements Driver {
    
    // The class of the driver that we're wrapping
    //TODO: CHANGE THIS
    public static final String WRAPPED_DRIVER = "org.postgresql.Driver";
    
    // The scheme of the driver we're wrapping. For instance, if the JDBC URL for
    // the DB we want to connect to is:
    //        jdbc:postgresql://db_server.redfintest.com/production
    // then this string should be "jdbc:postgresql:"
    //TODO: CHANGE THIS
    public static final String WRAPPED_DRIVER_SCHEME = "jdbc:postgresql:";
    
    // The scheme of THIS driver (the wrapper.) Clients use this scheme when they
    // want to use this driver.
    public static final String THIS_DRIVER_SCHEME = "jdbc:redfin:";

    private Driver wrappedDriver;
    
    static {
     try {
     DriverManager.registerDriver(new DriverWrapper());
     } catch (Exception e) {}
    }

    public DriverWrapper() throws SQLException {
        try {
            // TODO: For more flexibility, we COULD defer this, and encode this
            //    info into the driver scheme. That way, we could allow users to
            //    dynamically specify the underlying driver and scheme in the JDBC URL.
            wrappedDriver = (Driver) Class.forName(WRAPPED_DRIVER).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public boolean acceptsURL(String url) throws SQLException {
        // Remove our special stuff from the URL
        String fixedUrl = fixupUrl(url);
        // If the fixed URL is the same as the original URL, then it's NOT one of
        // our URLs and we shouldn't handle it.
        if (fixedUrl.equals(url)) {
            return false;
        }
        
        // Pass the corrected URL to the underlying driver-
        // if the underlying driver can accept the URL, then we can too!
        return wrappedDriver.acceptsURL(fixedUrl);
    }

    public Connection connect(String url, Properties info) throws SQLException {
        // Remove our special stuff from the URL
        url = fixupUrl(url);
        // And pass through
        Connection conn = wrappedDriver.connect(url, info);
        return new ConnectionWrapper(conn);
    }

    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
            throws SQLException {
        return wrappedDriver.getPropertyInfo(url, info);
    }

    public int getMajorVersion() {
        return wrappedDriver.getMajorVersion();
    }

    public int getMinorVersion() {
        return wrappedDriver.getMinorVersion();
    }

    public boolean jdbcCompliant() {
        return wrappedDriver.jdbcCompliant();
    }
    
    private String fixupUrl(String url) {
        if (url.startsWith(THIS_DRIVER_SCHEME)) {
            url = WRAPPED_DRIVER_SCHEME + url.substring(THIS_DRIVER_SCHEME.length());
        }
        
        return url;
    }
}

ConnectionWrapper.java:

package redfin.util.jdbc;

import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;

import redfin.util.stats.PerfStatsManager;

/**
* A wrapper for Connections generated by DriverWrapper. See comments in DriverWrapper.
*
*/
public class ConnectionWrapper implements Connection {
    
    private Connection wrappedConnection;
    
    public ConnectionWrapper(Connection wrappedConnection) {
        this.wrappedConnection = wrappedConnection;
    }
    
    // Semi-copied from http://www.java2s.com/Open-Source/Java-Document/Database-JDBC-Connection-Pool/mysql/com/mysql/jdbc/jdbc2/optional/JDBC4PreparedStatementWrapper.java.htm
    public T unwrap(Class iface) throws SQLException {
        try {
         if (    "java.sql.Connection".equals(iface.getName())
         || "java.sql.Wrapper.class".equals(iface.getName())) {
         return iface.cast(this);
         }

            return wrappedConnection.unwrap(iface);
        } catch (ClassCastException cce) {
            throw new SQLException("Unable to unwrap to " + iface.toString(), cce);
        }
    }

    public boolean isWrapperFor(Class iface) throws SQLException {
     if (    "java.sql.Connection".equals(iface.getName())
     || "java.sql.Wrapper.class".equals(iface.getName())) {
            return true;
        }
        return wrappedConnection.isWrapperFor(iface);
    }

    public Statement createStatement() throws SQLException {
        return new StatementWrapper(this, wrappedConnection.createStatement());
    }

    public PreparedStatement prepareStatement(String sql) throws SQLException {
        return new PreparedStatementWrapper(this, wrappedConnection.prepareStatement(sql));
    }

    public CallableStatement prepareCall(String sql) throws SQLException {
        return new CallableStatementWrapper(this, wrappedConnection.prepareCall(sql));
    }

    public String nativeSQL(String sql) throws SQLException {
        return wrappedConnection.nativeSQL(sql);
    }

    public void setAutoCommit(boolean autoCommit) throws SQLException {
        wrappedConnection.setAutoCommit(autoCommit);
    }

    public boolean getAutoCommit() throws SQLException {
        return wrappedConnection.getAutoCommit();
    }

    public void commit() throws SQLException {
        wrappedConnection.commit();
    }

    public void rollback() throws SQLException {
        wrappedConnection.rollback();
    }

    public void close() throws SQLException {
        wrappedConnection.close();
    }

    public boolean isClosed() throws SQLException {
        return wrappedConnection.isClosed();
    }

    public DatabaseMetaData getMetaData() throws SQLException {
        return wrappedConnection.getMetaData();
    }

    public void setReadOnly(boolean readOnly) throws SQLException {
        wrappedConnection.setReadOnly(readOnly);
    }

    public boolean isReadOnly() throws SQLException {
        return wrappedConnection.isReadOnly();
    }

    public void setCatalog(String catalog) throws SQLException {
        wrappedConnection.setCatalog(catalog);
    }

    public String getCatalog() throws SQLException {
        return wrappedConnection.getCatalog();
    }

    public void setTransactionIsolation(int level) throws SQLException {
        wrappedConnection.setTransactionIsolation(level);
    }

    public int getTransactionIsolation() throws SQLException {
        return wrappedConnection.getTransactionIsolation();
    }

    public SQLWarning getWarnings() throws SQLException {
        return wrappedConnection.getWarnings();
    }

    public void clearWarnings() throws SQLException {
        wrappedConnection.clearWarnings();
    }

    public Statement createStatement(int resultSetType, int resultSetConcurrency)
            throws SQLException {
        return new StatementWrapper(this, wrappedConnection.createStatement(resultSetType, resultSetConcurrency));
    }

    public PreparedStatement prepareStatement(String sql, int resultSetType,
            int resultSetConcurrency) throws SQLException {
        return new PreparedStatementWrapper(this, wrappedConnection.prepareStatement(sql, resultSetType, resultSetConcurrency));
    }

    public CallableStatement prepareCall(String sql, int resultSetType,
            int resultSetConcurrency) throws SQLException {
        return new CallableStatementWrapper(this, wrappedConnection.prepareCall(sql, resultSetType, resultSetConcurrency));
    }

    public Map<String, Class> getTypeMap() throws SQLException {
        return wrappedConnection.getTypeMap();
    }

    public void setTypeMap(Map<String, Class> map) throws SQLException {
        wrappedConnection.setTypeMap(map);
    }

    public void setHoldability(int holdability) throws SQLException {
        wrappedConnection.setHoldability(holdability);
    }

    public int getHoldability() throws SQLException {
        return wrappedConnection.getHoldability();
    }

    public Savepoint setSavepoint() throws SQLException {
        return wrappedConnection.setSavepoint();
    }

    public Savepoint setSavepoint(String name) throws SQLException {
        return wrappedConnection.setSavepoint(name);
    }

    public void rollback(Savepoint savepoint) throws SQLException {
        wrappedConnection.rollback(savepoint);
    }

    public void releaseSavepoint(Savepoint savepoint) throws SQLException {
        wrappedConnection.releaseSavepoint(savepoint);
    }

    public Statement createStatement(int resultSetType,
            int resultSetConcurrency, int resultSetHoldability)
            throws SQLException {
        return new StatementWrapper(this, wrappedConnection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability));
    }

    public PreparedStatement prepareStatement(String sql, int resultSetType,
            int resultSetConcurrency, int resultSetHoldability)
            throws SQLException {
        return new PreparedStatementWrapper(this, wrappedConnection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
    }

    public CallableStatement prepareCall(String sql, int resultSetType,
            int resultSetConcurrency, int resultSetHoldability)
            throws SQLException {
        return new CallableStatementWrapper(this, wrappedConnection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
    }

    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
            throws SQLException {
        return new PreparedStatementWrapper(this, wrappedConnection.prepareStatement(sql, autoGeneratedKeys));
    }

    public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
            throws SQLException {
        return new PreparedStatementWrapper(this, wrappedConnection.prepareStatement(sql, columnIndexes));
    }

    public PreparedStatement prepareStatement(String sql, String[] columnNames)
            throws SQLException {
        return new PreparedStatementWrapper(this, wrappedConnection.prepareStatement(sql, columnNames));
    }

    public Clob createClob() throws SQLException {
        return wrappedConnection.createClob();
    }

    public Blob createBlob() throws SQLException {
        return wrappedConnection.createBlob();
    }

    public NClob createNClob() throws SQLException {
        return wrappedConnection.createNClob();
    }

    public SQLXML createSQLXML() throws SQLException {
        return wrappedConnection.createSQLXML();
    }

    public boolean isValid(int timeout) throws SQLException {
        return wrappedConnection.isValid(timeout);
    }

    public void setClientInfo(String name, String value)
            throws SQLClientInfoException {
        wrappedConnection.setClientInfo(name, value);
    }

    public void setClientInfo(Properties properties)
            throws SQLClientInfoException {
        wrappedConnection.setClientInfo(properties);
    }

    public String getClientInfo(String name) throws SQLException {
        return wrappedConnection.getClientInfo(name);
    }

    public Properties getClientInfo() throws SQLException {
        return wrappedConnection.getClientInfo();
    }

    public Array createArrayOf(String typeName, Object[] elements)
            throws SQLException {
        return wrappedConnection.createArrayOf(typeName, elements);
    }

    public Struct createStruct(String typeName, Object[] attributes)
            throws SQLException {
        return wrappedConnection.createStruct(typeName, attributes);
    }
}

StatementWrapper.java:

package redfin.util.jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;

import redfin.util.stats.PerfStatsManager;

/**
* A wrapper for Statements generated by ConnectionWrapper. See comments in DriverWrapper.
*
*/
public class StatementWrapper implements Statement {
    
    private Connection parentConnection;
    private Statement wrappedStatement;
    
    public StatementWrapper(Connection parentConnection, Statement wrappedStatement) {
        this.parentConnection = parentConnection;
        this.wrappedStatement = wrappedStatement;
        
        if (PerfStatsManager.perfStatsEnabled()) {
            PerfStatsManager.getThreadLocalJDBCPerfStats().incrementNumStatements();
        }
    }
    
    // Semi-copied from http://www.java2s.com/Open-Source/Java-Document/Database-JDBC-Connection-Pool/mysql/com/mysql/jdbc/jdbc2/optional/JDBC4PreparedStatementWrapper.java.htm
    public T unwrap(Class iface) throws SQLException {
        try {
         if (    "java.sql.Statement".equals(iface.getName())
         || "java.sql.Wrapper.class".equals(iface.getName())) {
         return iface.cast(this);
         }

            return wrappedStatement.unwrap(iface);
        } catch (ClassCastException cce) {
            throw new SQLException("Unable to unwrap to " + iface.toString(), cce);
        }
    }

    public boolean isWrapperFor(Class iface) throws SQLException {
     if (    "java.sql.Statement".equals(iface.getName())
     || "java.sql.Wrapper.class".equals(iface.getName())) {
            return true;
        }
        return wrappedStatement.isWrapperFor(iface);
    }

    public ResultSet executeQuery(String sql) throws SQLException {
        return new ResultSetWrapper(this, wrappedStatement.executeQuery(sql));
    }

    public int executeUpdate(String sql) throws SQLException {
        return wrappedStatement.executeUpdate(sql);
    }

    public void close() throws SQLException {
        wrappedStatement.close();
    }

    public int getMaxFieldSize() throws SQLException {
        return wrappedStatement.getMaxFieldSize();
    }

    public void setMaxFieldSize(int max) throws SQLException {
        wrappedStatement.setMaxFieldSize(max);
    }

    public int getMaxRows() throws SQLException {
        return wrappedStatement.getMaxRows();
    }

    public void setMaxRows(int max) throws SQLException {
        wrappedStatement.setMaxRows(max);
    }

    public void setEscapeProcessing(boolean enable) throws SQLException {
        wrappedStatement.setEscapeProcessing(enable);
    }

    public int getQueryTimeout() throws SQLException {
        return wrappedStatement.getQueryTimeout();
    }

    public void setQueryTimeout(int seconds) throws SQLException {
        wrappedStatement.setQueryTimeout(seconds);
    }

    public void cancel() throws SQLException {
        wrappedStatement.cancel();
    }

    public SQLWarning getWarnings() throws SQLException {
        return wrappedStatement.getWarnings();
    }

    public void clearWarnings() throws SQLException {
        wrappedStatement.clearWarnings();
    }

    public void setCursorName(String name) throws SQLException {
        wrappedStatement.setCursorName(name);
    }

    public boolean execute(String sql) throws SQLException {
        return wrappedStatement.execute(sql);
    }

    public ResultSet getResultSet() throws SQLException {
        return new ResultSetWrapper(this, wrappedStatement.getResultSet());
    }

    public int getUpdateCount() throws SQLException {
        return wrappedStatement.getUpdateCount();
    }

    public boolean getMoreResults() throws SQLException {
        return wrappedStatement.getMoreResults();
    }

    public void setFetchDirection(int direction) throws SQLException {
        wrappedStatement.setFetchDirection(direction);
    }

    public int getFetchDirection() throws SQLException {
        return wrappedStatement.getFetchDirection();
    }

    public void setFetchSize(int rows) throws SQLException {
        wrappedStatement.setFetchSize(rows);
    }

    public int getFetchSize() throws SQLException {
        return wrappedStatement.getFetchSize();
    }

    public int getResultSetConcurrency() throws SQLException {
        return wrappedStatement.getResultSetConcurrency();
    }

    public int getResultSetType() throws SQLException {
        return wrappedStatement.getResultSetType();
    }

    public void addBatch(String sql) throws SQLException {
        wrappedStatement.addBatch(sql);
    }

    public void clearBatch() throws SQLException {
        wrappedStatement.clearBatch();
    }

    public int[] executeBatch() throws SQLException {
        return = wrappedStatement.executeBatch();
    }

    public Connection getConnection() throws SQLException {
        return parentConnection;
    }

    public boolean getMoreResults(int current) throws SQLException {
        return wrappedStatement.getMoreResults(current);
    }

    public ResultSet getGeneratedKeys() throws SQLException {
        return new ResultSetWrapper(this, wrappedStatement.getGeneratedKeys());
    }

    public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
        return wrappedStatement.executeUpdate(sql, autoGeneratedKeys);
    }

    public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
        return wrappedStatement.executeUpdate(sql, columnIndexes);
    }

    public int executeUpdate(String sql, String[] columnNames) throws SQLException {
        return wrappedStatement.executeUpdate(sql, columnNames);
    }

    public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
        return wrappedStatement.execute(sql, autoGeneratedKeys);
    }

    public boolean execute(String sql, int[] columnIndexes) throws SQLException {
        return wrappedStatement.execute(sql, columnIndexes);
    }

    public boolean execute(String sql, String[] columnNames) throws SQLException {
        return wrappedStatement.execute(sql, columnNames);
    }

    public int getResultSetHoldability() throws SQLException {
        return wrappedStatement.getResultSetHoldability();
    }

    public boolean isClosed() throws SQLException {
        return wrappedStatement.isClosed();
    }

    public void setPoolable(boolean poolable) throws SQLException {
        wrappedStatement.setPoolable(poolable);
    }

    public boolean isPoolable() throws SQLException {
        return wrappedStatement.isPoolable();
    }
}

CallableStatementWrapper.java:

package redfin.util.jdbc;

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.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.Date;
import java.sql.NClob;
import java.sql.ParameterMetaData;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Map;

import redfin.util.stats.PerfStatsManager;

/**
* A wrapper for CallableStatements generated by ConnectionWrapper. See comments in DriverWrapper.
*
*/
public class CallableStatementWrapper implements CallableStatement {
    
    private Connection parentConnection;
    private CallableStatement wrappedCallableStatement;
    
    public CallableStatementWrapper(Connection parentConnection, CallableStatement wrappedCallableStatement) {
        this.parentConnection = parentConnection;
        this.wrappedCallableStatement = wrappedCallableStatement;
        
        if (PerfStatsManager.perfStatsEnabled()) {
            PerfStatsManager.getThreadLocalJDBCPerfStats().incrementNumStatements();
        }
    }

    // Semi-copied from http://www.java2s.com/Open-Source/Java-Document/Database-JDBC-Connection-Pool/mysql/com/mysql/jdbc/jdbc2/optional/JDBC4PreparedStatementWrapper.java.htm
    public T unwrap(Class iface) throws SQLException {
        try {
         if (    "java.sql.CallableStatement".equals(iface.getName())
         || "java.sql.PreparedStatement".equals(iface.getName())
         || "java.sql.Statement".equals(iface.getName())
         || "java.sql.Wrapper.class".equals(iface.getName())) {
         return iface.cast(this);
         }

            return wrappedCallableStatement.unwrap(iface);
        } catch (ClassCastException cce) {
            throw new SQLException("Unable to unwrap to " + iface.toString(), cce);
        }
    }

    public boolean isWrapperFor(Class iface) throws SQLException {
     if (    "java.sql.CallableStatement".equals(iface.getName())
     || "java.sql.PreparedStatement".equals(iface.getName())
     || "java.sql.Statement".equals(iface.getName())
     || "java.sql.Wrapper.class".equals(iface.getName())) {
            return true;
        }
        return wrappedCallableStatement.isWrapperFor(iface);
    }

    public ResultSet executeQuery() throws SQLException {
        return new ResultSetWrapper(this, wrappedCallableStatement.executeQuery());
    }

    public int executeUpdate() throws SQLException {
        return wrappedCallableStatement.executeUpdate();
    }

    public void setNull(int parameterIndex, int sqlType) throws SQLException {
        wrappedCallableStatement.setNull(parameterIndex, sqlType);
    }

    public void setBoolean(int parameterIndex, boolean x) throws SQLException {
        wrappedCallableStatement.setBoolean(parameterIndex, x);
    }

    public void setByte(int parameterIndex, byte x) throws SQLException {
        wrappedCallableStatement.setByte(parameterIndex, x);
    }

    public void setShort(int parameterIndex, short x) throws SQLException {
        wrappedCallableStatement.setShort(parameterIndex, x);
    }

    public void setInt(int parameterIndex, int x) throws SQLException {
        wrappedCallableStatement.setInt(parameterIndex, x);
    }

    public void setLong(int parameterIndex, long x) throws SQLException {
        wrappedCallableStatement.setLong(parameterIndex, x);
    }

    public void setFloat(int parameterIndex, float x) throws SQLException {
        wrappedCallableStatement.setFloat(parameterIndex, x);
    }

    public void setDouble(int parameterIndex, double x) throws SQLException {
        wrappedCallableStatement.setDouble(parameterIndex, x);
    }

    public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
        wrappedCallableStatement.setBigDecimal(parameterIndex, x);
    }

    public void setString(int parameterIndex, String x) throws SQLException {
        wrappedCallableStatement.setString(parameterIndex, x);
    }

    public void setBytes(int parameterIndex, byte[] x) throws SQLException {
        wrappedCallableStatement.setBytes(parameterIndex, x);
    }

    public void setDate(int parameterIndex, Date x) throws SQLException {
        wrappedCallableStatement.setDate(parameterIndex, x);
    }

    public void setTime(int parameterIndex, Time x) throws SQLException {
        wrappedCallableStatement.setTime(parameterIndex, x);
    }

    public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
        wrappedCallableStatement.setTimestamp(parameterIndex, x);
    }

    public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
        wrappedCallableStatement.setAsciiStream(parameterIndex, x);
    }

    @SuppressWarnings("deprecation")
    public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
        wrappedCallableStatement.setUnicodeStream(parameterIndex, x, length);
    }

    public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
        wrappedCallableStatement.setBinaryStream(parameterIndex, x);
    }

    public void clearParameters() throws SQLException {
        wrappedCallableStatement.clearParameters();
    }

    public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
        wrappedCallableStatement.setObject(parameterIndex, x, targetSqlType);
    }

    public void setObject(int parameterIndex, Object x) throws SQLException {
        wrappedCallableStatement.setObject(parameterIndex, x);
    }

    public boolean execute() throws SQLException {
        return wrappedCallableStatement.execute();
    }

    public void addBatch() throws SQLException {
        wrappedCallableStatement.addBatch();
    }

    public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
        wrappedCallableStatement.setCharacterStream(parameterIndex, reader, length);
    }

    public void setRef(int parameterIndex, Ref x) throws SQLException {
        wrappedCallableStatement.setRef(parameterIndex, x);
    }

    public void setBlob(int parameterIndex, Blob x) throws SQLException {
        wrappedCallableStatement.setBlob(parameterIndex, x);
    }

    public void setClob(int parameterIndex, Clob x) throws SQLException {
        wrappedCallableStatement.setClob(parameterIndex, x);
    }

    public void setArray(int parameterIndex, Array x) throws SQLException {
        wrappedCallableStatement.setArray(parameterIndex, x);
    }

    public ResultSetMetaData getMetaData() throws SQLException {
        return wrappedCallableStatement.getMetaData();
    }

    public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
        wrappedCallableStatement.setDate(parameterIndex, x, cal);
        
    }

    public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
        wrappedCallableStatement.setTime(parameterIndex, x, cal);
        
    }

    public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
        wrappedCallableStatement.setTimestamp(parameterIndex, x, cal);
        
    }

    public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
        wrappedCallableStatement.setNull(parameterIndex, sqlType, typeName);
        
    }

    public void setURL(int parameterIndex, URL x) throws SQLException {
        wrappedCallableStatement.setURL(parameterIndex, x);
    }

    public ParameterMetaData getParameterMetaData() throws SQLException {
        return wrappedCallableStatement.getParameterMetaData();
    }

    public void setRowId(int parameterIndex, RowId x) throws SQLException {
        wrappedCallableStatement.setRowId(parameterIndex, x);
    }

    public void setNString(int parameterIndex, String value) throws SQLException {
        wrappedCallableStatement.setNString(parameterIndex, value);
    }

    public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
        wrappedCallableStatement.setNCharacterStream(parameterIndex, value, length);
    }

    public void setNClob(int parameterIndex, NClob value) throws SQLException {
        wrappedCallableStatement.setNClob(parameterIndex, value);
    }

    public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
        wrappedCallableStatement.setClob(parameterIndex, reader, length);
    }

    public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
        wrappedCallableStatement.setBlob(parameterIndex, inputStream, length);
    }

    public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
        wrappedCallableStatement.setNClob(parameterIndex, reader, length);
    }

    public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
        wrappedCallableStatement.setSQLXML(parameterIndex, xmlObject);
    }

    public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
        wrappedCallableStatement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
    }

    public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
        wrappedCallableStatement.setAsciiStream(parameterIndex, x, length);
    }

    public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
        wrappedCallableStatement.setBinaryStream(parameterIndex, x, length);
    }

    public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
        wrappedCallableStatement.setCharacterStream(parameterIndex, reader, length);
    }

    public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
        wrappedCallableStatement.setAsciiStream(parameterIndex, x);
    }

    public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
        wrappedCallableStatement.setBinaryStream(parameterIndex, x);
    }

    public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
        wrappedCallableStatement.setCharacterStream(parameterIndex, reader);
    }

    public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
        wrappedCallableStatement.setNCharacterStream(parameterIndex, value);
    }

    public void setClob(int parameterIndex, Reader reader) throws SQLException {
        wrappedCallableStatement.setClob(parameterIndex, reader);
    }

    public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
        wrappedCallableStatement.setBlob(parameterIndex, inputStream);
    }

    public void setNClob(int parameterIndex, Reader reader) throws SQLException {
        wrappedCallableStatement.setNClob(parameterIndex, reader);
    }

    public ResultSet executeQuery(String sql) throws SQLException {
        return new ResultSetWrapper(this, wrappedCallableStatement.executeQuery(sql));
    }

    public int executeUpdate(String sql) throws SQLException {
        return wrappedCallableStatement.executeUpdate(sql);
    }

    public void close() throws SQLException {
        wrappedCallableStatement.close();
    }

    public int getMaxFieldSize() throws SQLException {
        return wrappedCallableStatement.getMaxFieldSize();
    }

    public void setMaxFieldSize(int max) throws SQLException {
        wrappedCallableStatement.setMaxFieldSize(max);
    }

    public int getMaxRows() throws SQLException {
        return wrappedCallableStatement.getMaxRows();
    }

    public void setMaxRows(int max) throws SQLException {
        wrappedCallableStatement.setMaxRows(max);
    }

    public void setEscapeProcessing(boolean enable) throws SQLException {
        wrappedCallableStatement.setEscapeProcessing(enable);
    }

    public int getQueryTimeout() throws SQLException {
        return wrappedCallableStatement.getQueryTimeout();
    }

    public void setQueryTimeout(int seconds) throws SQLException {
        wrappedCallableStatement.setQueryTimeout(seconds);
    }

    public void cancel() throws SQLException {
        wrappedCallableStatement.cancel();
    }

    public SQLWarning getWarnings() throws SQLException {
        return wrappedCallableStatement.getWarnings();
    }

    public void clearWarnings() throws SQLException {
        wrappedCallableStatement.clearWarnings();
    }

    public void setCursorName(String name) throws SQLException {
        wrappedCallableStatement.setCursorName(name);
    }

    public boolean execute(String sql) throws SQLException {
        return wrappedCallableStatement.execute(sql);
    }

    public ResultSet getResultSet() throws SQLException {
        return new ResultSetWrapper(this, wrappedCallableStatement.getResultSet());
    }

    public int getUpdateCount() throws SQLException {
        return wrappedCallableStatement.getUpdateCount();
    }

    public boolean getMoreResults() throws SQLException {
        return wrappedCallableStatement.getMoreResults();
    }

    public void setFetchDirection(int direction) throws SQLException {
        wrappedCallableStatement.setFetchDirection(direction);
    }

    public int getFetchDirection() throws SQLException {
        return wrappedCallableStatement.getFetchDirection();
    }

    public void setFetchSize(int rows) throws SQLException {
        wrappedCallableStatement.setFetchSize(rows);
    }

    public int getFetchSize() throws SQLException {
        return wrappedCallableStatement.getFetchSize();
    }

    public int getResultSetConcurrency() throws SQLException {
        return wrappedCallableStatement.getResultSetConcurrency();
    }

    public int getResultSetType() throws SQLException {
        return wrappedCallableStatement.getResultSetType();
    }

    public void addBatch(String sql) throws SQLException {
        wrappedCallableStatement.addBatch(sql);
    }

    public void clearBatch() throws SQLException {
        wrappedCallableStatement.clearBatch();
    }

    public int[] executeBatch() throws SQLException {
        return wrappedCallableStatement.executeBatch();
    }

    public Connection getConnection() throws SQLException {
        return parentConnection;
    }

    public boolean getMoreResults(int current) throws SQLException {
        return wrappedCallableStatement.getMoreResults(current);
    }

    public ResultSet getGeneratedKeys() throws SQLException {
        return new ResultSetWrapper(this, wrappedCallableStatement.getGeneratedKeys());
    }

    public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
        return wrappedCallableStatement.executeUpdate(sql, autoGeneratedKeys);
    }

    public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
        return wrappedCallableStatement.executeUpdate(sql, columnIndexes);
    }

    public int executeUpdate(String sql, String[] columnNames) throws SQLException {
        return wrappedCallableStatement.executeUpdate(sql, columnNames);
    }

    public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
        return wrappedCallableStatement.execute(sql, autoGeneratedKeys);
    }

    public boolean execute(String sql, int[] columnIndexes) throws SQLException {
        return wrappedCallableStatement.execute(sql, columnIndexes);
    }

    public boolean execute(String sql, String[] columnNames) throws SQLException {
        return wrappedCallableStatement.execute(sql, columnNames);
    }

    public int getResultSetHoldability() throws SQLException {
        return wrappedCallableStatement.getResultSetHoldability();
    }

    public boolean isClosed() throws SQLException {
        return wrappedCallableStatement.isClosed();
    }

    public void setPoolable(boolean poolable) throws SQLException {
        wrappedCallableStatement.setPoolable(poolable);
    }

    public boolean isPoolable() throws SQLException {
        return wrappedCallableStatement.isPoolable();
    }

    public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException {
        wrappedCallableStatement.registerOutParameter(parameterIndex, sqlType);
    }

    public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException {
        wrappedCallableStatement.registerOutParameter(parameterIndex, sqlType, scale);
    }

    public boolean wasNull() throws SQLException {
        return wrappedCallableStatement.wasNull();
    }

    public String getString(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getString(parameterIndex);
    }

    public boolean getBoolean(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getBoolean(parameterIndex);
    }

    public byte getByte(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getByte(parameterIndex);
    }

    public short getShort(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getShort(parameterIndex);
    }

    public int getInt(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getInt(parameterIndex);
    }

    public long getLong(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getLong(parameterIndex);
    }

    public float getFloat(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getFloat(parameterIndex);
    }

    public double getDouble(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getDouble(parameterIndex);
    }

    public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException {
        return wrappedCallableStatement.getBigDecimal(parameterIndex);
    }

    public byte[] getBytes(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getBytes(parameterIndex);
    }

    public Date getDate(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getDate(parameterIndex);
    }

    public Time getTime(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getTime(parameterIndex);
    }

    public Timestamp getTimestamp(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getTimestamp(parameterIndex);
    }

    public Object getObject(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getObject(parameterIndex);
    }

    public BigDecimal getBigDecimal(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getBigDecimal(parameterIndex);
    }

    public Object getObject(int parameterIndex, Map<String, Class> map) throws SQLException {
        return wrappedCallableStatement.getObject(parameterIndex, map);
    }

    public Ref getRef(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getRef(parameterIndex);
    }

    public Blob getBlob(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getBlob(parameterIndex);
    }

    public Clob getClob(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getClob(parameterIndex);
    }

    public Array getArray(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getArray(parameterIndex);
    }

    public Date getDate(int parameterIndex, Calendar cal) throws SQLException {
        return wrappedCallableStatement.getDate(parameterIndex, cal);
    }

    public Time getTime(int parameterIndex, Calendar cal) throws SQLException {
        return wrappedCallableStatement.getTime(parameterIndex, cal);
    }

    public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException {
        return wrappedCallableStatement.getTimestamp(parameterIndex, cal);
    }

    public void registerOutParameter(int parameterIndex, int sqlType, String typeName) throws SQLException {
        wrappedCallableStatement.registerOutParameter(parameterIndex, sqlType, typeName);
    }

    public void registerOutParameter(String parameterName, int sqlType) throws SQLException {
        wrappedCallableStatement.registerOutParameter(parameterName, sqlType);
    }

    public void registerOutParameter(String parameterName, int sqlType, int scale) throws SQLException {
        wrappedCallableStatement.registerOutParameter(parameterName, sqlType);
    }

    public void registerOutParameter(String parameterName, int sqlType, String typeName) throws SQLException {
        wrappedCallableStatement.registerOutParameter(parameterName, sqlType, typeName);
    }

    public URL getURL(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getURL(parameterIndex);
    }

    public void setURL(String parameterName, URL val) throws SQLException {
        wrappedCallableStatement.setURL(parameterName, val);
    }

    public void setNull(String parameterName, int sqlType) throws SQLException {
        wrappedCallableStatement.setNull(parameterName, sqlType);
    }

    public void setBoolean(String parameterName, boolean x) throws SQLException {
        wrappedCallableStatement.setBoolean(parameterName, x);
    }

    public void setByte(String parameterName, byte x) throws SQLException {
        wrappedCallableStatement.setByte(parameterName, x);
    }

    public void setShort(String parameterName, short x) throws SQLException {
        wrappedCallableStatement.setShort(parameterName, x);
    }

    public void setInt(String parameterName, int x) throws SQLException {
        wrappedCallableStatement.setInt(parameterName, x);
    }

    public void setLong(String parameterName, long x) throws SQLException {
        wrappedCallableStatement.setLong(parameterName, x);
    }

    public void setFloat(String parameterName, float x) throws SQLException {
        wrappedCallableStatement.setFloat(parameterName, x);
    }

    public void setDouble(String parameterName, double x) throws SQLException {
        wrappedCallableStatement.setDouble(parameterName, x);
    }

    public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException {
        wrappedCallableStatement.setBigDecimal(parameterName, x);
    }

    public void setString(String parameterName, String x) throws SQLException {
        wrappedCallableStatement.setString(parameterName, x);
    }

    public void setBytes(String parameterName, byte[] x) throws SQLException {
        wrappedCallableStatement.setBytes(parameterName, x);
    }

    public void setDate(String parameterName, Date x) throws SQLException {
        wrappedCallableStatement.setDate(parameterName, x);
    }

    public void setTime(String parameterName, Time x) throws SQLException {
        wrappedCallableStatement.setTime(parameterName, x);
    }

    public void setTimestamp(String parameterName, Timestamp x) throws SQLException {
        wrappedCallableStatement.setTimestamp(parameterName, x);
    }

    public void setAsciiStream(String parameterName, InputStream x, int length) throws SQLException {
        wrappedCallableStatement.setAsciiStream(parameterName, x, length);
    }

    public void setBinaryStream(String parameterName, InputStream x, int length) throws SQLException {
        wrappedCallableStatement.setBinaryStream(parameterName, x, length);
    }

    public void setObject(String parameterName, Object x, int targetSqlType, int scale) throws SQLException {
        wrappedCallableStatement.setObject(parameterName, x, targetSqlType, scale);
    }

    public void setObject(String parameterName, Object x, int targetSqlType) throws SQLException {
        wrappedCallableStatement.setObject(parameterName, x, targetSqlType);
    }

    public void setObject(String parameterName, Object x) throws SQLException {
        wrappedCallableStatement.setObject(parameterName, x);
    }

    public void setCharacterStream(String parameterName, Reader reader, int length) throws SQLException {
        wrappedCallableStatement.setCharacterStream(parameterName, reader, length);
    }

    public void setDate(String parameterName, Date x, Calendar cal) throws SQLException {
        wrappedCallableStatement.setDate(parameterName, x, cal);
    }

    public void setTime(String parameterName, Time x, Calendar cal) throws SQLException {
        wrappedCallableStatement.setTime(parameterName, x, cal);
    }

    public void setTimestamp(String parameterName, Timestamp x, Calendar cal) throws SQLException {
        wrappedCallableStatement.setTimestamp(parameterName, x, cal);
    }

    public void setNull(String parameterName, int sqlType, String typeName) throws SQLException {
        wrappedCallableStatement.setNull(parameterName, sqlType, typeName);
    }

    public String getString(String parameterName) throws SQLException {
        return wrappedCallableStatement.getString(parameterName);
    }

    public boolean getBoolean(String parameterName) throws SQLException {
        return wrappedCallableStatement.getBoolean(parameterName);
    }

    public byte getByte(String parameterName) throws SQLException {
        return wrappedCallableStatement.getByte(parameterName);
    }

    public short getShort(String parameterName) throws SQLException {
        return wrappedCallableStatement.getShort(parameterName);
    }

    public int getInt(String parameterName) throws SQLException {
        return wrappedCallableStatement.getInt(parameterName);
    }

    public long getLong(String parameterName) throws SQLException {
        return wrappedCallableStatement.getLong(parameterName);
    }

    public float getFloat(String parameterName) throws SQLException {
        return wrappedCallableStatement.getFloat(parameterName);
    }

    public double getDouble(String parameterName) throws SQLException {
        return wrappedCallableStatement.getDouble(parameterName);
    }

    public byte[] getBytes(String parameterName) throws SQLException {
        return wrappedCallableStatement.getBytes(parameterName);
    }

    public Date getDate(String parameterName) throws SQLException {
        return wrappedCallableStatement.getDate(parameterName);
    }

    public Time getTime(String parameterName) throws SQLException {
        return wrappedCallableStatement.getTime(parameterName);
    }

    public Timestamp getTimestamp(String parameterName) throws SQLException {
        return wrappedCallableStatement.getTimestamp(parameterName);
    }

    public Object getObject(String parameterName) throws SQLException {
        return wrappedCallableStatement.getObject(parameterName);
    }

    public BigDecimal getBigDecimal(String parameterName) throws SQLException {
        return wrappedCallableStatement.getBigDecimal(parameterName);
    }

    public Object getObject(String parameterName, Map<String, Class> map) throws SQLException {
        return wrappedCallableStatement.getObject(parameterName, map);
    }

    public Ref getRef(String parameterName) throws SQLException {
        return wrappedCallableStatement.getRef(parameterName);
    }

    public Blob getBlob(String parameterName) throws SQLException {
        return wrappedCallableStatement.getBlob(parameterName);
    }

    public Clob getClob(String parameterName) throws SQLException {
        return wrappedCallableStatement.getClob(parameterName);
    }

    public Array getArray(String parameterName) throws SQLException {
        return wrappedCallableStatement.getArray(parameterName);
    }

    public Date getDate(String parameterName, Calendar cal) throws SQLException {
        return wrappedCallableStatement.getDate(parameterName, cal);
    }

    public Time getTime(String parameterName, Calendar cal) throws SQLException {
        return wrappedCallableStatement.getTime(parameterName, cal);
    }

    public Timestamp getTimestamp(String parameterName, Calendar cal) throws SQLException {
        return wrappedCallableStatement.getTimestamp(parameterName, cal);
    }

    public URL getURL(String parameterName) throws SQLException {
        return wrappedCallableStatement.getURL(parameterName);
    }

    public RowId getRowId(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getRowId(parameterIndex);
    }

    public RowId getRowId(String parameterName) throws SQLException {
        return wrappedCallableStatement.getRowId(parameterName);
    }

    public void setRowId(String parameterName, RowId x) throws SQLException {
        wrappedCallableStatement.setRowId(parameterName, x);
    }

    public void setNString(String parameterName, String value) throws SQLException {
        wrappedCallableStatement.setNString(parameterName, value);
    }

    public void setNCharacterStream(String parameterName, Reader value, long length) throws SQLException {
        wrappedCallableStatement.setNCharacterStream(parameterName, value, length);
    }

    public void setNClob(String parameterName, NClob value) throws SQLException {
        wrappedCallableStatement.setNClob(parameterName, value);
    }

    public void setClob(String parameterName, Reader reader, long length) throws SQLException {
        wrappedCallableStatement.setClob(parameterName, reader, length);
    }

    public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException {
        wrappedCallableStatement.setBlob(parameterName, inputStream, length);
    }

    public void setNClob(String parameterName, Reader reader, long length) throws SQLException {
        wrappedCallableStatement.setNClob(parameterName, reader, length);
    }

    public NClob getNClob(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getNClob(parameterIndex);
    }

    public NClob getNClob(String parameterName) throws SQLException {
        return wrappedCallableStatement.getNClob(parameterName);
    }

    public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException {
        wrappedCallableStatement.setSQLXML(parameterName, xmlObject);
    }

    public SQLXML getSQLXML(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getSQLXML(parameterIndex);
    }

    public SQLXML getSQLXML(String parameterName) throws SQLException {
        return wrappedCallableStatement.getSQLXML(parameterName);
    }

    public String getNString(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getNString(parameterIndex);
    }

    public String getNString(String parameterName) throws SQLException {
        return wrappedCallableStatement.getNString(parameterName);
    }

    public Reader getNCharacterStream(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getNCharacterStream(parameterIndex);
    }

    public Reader getNCharacterStream(String parameterName) throws SQLException {
        return wrappedCallableStatement.getNCharacterStream(parameterName);
    }

    public Reader getCharacterStream(int parameterIndex) throws SQLException {
        return wrappedCallableStatement.getCharacterStream(parameterIndex);
    }

    public Reader getCharacterStream(String parameterName) throws SQLException {
        return wrappedCallableStatement.getCharacterStream(parameterName);
    }

    public void setBlob(String parameterName, Blob x) throws SQLException {
        wrappedCallableStatement.setBlob(parameterName, x);
    }

    public void setClob(String parameterName, Clob x) throws SQLException {
        wrappedCallableStatement.setClob(parameterName, x);
    }

    public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException {
        wrappedCallableStatement.setAsciiStream(parameterName, x, length);
    }

    public void setBinaryStream(String parameterName, InputStream x, long length) throws SQLException {
        wrappedCallableStatement.setBinaryStream(parameterName, x, length);
    }

    public void setCharacterStream(String parameterName, Reader reader, long length) throws SQLException {
        wrappedCallableStatement.setCharacterStream(parameterName, reader, length);
    }

    public void setAsciiStream(String parameterName, InputStream x) throws SQLException {
        wrappedCallableStatement.setAsciiStream(parameterName, x);
    }

    public void setBinaryStream(String parameterName, InputStream x) throws SQLException {
        wrappedCallableStatement.setBinaryStream(parameterName, x);
    }

    public void setCharacterStream(String parameterName, Reader reader) throws SQLException {
        wrappedCallableStatement.setCharacterStream(parameterName, reader);
    }

    public void setNCharacterStream(String parameterName, Reader value) throws SQLException {
        wrappedCallableStatement.setNCharacterStream(parameterName, value);
    }

    public void setClob(String parameterName, Reader reader) throws SQLException {
        wrappedCallableStatement.setClob(parameterName, reader);
    }

    public void setBlob(String parameterName, InputStream inputStream) throws SQLException {
        wrappedCallableStatement.setBlob(parameterName, inputStream);
    }

    public void setNClob(String parameterName, Reader reader) throws SQLException {
        wrappedCallableStatement.setNClob(parameterName, reader);
    }
    
}

PreparedStatementWrapper.java:

package redfin.util.jdbc;

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.NClob;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;

import redfin.util.stats.PerfStatsManager;

/**
* A wrapper for PreparedStatements generated by ConnectionWrapper. See comments in DriverWrapper.
*
*/
public class PreparedStatementWrapper implements PreparedStatement {
    
    private Connection parentConnection;
    private PreparedStatement wrappedPreparedStatement;
    
    public PreparedStatementWrapper(Connection parentConnection, PreparedStatement wrappedPreparedStatement) {
        this.parentConnection = parentConnection;
        this.wrappedPreparedStatement = wrappedPreparedStatement;
        
        if (PerfStatsManager.perfStatsEnabled()) {
            PerfStatsManager.getThreadLocalJDBCPerfStats().incrementNumStatements();
        }
    }
    
    // Semi-copied from http://www.java2s.com/Open-Source/Java-Document/Database-JDBC-Connection-Pool/mysql/com/mysql/jdbc/jdbc2/optional/JDBC4PreparedStatementWrapper.java.htm
    public T unwrap(Class iface) throws SQLException {
        try {
         if (    "java.sql.PreparedStatement".equals(iface.getName())
                 || "java.sql.Statement".equals(iface.getName())
         || "java.sql.Wrapper.class".equals(iface.getName())) {
         return iface.cast(this);
         }

            return wrappedPreparedStatement.unwrap(iface);
        } catch (ClassCastException cce) {
            throw new SQLException("Unable to unwrap to " + iface.toString(), cce);
        }
    }

    public boolean isWrapperFor(Class iface) throws SQLException {
     if (    "java.sql.PreparedStatement".equals(iface.getName())
             || "java.sql.Statement".equals(iface.getName())
     || "java.sql.Wrapper.class".equals(iface.getName())) {
            return true;
        }
        return wrappedPreparedStatement.isWrapperFor(iface);
    }

    public ResultSet executeQuery(String sql) throws SQLException {
        return new ResultSetWrapper(this, wrappedPreparedStatement.executeQuery(sql));
    }

    public int executeUpdate(String sql) throws SQLException {
        return wrappedPreparedStatement.executeUpdate(sql);
    }

    public void close() throws SQLException {
        wrappedPreparedStatement.close();
    }

    public int getMaxFieldSize() throws SQLException {
        return wrappedPreparedStatement.getMaxFieldSize();
    }

    public void setMaxFieldSize(int max) throws SQLException {
        wrappedPreparedStatement.setMaxFieldSize(max);
    }

    public int getMaxRows() throws SQLException {
        return wrappedPreparedStatement.getMaxRows();
    }

    public void setMaxRows(int max) throws SQLException {
        wrappedPreparedStatement.setMaxRows(max);
    }

    public void setEscapeProcessing(boolean enable) throws SQLException {
        wrappedPreparedStatement.setEscapeProcessing(enable);
    }

    public int getQueryTimeout() throws SQLException {
        return wrappedPreparedStatement.getQueryTimeout();
    }

    public void setQueryTimeout(int seconds) throws SQLException {
        wrappedPreparedStatement.setQueryTimeout(seconds);
    }

    public void cancel() throws SQLException {
        wrappedPreparedStatement.cancel();
    }

    public SQLWarning getWarnings() throws SQLException {
        return wrappedPreparedStatement.getWarnings();
    }

    public void clearWarnings() throws SQLException {
        wrappedPreparedStatement.clearWarnings();
    }

    public void setCursorName(String name) throws SQLException {
        wrappedPreparedStatement.setCursorName(name);
    }

    public boolean execute(String sql) throws SQLException {
        return wrappedPreparedStatement.execute(sql);
    }

    public ResultSet getResultSet() throws SQLException {
        return new ResultSetWrapper(this, wrappedPreparedStatement.getResultSet());
    }

    public int getUpdateCount() throws SQLException {
        return wrappedPreparedStatement.getUpdateCount();
    }

    public boolean getMoreResults() throws SQLException {
        return wrappedPreparedStatement.getMoreResults();
    }

    public void setFetchDirection(int direction) throws SQLException {
        wrappedPreparedStatement.setFetchDirection(direction);
    }

    public int getFetchDirection() throws SQLException {
        return wrappedPreparedStatement.getFetchDirection();
    }

    public void setFetchSize(int rows) throws SQLException {
        wrappedPreparedStatement.setFetchSize(rows);
    }

    public int getFetchSize() throws SQLException {
        return wrappedPreparedStatement.getFetchSize();
    }

    public int getResultSetConcurrency() throws SQLException {
        return wrappedPreparedStatement.getResultSetConcurrency();
    }

    public int getResultSetType() throws SQLException {
        return wrappedPreparedStatement.getResultSetType();
    }

    public void addBatch(String sql) throws SQLException {
        wrappedPreparedStatement.addBatch(sql);
    }

    public void clearBatch() throws SQLException {
        wrappedPreparedStatement.clearBatch();
    }

    public int[] executeBatch() throws SQLException {
        return wrappedPreparedStatement.executeBatch();
    }

    public Connection getConnection() throws SQLException {
        return parentConnection;
    }

    public boolean getMoreResults(int current) throws SQLException {
        return wrappedPreparedStatement.getMoreResults(current);
    }

    public ResultSet getGeneratedKeys() throws SQLException {
        return new ResultSetWrapper(this, wrappedPreparedStatement.getGeneratedKeys());
    }

    public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
        return wrappedPreparedStatement.executeUpdate(sql, autoGeneratedKeys);
    }

    public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
        return wrappedPreparedStatement.executeUpdate(sql, columnIndexes);
    }

    public int executeUpdate(String sql, String[] columnNames) throws SQLException {
        return wrappedPreparedStatement.executeUpdate(sql, columnNames);
    }

    public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
        return wrappedPreparedStatement.execute(sql, autoGeneratedKeys);
    }

    public boolean execute(String sql, int[] columnIndexes) throws SQLException {
        return wrappedPreparedStatement.execute(sql, columnIndexes);
    }

    public boolean execute(String sql, String[] columnNames) throws SQLException {
        return wrappedPreparedStatement.execute(sql, columnNames);
    }

    public int getResultSetHoldability() throws SQLException {
        return wrappedPreparedStatement.getResultSetHoldability();
    }

    public boolean isClosed() throws SQLException {
        return wrappedPreparedStatement.isClosed();
    }

    public void setPoolable(boolean poolable) throws SQLException {
        wrappedPreparedStatement.setPoolable(poolable);
    }

    public boolean isPoolable() throws SQLException {
        return wrappedPreparedStatement.isPoolable();
    }

    public ResultSet executeQuery() throws SQLException {
        return new ResultSetWrapper(this, wrappedPreparedStatement.executeQuery());
    }

    public int executeUpdate() throws SQLException {
        return wrappedPreparedStatement.executeUpdate();
    }

    public void setNull(int parameterIndex, int sqlType) throws SQLException {
        wrappedPreparedStatement.setNull(parameterIndex, sqlType);
    }

    public void setBoolean(int parameterIndex, boolean x) throws SQLException {
        wrappedPreparedStatement.setBoolean(parameterIndex, x);
    }

    public void setByte(int parameterIndex, byte x) throws SQLException {
        wrappedPreparedStatement.setByte(parameterIndex, x);
    }

    public void setShort(int parameterIndex, short x) throws SQLException {
        wrappedPreparedStatement.setShort(parameterIndex, x);
    }

    public void setInt(int parameterIndex, int x) throws SQLException {
        wrappedPreparedStatement.setInt(parameterIndex, x);
    }

    public void setLong(int parameterIndex, long x) throws SQLException {
        wrappedPreparedStatement.setLong(parameterIndex, x);
    }

    public void setFloat(int parameterIndex, float x) throws SQLException {
        wrappedPreparedStatement.setFloat(parameterIndex, x);
    }

    public void setDouble(int parameterIndex, double x) throws SQLException {
        wrappedPreparedStatement.setDouble(parameterIndex, x);
    }

    public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
        wrappedPreparedStatement.setBigDecimal(parameterIndex, x);
    }

    public void setString(int parameterIndex, String x) throws SQLException {
        wrappedPreparedStatement.setString(parameterIndex, x);
    }

    public void setBytes(int parameterIndex, byte[] x) throws SQLException {
        wrappedPreparedStatement.setBytes(parameterIndex, x);
    }

    public void setDate(int parameterIndex, Date x) throws SQLException {
        wrappedPreparedStatement.setDate(parameterIndex, x);
    }

    public void setTime(int parameterIndex, Time x) throws SQLException {
        wrappedPreparedStatement.setTime(parameterIndex, x);
    }

    public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
        wrappedPreparedStatement.setTimestamp(parameterIndex, x);
    }

    public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
        wrappedPreparedStatement.setAsciiStream(parameterIndex, x, length);
    }

    @SuppressWarnings("deprecation")
    public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
        wrappedPreparedStatement.setUnicodeStream(parameterIndex, x, length);
    }

    public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
        wrappedPreparedStatement.setBinaryStream(parameterIndex, x, length);
    }

    public void clearParameters() throws SQLException {
        wrappedPreparedStatement.clearParameters();
    }

    public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
        wrappedPreparedStatement.setObject(parameterIndex, x, targetSqlType);
    }

    public void setObject(int parameterIndex, Object x) throws SQLException {
        wrappedPreparedStatement.setObject(parameterIndex, x);
    }

    public boolean execute() throws SQLException {
        return wrappedPreparedStatement.execute();
    }

    public void addBatch() throws SQLException {
        wrappedPreparedStatement.addBatch();
    }

    public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
        wrappedPreparedStatement.setCharacterStream(parameterIndex, reader, length);
    }

    public void setRef(int parameterIndex, Ref x) throws SQLException {
        wrappedPreparedStatement.setRef(parameterIndex, x);
    }

    public void setBlob(int parameterIndex, Blob x) throws SQLException {
        wrappedPreparedStatement.setBlob(parameterIndex, x);
    }

    public void setClob(int parameterIndex, Clob x) throws SQLException {
        wrappedPreparedStatement.setClob(parameterIndex, x);
    }

    public void setArray(int parameterIndex, Array x) throws SQLException {
        wrappedPreparedStatement.setArray(parameterIndex, x);
    }

    public ResultSetMetaData getMetaData() throws SQLException {
        return wrappedPreparedStatement.getMetaData();
    }

    public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
        wrappedPreparedStatement.setDate(parameterIndex, x, cal);
    }

    public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
        wrappedPreparedStatement.setTime(parameterIndex, x, cal);
    }

    public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
        wrappedPreparedStatement.setTimestamp(parameterIndex, x, cal);
    }

    public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
        wrappedPreparedStatement.setNull(parameterIndex, sqlType, typeName);
    }

    public void setURL(int parameterIndex, URL x) throws SQLException {
        wrappedPreparedStatement.setURL(parameterIndex, x);
    }

    public ParameterMetaData getParameterMetaData() throws SQLException {
        return wrappedPreparedStatement.getParameterMetaData();
    }

    public void setRowId(int parameterIndex, RowId x) throws SQLException {
        wrappedPreparedStatement.setRowId(parameterIndex, x);
    }

    public void setNString(int parameterIndex, String value) throws SQLException {
        wrappedPreparedStatement.setNString(parameterIndex, value);
    }

    public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
        wrappedPreparedStatement.setNCharacterStream(parameterIndex, value, length);
    }

    public void setNClob(int parameterIndex, NClob value) throws SQLException {
        wrappedPreparedStatement.setNClob(parameterIndex, value);
    }

    public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
        wrappedPreparedStatement.setClob(parameterIndex, reader, length);
    }

    public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
        wrappedPreparedStatement.setBlob(parameterIndex, inputStream, length);
    }

    public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
        wrappedPreparedStatement.setNClob(parameterIndex, reader, length);
    }

    public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
        wrappedPreparedStatement.setSQLXML(parameterIndex, xmlObject);
    }

    public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
        wrappedPreparedStatement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
    }

    public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
        wrappedPreparedStatement.setAsciiStream(parameterIndex, x, length);
    }

    public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
        wrappedPreparedStatement.setBinaryStream(parameterIndex, x, length);
    }

    public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
        wrappedPreparedStatement.setCharacterStream(parameterIndex, reader, length);
    }

    public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
        wrappedPreparedStatement.setAsciiStream(parameterIndex, x);
    }

    public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
        wrappedPreparedStatement.setBinaryStream(parameterIndex, x);
    }

    public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
        wrappedPreparedStatement.setCharacterStream(parameterIndex, reader);
    }

    public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
        wrappedPreparedStatement.setNCharacterStream(parameterIndex, value);
    }

    public void setClob(int parameterIndex, Reader reader) throws SQLException {
        wrappedPreparedStatement.setClob(parameterIndex, reader);
    }

    public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
        wrappedPreparedStatement.setBlob(parameterIndex, inputStream);
    }

    public void setNClob(int parameterIndex, Reader reader) throws SQLException {
        wrappedPreparedStatement.setNClob(parameterIndex, reader);
    }
}

ResultSetWrapper.java:

package redfin.util.jdbc;

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.Date;
import java.sql.NClob;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Map;

/**
* A wrapper for ResultSets generated by ConnectionWrapper. See comments in DriverWrapper.
*
*/
public class ResultSetWrapper implements ResultSet {
    
    private Statement parentStatement;
    private ResultSet wrappedResultSet;
    
    public ResultSetWrapper(Statement parentStatement, ResultSet wrappedResultSet) {
        this.parentStatement = parentStatement;
        this.wrappedResultSet = wrappedResultSet;
    }
    
    // Semi-copied from http://www.java2s.com/Open-Source/Java-Document/Database-JDBC-Connection-Pool/mysql/com/mysql/jdbc/jdbc2/optional/JDBC4PreparedStatementWrapper.java.htm
    public T unwrap(Class iface) throws SQLException {
        try {
         if (    "java.sql.ResultSet".equals(iface.getName())
         || "java.sql.Wrapper.class".equals(iface.getName())) {
         return iface.cast(this);
         }

            return wrappedResultSet.unwrap(iface);
        } catch (ClassCastException cce) {
            throw new SQLException("Unable to unwrap to " + iface.toString(), cce);
        }
    }

    public boolean isWrapperFor(Class iface) throws SQLException {
     if (    "java.sql.ResultSet".equals(iface.getName())
     || "java.sql.Wrapper.class".equals(iface.getName())) {
            return true;
        }
        return wrappedResultSet.isWrapperFor(iface);
    }

    public boolean next() throws SQLException {
        return wrappedResultSet.next();
    }

    public void close() throws SQLException {
        wrappedResultSet.close();
        
    }

    public boolean wasNull() throws SQLException {
        return wrappedResultSet.wasNull();
    }

    public String getString(int columnIndex) throws SQLException {
        return wrappedResultSet.getString(columnIndex);
    }

    public boolean getBoolean(int columnIndex) throws SQLException {
        return wrappedResultSet.getBoolean(columnIndex);
    }

    public byte getByte(int columnIndex) throws SQLException {
        return wrappedResultSet.getByte(columnIndex);
    }

    public short getShort(int columnIndex) throws SQLException {
        return wrappedResultSet.getShort(columnIndex);
    }

    public int getInt(int columnIndex) throws SQLException {
        return wrappedResultSet.getInt(columnIndex);
    }

    public long getLong(int columnIndex) throws SQLException {
        return wrappedResultSet.getLong(columnIndex);
    }

    public float getFloat(int columnIndex) throws SQLException {
        return wrappedResultSet.getFloat(columnIndex);
    }

    public double getDouble(int columnIndex) throws SQLException {
        return wrappedResultSet.getDouble(columnIndex);
    }

    @SuppressWarnings("deprecation")
    public BigDecimal getBigDecimal(int columnIndex, int scale)
            throws SQLException {
        return wrappedResultSet.getBigDecimal(columnIndex, scale);
    }

    public byte[] getBytes(int columnIndex) throws SQLException {
        return wrappedResultSet.getBytes(columnIndex);
    }

    public Date getDate(int columnIndex) throws SQLException {
        return wrappedResultSet.getDate(columnIndex);
    }

    public Time getTime(int columnIndex) throws SQLException {
        return wrappedResultSet.getTime(columnIndex);
    }

    public Timestamp getTimestamp(int columnIndex) throws SQLException {
        return wrappedResultSet.getTimestamp(columnIndex);
    }

    public InputStream getAsciiStream(int columnIndex) throws SQLException {
        return wrappedResultSet.getAsciiStream(columnIndex);
    }

    @SuppressWarnings("deprecation")
    public InputStream getUnicodeStream(int columnIndex) throws SQLException {
        return wrappedResultSet.getUnicodeStream(columnIndex);
    }

    public InputStream getBinaryStream(int columnIndex) throws SQLException {
        return wrappedResultSet.getBinaryStream(columnIndex);
    }

    public String getString(String columnLabel) throws SQLException {
        return wrappedResultSet.getString(columnLabel);
    }

    public boolean getBoolean(String columnLabel) throws SQLException {
        return wrappedResultSet.getBoolean(columnLabel);
    }

    public byte getByte(String columnLabel) throws SQLException {
        return wrappedResultSet.getByte(columnLabel);
    }

    public short getShort(String columnLabel) throws SQLException {
        return wrappedResultSet.getShort(columnLabel);
    }

    public int getInt(String columnLabel) throws SQLException {
        return wrappedResultSet.getInt(columnLabel);
    }

    public long getLong(String columnLabel) throws SQLException {
        return wrappedResultSet.getLong(columnLabel);
    }

    public float getFloat(String columnLabel) throws SQLException {
        return wrappedResultSet.getFloat(columnLabel);
    }

    public double getDouble(String columnLabel) throws SQLException {
        return wrappedResultSet.getDouble(columnLabel);
    }

    @SuppressWarnings("deprecation")
    public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException {
        return wrappedResultSet.getBigDecimal(columnLabel, scale);
    }

    public byte[] getBytes(String columnLabel) throws SQLException {
        return wrappedResultSet.getBytes(columnLabel);
    }

    public Date getDate(String columnLabel) throws SQLException {
        return wrappedResultSet.getDate(columnLabel);
    }

    public Time getTime(String columnLabel) throws SQLException {
        return wrappedResultSet.getTime(columnLabel);
    }

    public Timestamp getTimestamp(String columnLabel) throws SQLException {
        return wrappedResultSet.getTimestamp(columnLabel);
    }

    public InputStream getAsciiStream(String columnLabel) throws SQLException {
        return wrappedResultSet.getAsciiStream(columnLabel);
    }

    @SuppressWarnings("deprecation")
    public InputStream getUnicodeStream(String columnLabel) throws SQLException {
        return wrappedResultSet.getUnicodeStream(columnLabel);
    }

    public InputStream getBinaryStream(String columnLabel) throws SQLException {
        return wrappedResultSet.getBinaryStream(columnLabel);
    }

    public SQLWarning getWarnings() throws SQLException {
        return wrappedResultSet.getWarnings();
    }

    public void clearWarnings() throws SQLException {
        wrappedResultSet.clearWarnings();
    }

    public String getCursorName() throws SQLException {
        return wrappedResultSet.getCursorName();
    }

    public ResultSetMetaData getMetaData() throws SQLException {
        return wrappedResultSet.getMetaData();
    }

    public Object getObject(int columnIndex) throws SQLException {
        return wrappedResultSet.getObject(columnIndex);
    }

    public Object getObject(String columnLabel) throws SQLException {
        return wrappedResultSet.getObject(columnLabel);
    }

    public int findColumn(String columnLabel) throws SQLException {
        return wrappedResultSet.findColumn(columnLabel);
    }

    public Reader getCharacterStream(int columnIndex) throws SQLException {
        return wrappedResultSet.getCharacterStream(columnIndex);
    }

    public Reader getCharacterStream(String columnLabel) throws SQLException {
        return wrappedResultSet.getCharacterStream(columnLabel);
    }

    public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
        return wrappedResultSet.getBigDecimal(columnIndex);
    }

    public BigDecimal getBigDecimal(String columnLabel) throws SQLException {
        return wrappedResultSet.getBigDecimal(columnLabel);
    }

    public boolean isBeforeFirst() throws SQLException {
        return wrappedResultSet.isBeforeFirst();
    }

    public boolean isAfterLast() throws SQLException {
        return wrappedResultSet.isAfterLast();
    }

    public boolean isFirst() throws SQLException {
        return wrappedResultSet.isFirst();
    }

    public boolean isLast() throws SQLException {
        return wrappedResultSet.isLast();
    }

    public void beforeFirst() throws SQLException {
        wrappedResultSet.beforeFirst();
    }

    public void afterLast() throws SQLException {
        wrappedResultSet.afterLast();
    }

    public boolean first() throws SQLException {
        return wrappedResultSet.first();
    }

    public boolean last() throws SQLException {
        return wrappedResultSet.last();
    }

    public int getRow() throws SQLException {
        return wrappedResultSet.getRow();
    }

    public boolean absolute(int row) throws SQLException {
        return wrappedResultSet.absolute(row);
    }

    public boolean relative(int rows) throws SQLException {
        return wrappedResultSet.relative(rows);
    }

    public boolean previous() throws SQLException {
        return wrappedResultSet.previous();
    }

    public void setFetchDirection(int direction) throws SQLException {
        wrappedResultSet.setFetchDirection(direction);
    }

    public int getFetchDirection() throws SQLException {
        return wrappedResultSet.getFetchDirection();
    }

    public void setFetchSize(int rows) throws SQLException {
        wrappedResultSet.setFetchSize(rows);
    }

    public int getFetchSize() throws SQLException {
        return wrappedResultSet.getFetchSize();
    }

    public int getType() throws SQLException {
        return wrappedResultSet.getType();
    }

    public int getConcurrency() throws SQLException {
        return wrappedResultSet.getConcurrency();
    }

    public boolean rowUpdated() throws SQLException {
        return wrappedResultSet.rowUpdated();
    }

    public boolean rowInserted() throws SQLException {
        return wrappedResultSet.rowInserted();
    }

    public boolean rowDeleted() throws SQLException {
        return wrappedResultSet.rowDeleted();
    }

    public void updateNull(int columnIndex) throws SQLException {
        wrappedResultSet.updateNull(columnIndex);
    }

    public void updateBoolean(int columnIndex, boolean x) throws SQLException {
        wrappedResultSet.updateBoolean(columnIndex, x);
    }

    public void updateByte(int columnIndex, byte x) throws SQLException {
        wrappedResultSet.updateByte(columnIndex, x);
    }

    public void updateShort(int columnIndex, short x) throws SQLException {
        wrappedResultSet.updateShort(columnIndex, x);
    }

    public void updateInt(int columnIndex, int x) throws SQLException {
        wrappedResultSet.updateInt(columnIndex, x);
    }

    public void updateLong(int columnIndex, long x) throws SQLException {
        wrappedResultSet.updateLong(columnIndex, x);
    }

    public void updateFloat(int columnIndex, float x) throws SQLException {
        wrappedResultSet.updateFloat(columnIndex, x);
    }

    public void updateDouble(int columnIndex, double x) throws SQLException {
        wrappedResultSet.updateDouble(columnIndex, x);
    }

    public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
        wrappedResultSet.updateBigDecimal(columnIndex, x);
    }

    public void updateString(int columnIndex, String x) throws SQLException {
        wrappedResultSet.updateString(columnIndex, x);
    }

    public void updateBytes(int columnIndex, byte[] x) throws SQLException {
        wrappedResultSet.updateBytes(columnIndex, x);
    }

    public void updateDate(int columnIndex, Date x) throws SQLException {
        wrappedResultSet.updateDate(columnIndex, x);
    }

    public void updateTime(int columnIndex, Time x) throws SQLException {
        wrappedResultSet.updateTime(columnIndex, x);
    }

    public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
        wrappedResultSet.updateTimestamp(columnIndex, x);
    }

    public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
        wrappedResultSet.updateAsciiStream(columnIndex, x);
    }

    public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
        wrappedResultSet.updateBinaryStream(columnIndex, x);
    }

    public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
        wrappedResultSet.updateCharacterStream(columnIndex, x);
    }

    public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException {
        wrappedResultSet.updateObject(columnIndex, x);
    }

    public void updateObject(int columnIndex, Object x) throws SQLException {
        wrappedResultSet.updateObject(columnIndex, x);
    }

    public void updateNull(String columnLabel) throws SQLException {
        wrappedResultSet.updateNull(columnLabel);
    }

    public void updateBoolean(String columnLabel, boolean x) throws SQLException {
        wrappedResultSet.updateBoolean(columnLabel, x);
    }

    public void updateByte(String columnLabel, byte x) throws SQLException {
        wrappedResultSet.updateByte(columnLabel, x);
    }

    public void updateShort(String columnLabel, short x) throws SQLException {
        wrappedResultSet.updateShort(columnLabel, x);
    }

    public void updateInt(String columnLabel, int x) throws SQLException {
        wrappedResultSet.updateInt(columnLabel, x);
    }

    public void updateLong(String columnLabel, long x) throws SQLException {
        wrappedResultSet.updateLong(columnLabel, x);
    }

    public void updateFloat(String columnLabel, float x) throws SQLException {
        wrappedResultSet.updateFloat(columnLabel, x);
    }

    public void updateDouble(String columnLabel, double x) throws SQLException {
        wrappedResultSet.updateDouble(columnLabel, x);
    }

    public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException {
        wrappedResultSet.updateBigDecimal(columnLabel, x);
    }

    public void updateString(String columnLabel, String x) throws SQLException {
        wrappedResultSet.updateString(columnLabel, x);
    }

    public void updateBytes(String columnLabel, byte[] x) throws SQLException {
        wrappedResultSet.updateBytes(columnLabel, x);
    }

    public void updateDate(String columnLabel, Date x) throws SQLException {
        wrappedResultSet.updateDate(columnLabel, x);
    }

    public void updateTime(String columnLabel, Time x) throws SQLException {
        wrappedResultSet.updateTime(columnLabel, x);
    }

    public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException {
        wrappedResultSet.updateTimestamp(columnLabel, x);
    }

    public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException {
        wrappedResultSet.updateAsciiStream(columnLabel, x);
    }

    public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException {
        wrappedResultSet.updateBinaryStream(columnLabel, x);
    }

    public void updateCharacterStream(String columnLabel, Reader reader,
            int length) throws SQLException {
        wrappedResultSet.updateCharacterStream(columnLabel, reader, length);
    }

    public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException {
        wrappedResultSet.updateObject(columnLabel, x);
    }

    public void updateObject(String columnLabel, Object x) throws SQLException {
        wrappedResultSet.updateObject(columnLabel, x);
    }

    public void insertRow() throws SQLException {
        wrappedResultSet.insertRow();
    }

    public void updateRow() throws SQLException {
        wrappedResultSet.updateRow();
    }

    public void deleteRow() throws SQLException {
        wrappedResultSet.deleteRow();
    }

    public void refreshRow() throws SQLException {
        wrappedResultSet.refreshRow();
    }

    public void cancelRowUpdates() throws SQLException {
        wrappedResultSet.cancelRowUpdates();
    }

    public void moveToInsertRow() throws SQLException {
        wrappedResultSet.moveToInsertRow();
    }

    public void moveToCurrentRow() throws SQLException {
        wrappedResultSet.moveToCurrentRow();
    }

    public Statement getStatement() throws SQLException {
        return parentStatement;
    }

    public Object getObject(int columnIndex, Map<String, Class> map) throws SQLException {
        return wrappedResultSet.getObject(columnIndex, map);
    }

    public Ref getRef(int columnIndex) throws SQLException {
        return wrappedResultSet.getRef(columnIndex);
    }

    public Blob getBlob(int columnIndex) throws SQLException {
        return wrappedResultSet.getBlob(columnIndex);
    }

    public Clob getClob(int columnIndex) throws SQLException {
        return wrappedResultSet.getClob(columnIndex);
    }

    public Array getArray(int columnIndex) throws SQLException {
        return wrappedResultSet.getArray(columnIndex);
    }

    public Object getObject(String columnLabel, Map<String, Class> map)
            throws SQLException {
        return wrappedResultSet.getObject(columnLabel, map);
    }

    public Ref getRef(String columnLabel) throws SQLException {
        return wrappedResultSet.getRef(columnLabel);
    }

    public Blob getBlob(String columnLabel) throws SQLException {
        return wrappedResultSet.getBlob(columnLabel);
    }

    public Clob getClob(String columnLabel) throws SQLException {
        return wrappedResultSet.getClob(columnLabel);
    }

    public Array getArray(String columnLabel) throws SQLException {
        return wrappedResultSet.getArray(columnLabel);
    }

    public Date getDate(int columnIndex, Calendar cal) throws SQLException {
        return wrappedResultSet.getDate(columnIndex, cal);
    }

    public Date getDate(String columnLabel, Calendar cal) throws SQLException {
        return wrappedResultSet.getDate(columnLabel, cal);
    }

    public Time getTime(int columnIndex, Calendar cal) throws SQLException {
        return wrappedResultSet.getTime(columnIndex, cal);
    }

    public Time getTime(String columnLabel, Calendar cal) throws SQLException {
        return wrappedResultSet.getTime(columnLabel, cal);
    }

    public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
        return wrappedResultSet.getTimestamp(columnIndex, cal);
    }

    public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException {
        return wrappedResultSet.getTimestamp(columnLabel, cal);
    }

    public URL getURL(int columnIndex) throws SQLException {
        return wrappedResultSet.getURL(columnIndex);
    }

    public URL getURL(String columnLabel) throws SQLException {
        return wrappedResultSet.getURL(columnLabel);
    }

    public void updateRef(int columnIndex, Ref x) throws SQLException {
        wrappedResultSet.updateRef(columnIndex, x);
    }

    public void updateRef(String columnLabel, Ref x) throws SQLException {
        wrappedResultSet.updateRef(columnLabel, x);
    }

    public void updateBlob(int columnIndex, Blob x) throws SQLException {
        wrappedResultSet.updateBlob(columnIndex, x);
    }

    public void updateBlob(String columnLabel, Blob x) throws SQLException {
        wrappedResultSet.updateBlob(columnLabel, x);
    }

    public void updateClob(int columnIndex, Clob x) throws SQLException {
        wrappedResultSet.updateClob(columnIndex, x);
    }

    public void updateClob(String columnLabel, Clob x) throws SQLException {
        wrappedResultSet.updateClob(columnLabel, x);
    }

    public void updateArray(int columnIndex, Array x) throws SQLException {
        wrappedResultSet.updateArray(columnIndex, x);
    }

    public void updateArray(String columnLabel, Array x) throws SQLException {
        wrappedResultSet.updateArray(columnLabel, x);
    }

    public RowId getRowId(int columnIndex) throws SQLException {
        return wrappedResultSet.getRowId(columnIndex);
    }

    public RowId getRowId(String columnLabel) throws SQLException {
        return wrappedResultSet.getRowId(columnLabel);
    }

    public void updateRowId(int columnIndex, RowId x) throws SQLException {
        wrappedResultSet.updateRowId(columnIndex, x);
    }

    public void updateRowId(String columnLabel, RowId x) throws SQLException {
        wrappedResultSet.updateRowId(columnLabel, x);
    }

    public int getHoldability() throws SQLException {
        return wrappedResultSet.getHoldability();
    }

    public boolean isClosed() throws SQLException {
        return wrappedResultSet.isClosed();
    }

    public void updateNString(int columnIndex, String nString) throws SQLException {
        wrappedResultSet.updateNString(columnIndex, nString);
    }

    public void updateNString(String columnLabel, String nString) throws SQLException {
        wrappedResultSet.updateNString(columnLabel, nString);
    }

    public void updateNClob(int columnIndex, NClob nClob) throws SQLException {
        wrappedResultSet.updateNClob(columnIndex, nClob);
    }

    public void updateNClob(String columnLabel, NClob nClob) throws SQLException {
        wrappedResultSet.updateNClob(columnLabel, nClob);
    }

    public NClob getNClob(int columnIndex) throws SQLException {
        return wrappedResultSet.getNClob(columnIndex);
    }

    public NClob getNClob(String columnLabel) throws SQLException {
        return wrappedResultSet.getNClob(columnLabel);
    }

    public SQLXML getSQLXML(int columnIndex) throws SQLException {
        return wrappedResultSet.getSQLXML(columnIndex);
    }

    public SQLXML getSQLXML(String columnLabel) throws SQLException {
        return wrappedResultSet.getSQLXML(columnLabel);
    }

    public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {
        wrappedResultSet.updateSQLXML(columnIndex, xmlObject);
    }

    public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {
        wrappedResultSet.updateSQLXML(columnLabel, xmlObject);
    }

    public String getNString(int columnIndex) throws SQLException {
        return wrappedResultSet.getNString(columnIndex);
    }

    public String getNString(String columnLabel) throws SQLException {
        return wrappedResultSet.getNString(columnLabel);
    }

    public Reader getNCharacterStream(int columnIndex) throws SQLException {
        return wrappedResultSet.getNCharacterStream(columnIndex);
    }

    public Reader getNCharacterStream(String columnLabel) throws SQLException {
        return wrappedResultSet.getNCharacterStream(columnLabel);
    }

    public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
        wrappedResultSet.updateNCharacterStream(columnIndex, x, length);
    }

    public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
        wrappedResultSet.updateNCharacterStream(columnLabel, reader, length);
    }

    public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException {
        wrappedResultSet.updateAsciiStream(columnIndex, x, length);
    }

    public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
        wrappedResultSet.updateBinaryStream(columnIndex, x, length);
    }

    public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
        wrappedResultSet.updateCharacterStream(columnIndex, x, length);
    }

    public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException {
        wrappedResultSet.updateAsciiStream(columnLabel, x, length);
    }

    public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException {
        wrappedResultSet.updateBinaryStream(columnLabel, x, length);
    }

    public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
        wrappedResultSet.updateCharacterStream(columnLabel, reader, length);
    }

    public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException {
        wrappedResultSet.updateBlob(columnIndex, inputStream, length);
    }

    public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {
        wrappedResultSet.updateBlob(columnLabel, inputStream, length);
    }

    public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
        wrappedResultSet.updateClob(columnIndex, reader, length);
    }

    public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
        wrappedResultSet.updateClob(columnLabel, reader, length);
    }

    public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
        wrappedResultSet.updateNClob(columnIndex, reader, length);
    }

    public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
        wrappedResultSet.updateNClob(columnLabel, reader, length);
    }

    public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {
        wrappedResultSet.updateNCharacterStream(columnIndex, x);
    }

    public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
        wrappedResultSet.updateNCharacterStream(columnLabel, reader);
    }

    public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
        wrappedResultSet.updateAsciiStream(columnIndex, x);
    }

    public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {
        wrappedResultSet.updateBinaryStream(columnIndex, x);
    }

    public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {
        wrappedResultSet.updateCharacterStream(columnIndex, x);
    }

    public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException {
        wrappedResultSet.updateAsciiStream(columnLabel, x);
    }

    public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException {
        wrappedResultSet.updateBinaryStream(columnLabel, x);
    }

    public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
        wrappedResultSet.updateCharacterStream(columnLabel, reader);
    }

    public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
        wrappedResultSet.updateBlob(columnIndex, inputStream);
    }

    public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
        wrappedResultSet.updateBlob(columnLabel, inputStream);
    }

    public void updateClob(int columnIndex, Reader reader) throws SQLException {
        wrappedResultSet.updateClob(columnIndex, reader);
    }

    public void updateClob(String columnLabel, Reader reader) throws SQLException {
        wrappedResultSet.updateClob(columnLabel, reader);
    }

    public void updateNClob(int columnIndex, Reader reader) throws SQLException {
        wrappedResultSet.updateNClob(columnIndex, reader);
    }

    public void updateNClob(String columnLabel, Reader reader) throws SQLException {
        wrappedResultSet.updateNClob(columnLabel, reader);
    }
}

Discussion

  • http://www.cbcommercial.com.vn vietnam real estate

    thanks for sharing this, very interesting, though a bit too long…

  • Eelco

    Maybe github next time? Thanks for sharing though