/**
* Alipay.com Inc.
* Copyright (c) 2004-2012 All Rights Reserved.
*/
package com.alipay.zdal.datasource.resource.adapter.jdbc;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.alipay.zdal.datasource.ZDataSource;
/**
* A wrapper for a statement.
*
* @todo remove the org.jboss.ejb.plugins.cmp.jdbc.WrappedStatement dependency
*
* @author ����
* @version $Id: WrappedStatement.java, v 0.1 2014-1-6 ����05:31:18 Exp $
*/
public class WrappedStatement implements Statement, StatementAccess {
private final WrappedConnection lc;
private final Statement s;
protected String dataSourceName = "";
/** The result sets */
private HashMap resultSets;
/** Whether we are closed */
private boolean closed = false;
/** The state lock */
private final Object lock = new Object();
/** ���ÿ����Ĕ���Դ*/
protected ZDataSource zdatasource = null;
public ZDataSource getZdatasource() {
return zdatasource;
}
public void setZdatasource(ZDataSource zdatasource) {
this.zdatasource = zdatasource;
}
/**
* @param lc
* @param s
* @param zdatasource
*/
public WrappedStatement(final WrappedConnection lc, Statement s, ZDataSource zdatasource) {
this.lc = lc;
this.s = s;
this.zdatasource = zdatasource;
lc.registerStatement(this);
}
/**
* @param lc
* @param s
* @param dataSourceName
* @param zdatasource
*/
public WrappedStatement(final WrappedConnection lc, Statement s, String dataSourceName,
ZDataSource zdatasource) {
this.lc = lc;
this.s = s;
this.dataSourceName = dataSourceName;
this.zdatasource = zdatasource;
lc.registerStatement(this);
}
public void close() throws SQLException {
synchronized (lock) {
if (closed) {
return;
}
closed = true;
}
lc.unregisterStatement(this);
internalClose();
}
/**
* @see java.sql.Statement#execute(java.lang.String)
*/
public boolean execute(String sql) throws SQLException {
return this.executeInternal(sql, -1, null, null);
}
/**
* @see java.sql.Statement#execute(java.lang.String, int)
*/
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
return this.executeInternal(sql, autoGeneratedKeys, null, null);
}
/**
* @see java.sql.Statement#execute(java.lang.String, int[])
*/
public boolean execute(String sql, int[] columnIndexes) throws SQLException {
return this.executeInternal(sql, -1, columnIndexes, null);
}
/**
* @see java.sql.Statement#execute(java.lang.String, java.lang.String[])
*/
public boolean execute(String sql, String[] columnNames) throws SQLException {
return this.executeInternal(sql, -1, null, columnNames);
}
/**
*
* @param sql
* @param autoGeneratedKeys
* @param columnIndexes
* @param columnNames
* @return
* @throws SQLException
*/
private boolean executeInternal(String sql, int autoGeneratedKeys, int[] columnIndexes,
String[] columnNames) throws SQLException {
checkTransaction();
try {
checkConfiguredQueryTimeout();
if (autoGeneratedKeys == -1 && columnIndexes == null && columnNames == null) {
return s.execute(sql);
} else if (autoGeneratedKeys != -1) {
return s.execute(sql, autoGeneratedKeys);
} else if (columnIndexes != null) {
return s.execute(sql, columnIndexes);
} else {
return s.execute(sql, columnNames);
}
} catch (Throwable t) {
throw checkException(t);
} finally {
}
}
public Connection getConnection() throws SQLException {
return lc;
}
public SQLWarning getWarnings() throws SQLException {
checkState();
try {
return s.getWarnings();
} catch (Throwable t) {
throw checkException(t);
}
}
public void clearWarnings() throws SQLException {
checkState();
try {
s.clearWarnings();
} catch (Throwable t) {
throw checkException(t);
}
}
/**
* @see java.sql.Statement#executeQuery(java.lang.String)
*/
public ResultSet executeQuery(String sql) throws SQLException {
checkTransaction();
try {
checkConfiguredQueryTimeout();
ResultSet result = s.executeQuery(sql);
return registerResultSet(result);
} catch (Throwable t) {
throw checkException(t);
} finally {
}
}
/**
* @see java.sql.Statement#executeUpdate(java.lang.String)
*/
public int executeUpdate(String sql) throws SQLException {
return this.executeUpdateInternal(sql, -1, null, null);
}
/**
* @see java.sql.Statement#executeUpdate(java.lang.String, int)
*/
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
return this.executeUpdateInternal(sql, autoGeneratedKeys, null, null);
}
/**
* @see java.sql.Statement#executeUpdate(java.lang.String, int[])
*/
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
return this.executeUpdateInternal(sql, -1, columnIndexes, null);
}
/**
* @see java.sql.Statement#executeUpdate(java.lang.String, java.lang.String[])
*/
public int executeUpdate(String sql, String[] columnNames) throws SQLException {
return this.executeUpdateInternal(sql, -1, null, columnNames);
}
/**
*
* @param sql
* @param autoGeneratedKeys
* @param columnIndexes
* @param columnNames
* @return
* @throws SQLException
*/
private int executeUpdateInternal(String sql, int autoGeneratedKeys, int[] columnIndexes,
String[] columnNames) throws SQLException {
checkTransaction();
try {
checkConfiguredQueryTimeout();
if (autoGeneratedKeys == -1 && columnIndexes == null && columnNames == null) {
return s.executeUpdate(sql);
} else if (autoGeneratedKeys != -1) {
return s.executeUpdate(sql, autoGeneratedKeys);
} else if (columnIndexes != null) {
return s.executeUpdate(sql, columnIndexes);
} else {
return s.executeUpdate(sql, columnNames);
}
} catch (Throwable t) {
throw checkException(t);
} finally {
}
}
public int getMaxFieldSize() throws SQLException {
checkState();
try {
return s.getMaxFieldSize();
} catch (Throwable t) {
throw checkException(t);
}
}
public void setMaxFieldSize(int max) throws SQLException {
checkState();
try {
s.setMaxFieldSize(max);
} catch (Throwable t) {
throw checkException(t);
}
}
public int getMaxRows() throws SQLException {
checkState();
try {
return s.getMaxRows();
} catch (Throwable t) {
throw checkException(t);
}
}
public void setMaxRows(int max) throws SQLException {
checkState();
try {
s.setMaxRows(max);
} catch (Throwable t) {
throw checkException(t);
}
}
public void setEscapeProcessing(boolean enable) throws SQLException {
checkState();
try {
s.setEscapeProcessing(enable);
} catch (Throwable t) {
throw checkException(t);
}
}
public int getQueryTimeout() throws SQLException {
checkState();
try {
return s.getQueryTimeout();
} catch (Throwable t) {
throw checkException(t);
}
}
public void setQueryTimeout(int timeout) throws SQLException {
checkState();
try {
s.setQueryTimeout(timeout);
} catch (Throwable t) {
throw checkException(t);
}
}
public void cancel() throws SQLException {
checkState();
try {
s.cancel();
} catch (Throwable t) {
throw checkException(t);
}
}
public void setCursorName(String name) throws SQLException {
checkState();
try {
s.setCursorName(name);
} catch (Throwable t) {
throw checkException(t);
}
}
public ResultSet getResultSet() throws SQLException {
checkState();
try {
ResultSet result = s.getResultSet();
if (result == null) {
return null;
} else {
return registerResultSet(result);
}
} catch (Throwable t) {
throw checkException(t);
}
}
public int getUpdateCount() throws SQLException {
checkState();
try {
return s.getUpdateCount();
} catch (Throwable t) {
throw checkException(t);
}
}
public boolean getMoreResults() throws SQLException {
checkState();
try {
return s.getMoreResults();
} catch (Throwable t) {
throw checkException(t);
}
}
public boolean getMoreResults(int current) throws SQLException {
checkState();
try {
return s.getMoreResults(current);
} catch (Throwable t) {
throw checkException(t);
}
}
public void setFetchDirection(int direction) throws SQLException {
checkState();
try {
s.setFetchDirection(direction);
} catch (Throwable t) {
throw checkException(t);
}
}
public int getFetchDirection() throws SQLException {
checkState();
try {
return s.getFetchDirection();
} catch (Throwable t) {
throw checkException(t);
}
}
public void setFetchSize(int rows) throws SQLException {
checkState();
try {
s.setFetchSize(rows);
} catch (Throwable t) {
throw checkException(t);
}
}
public int getFetchSize() throws SQLException {
checkState();
try {
return s.getFetchSize();
} catch (Throwable t) {
throw checkException(t);
}
}
public int getResultSetConcurrency() throws SQLException {
checkState();
try {
return s.getResultSetConcurrency();
} catch (Throwable t) {
throw checkException(t);
}
}
public int getResultSetType() throws SQLException {
checkState();
try {
return s.getResultSetType();
} catch (Throwable t) {
throw checkException(t);
}
}
/**
* @see java.sql.Statement#addBatch(java.lang.String)
*/
public void addBatch(String sql) throws SQLException {
// doSqlValve(sql);
checkState();
try {
s.addBatch(sql);
} catch (Throwable t) {
throw checkException(t);
} finally {
}
}
/**
* @see java.sql.Statement#clearBatch()
*/
public void clearBatch() throws SQLException {
checkState();
try {
s.clearBatch();
} catch (Throwable t) {
throw checkException(t);
}
}
/**
* @see java.sql.Statement#executeBatch()
*/
public int[] executeBatch() throws SQLException {
checkState();
try {
checkConfiguredQueryTimeout();
return s.executeBatch();
} catch (Throwable t) {
throw checkException(t);
}
}
public ResultSet getGeneratedKeys() throws SQLException {
checkState();
try {
ResultSet resultSet = s.getGeneratedKeys();
return registerResultSet(resultSet);
} catch (Throwable t) {
throw checkException(t);
}
}
public int getResultSetHoldability() throws SQLException {
checkState();
try {
return s.getResultSetHoldability();
} catch (Throwable t) {
throw checkException(t);
}
}
public Statement getUnderlyingStatement() throws SQLException {
checkState();
return s;
}
protected SQLException checkException(Throwable t) throws SQLException {
throw lc.checkException(t);
}
protected void checkTransaction() throws SQLException {
checkState();
lc.checkTransaction();
}
protected void checkConfiguredQueryTimeout() throws SQLException {
lc.checkConfiguredQueryTimeout(this);
}
protected void internalClose() throws SQLException {
synchronized (lock) {
closed = true;
}
try {
closeResultSets();
} finally {
s.close();
}
}
/**
*
* @throws SQLException
*/
void checkState() throws SQLException {
synchronized (lock) {
if (closed) {
throw new SQLException("The statement is closed.");
}
}
}
/**
*
* @param resultSet
* @return
*/
protected ResultSet registerResultSet(ResultSet resultSet) {
if (resultSet != null) {
resultSet = new WrappedResultSet(this, resultSet);
}
if (lc.getTrackStatements() == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_FALSE_INT) {
return resultSet;
}
synchronized (this) {
if (resultSets == null) {
resultSets = new HashMap();
}
if (lc.getTrackStatements() == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_TRUE_INT) {
resultSets.put(resultSet, new Throwable("STACKTRACE"));
} else {
resultSets.put(resultSet, null);
}
}
return resultSet;
}
/**
*
* @param resultSet
*/
protected void unregisterResultSet(WrappedResultSet resultSet) {
if (lc.getTrackStatements() == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_FALSE_INT) {
return;
}
synchronized (this) {
if (resultSets != null) {
resultSets.remove(resultSet);
}
}
}
/**
*
*/
protected void closeResultSets() {
if (lc.getTrackStatements() == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_FALSE_INT) {
return;
}
synchronized (this) {
if (resultSets == null) {
return;
}
for (Iterator i = resultSets.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
WrappedResultSet resultSet = (WrappedResultSet) entry.getKey();
if (lc.getTrackStatements() == BaseWrapperManagedConnectionFactory.TRACK_STATEMENTS_TRUE_INT) {
Throwable stackTrace = (Throwable) entry.getValue();
lc.getLogger()
.warn("Closing a result set you left open! Please close it yourself.",
stackTrace);
}
try {
resultSet.internalClose();
} catch (Throwable t) {
lc.getLogger().warn(
"Error closing a result set you left open! Please close it yourself.", t);
}
}
resultSets.clear();
}
}
// jdk 6
public boolean isClosed() throws SQLException {
return closed;
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return iface.isInstance(s);
}
public <T> T unwrap(Class<T> iface) throws SQLException {
return (T) (iface.isInstance(s) ? s : null);
}
public boolean isPoolable() throws SQLException {
return false;
}
public void setPoolable(boolean poolable) throws SQLException {
}
protected String getDataSourceName() {
return dataSourceName;
}
protected void setDataSourceName(String dataSourceName) {
this.dataSourceName = dataSourceName;
}
}