package com.taobao.tddl.matrix.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.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.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import com.taobao.tddl.common.jdbc.ParameterContext;
import com.taobao.tddl.common.jdbc.ParameterMethod;
import com.taobao.tddl.common.model.SqlType;
import com.taobao.tddl.executor.common.ExecutionContext;
import com.taobao.tddl.matrix.jdbc.utils.PreParser;
import com.taobao.tddl.common.utils.logger.Logger;
import com.taobao.tddl.common.utils.logger.LoggerFactory;
/**
* @author mengshi.sunmengshi 2013-11-22 下午3:26:18
* @since 5.0.0
*/
public class TPreparedStatement extends TStatement implements PreparedStatement {
private static final Logger log = LoggerFactory.getLogger(TPreparedStatement.class);
// 参数列表到参数上下文的映射 如 1:name 2:'2011-11-11'
protected Map<Integer, ParameterContext> parameterSettings = new HashMap<Integer, ParameterContext>();
public TPreparedStatement(TDataSource ds, TConnection conn, String sql, ExecutionContext ec){
super(ds, conn, sql, ec);
}
@Override
public ResultSet executeQuery() throws SQLException {
checkClosed();
ensureResultSetIsEmpty();
this.currentResultSet = this.conn.executeSQL(sql, parameterSettings, this, extraCmd, this.executionContext);
return currentResultSet;
}
@Override
public int executeUpdate() throws SQLException {
checkClosed();
ensureResultSetIsEmpty();
this.currentResultSet = this.conn.executeSQL(sql, parameterSettings, this, extraCmd, this.executionContext);
int affectRows = ((TResultSet) this.currentResultSet).getAffectRows();
this.currentResultSet.close();
return affectRows;
}
// jdbc规范: 返回true表示executeQuery,false表示executeUpdate
@Override
public boolean execute() throws SQLException {
if (log.isDebugEnabled()) {
log.debug("invoke execute, sql = " + sql);
}
SqlType sqlType = PreParser.getSqlType(sql);
if (sqlType == SqlType.SELECT || sqlType == SqlType.SELECT_FOR_UPDATE
/**
* show 不支持吗 || sqlType == SqlType.SHOW
**/
) {
executeQuery();
return true;
} else if (sqlType == SqlType.INSERT || sqlType == SqlType.UPDATE || sqlType == SqlType.DELETE
|| sqlType == SqlType.REPLACE || sqlType == SqlType.TRUNCATE || sqlType == SqlType.CREATE
|| sqlType == SqlType.DROP || sqlType == SqlType.LOAD || sqlType == SqlType.MERGE) {
super.updateCount = executeUpdate();
return false;
} else {
throw new SQLException("only select, insert, update, delete,truncate,create,drop,load,merge sql is supported");
}
}
@Override
public void setShort(int parameterIndex, short x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setShort, new Object[] {
parameterIndex, x }));
}
// 数据库从0开始,jdbc规范从1开始,jdbc到数据库要减一
@Override
public void setInt(int parameterIndex, int x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setInt, new Object[] {
parameterIndex, x }));
}
@Override
public void setLong(int parameterIndex, long x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setLong, new Object[] {
parameterIndex, x }));
}
@Override
public void setBoolean(int parameterIndex, boolean x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setBoolean, new Object[] {
parameterIndex, x }));
}
@Override
public void setString(int parameterIndex, String x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setString, new Object[] {
parameterIndex, x }));
}
@Override
public void setFloat(int parameterIndex, float x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setFloat, new Object[] {
parameterIndex, x }));
}
@Override
public void setDouble(int parameterIndex, double x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setDouble, new Object[] {
parameterIndex, x }));
}
@Override
public void setBytes(int parameterIndex, byte[] x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setBytes, new Object[] {
parameterIndex, x }));
}
// 这里ustore底层将date按long存储
@Override
public void setDate(int parameterIndex, Date x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setDate1, new Object[] {
parameterIndex, x }));
}
@Override
public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
parameterSettings.put(parameterIndex - 1, new ParameterContext(ParameterMethod.setDate2, new Object[] {
parameterIndex, x, cal }));
}
@Override
public void clearParameters() throws SQLException {
this.parameterSettings.clear();
}
public void setNull(int parameterIndex, Object o) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setNull1, new Object[] {
parameterIndex, null }));
}
@Override
public void setNull(int parameterIndex, int sqlType) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setNull1, new Object[] {
parameterIndex, null }));
}
@Override
public void setByte(int parameterIndex, byte x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setByte, new Object[] {
parameterIndex, x }));
}
@Override
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setBigDecimal, new Object[] {
parameterIndex, x }));
}
@Override
public void setTime(int parameterIndex, Time x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setTime1, new Object[] {
parameterIndex, x }));
}
@Override
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setTimestamp1, new Object[] {
parameterIndex, x }));
}
@Override
public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
parameterSettings.put(parameterIndex - 1, new ParameterContext(ParameterMethod.setAsciiStream, new Object[] {
parameterIndex, x, length }));
}
@Override
public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
parameterSettings.put(parameterIndex - 1, new ParameterContext(ParameterMethod.setUnicodeStream, new Object[] {
parameterIndex, x, length }));
}
@Override
public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
parameterSettings.put(parameterIndex - 1, new ParameterContext(ParameterMethod.setBinaryStream, new Object[] {
parameterIndex, x, length }));
}
@Override
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setObject3, new Object[] {
parameterIndex, x, targetSqlType }));
}
@Override
public void setObject(int parameterIndex, Object x) throws SQLException {
// /*
// * 对于int long之类的类型,使用反射去调用其专属的setter,其他的加if判断,暂不支持
// */
// if (x instanceof java.util.Date)
// x = new Date(((java.util.Date) x).getTime());
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setObject1, new Object[] {
parameterIndex, x }));
// if (x == null) {
// setNull(parameterIndex -1, x);
// } else if (x instanceof Integer) {
// setInt(parameterIndex -1, (Integer) x);
// } else if (x instanceof Long) {
// setLong(parameterIndex -1, (Long) x);
// } else if (x instanceof String) {
// setString(parameterIndex -1, (String) x);
// } else if (x instanceof Boolean) {
// setBoolean(parameterIndex -1, (Boolean) x);
// } else if (x instanceof Float) {
// setFloat(parameterIndex -1, (Float) x);
// } else if (x instanceof Double) {
// setDouble(parameterIndex -1, (Double) x);
// } else if (x instanceof byte[]) {
// setBytes(parameterIndex -1, (byte[]) x);
// } else if (x instanceof Date) {
// setDate(parameterIndex -1, (Date) x);
// } else if (x instanceof java.util.Date) {
// setDate(parameterIndex -1,new Date(((java.util.Date)x).getTime()));
// }else
// {
// throw new
// UnsupportedOperationException("the type of "+x+" is not supported by prepare statement , index is "+parameterIndex);
// }
}
@Override
public void addBatch() throws SQLException {
throw new UnsupportedOperationException();
}
@Override
public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
parameterSettings.put(parameterIndex - 1, new ParameterContext(ParameterMethod.setCharacterStream,
new Object[] { parameterIndex, reader, length }));
}
@Override
public void setRef(int parameterIndex, Ref x) throws SQLException {
parameterSettings.put(parameterIndex - 1, new ParameterContext(ParameterMethod.setRef, new Object[] {
parameterIndex, x }));
}
@Override
public void setBlob(int parameterIndex, Blob x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setBlob, new Object[] {
parameterIndex, x }));
}
@Override
public void setClob(int parameterIndex, Clob x) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setClob, new Object[] {
parameterIndex, x }));
}
@Override
public void setArray(int parameterIndex, Array x) throws SQLException {
parameterSettings.put(parameterIndex - 1, new ParameterContext(ParameterMethod.setArray, new Object[] {
parameterIndex, x }));
}
@Override
public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
if (null == cal) {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setTime1, new Object[] {
parameterIndex, x }));
} else {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setTime2, new Object[] {
parameterIndex, x }));
}
}
@Override
public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setTimestamp2, new Object[] {
parameterIndex, x }));
}
@Override
public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setNull2, new Object[] {
parameterIndex, sqlType, typeName }));
}
@Override
public void setURL(int parameterIndex, URL x) throws SQLException {
parameterSettings.put(parameterIndex - 1, new ParameterContext(ParameterMethod.setURL, new Object[] {
parameterIndex, x }));
}
@Override
public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
parameterSettings.put(parameterIndex - 1, new ParameterContext(ParameterMethod.setObject3, new Object[] {
parameterIndex, x, targetSqlType, scaleOrLength }));
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return this.getClass().isAssignableFrom(iface);
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
try {
return (T) this;
} catch (Exception e) {
throw new SQLException(e);
}
}
// ----------------- 不支持的方法 ------------------
/**
* 不支持
*/
@Override
public ResultSetMetaData getMetaData() throws SQLException {
throw new UnsupportedOperationException("getMetaData");
}
@Override
public boolean isClosed() throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setPoolable(boolean poolable) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public boolean isPoolable() throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setRowId(int parameterIndex, RowId x) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setNString(int parameterIndex, String value) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setNClob(int parameterIndex, NClob value) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setClob(int parameterIndex, Reader reader) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public void setNClob(int parameterIndex, Reader reader) throws SQLException {
throw new SQLException("not support exception");
}
@Override
public ParameterMetaData getParameterMetaData() throws SQLException {
throw new SQLException("getParameterMetaData");
}
}