package com.meidusa.amoeba.aladdin.handler; import java.math.BigDecimal; import java.sql.Date; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Time; import java.util.concurrent.CountDownLatch; import org.apache.log4j.Logger; import com.meidusa.amoeba.aladdin.io.MysqlResultSetPacket; import com.meidusa.amoeba.aladdin.io.MysqlSimpleResultPacket; import com.meidusa.amoeba.aladdin.io.ResultPacket; import com.meidusa.amoeba.aladdin.util.ResultSetUtil; import com.meidusa.amoeba.jdbc.PoolableJdbcConnection; import com.meidusa.amoeba.mysql.handler.PreparedStatmentInfo; import com.meidusa.amoeba.mysql.jdbc.MysqlDefs; import com.meidusa.amoeba.mysql.net.MysqlClientConnection; import com.meidusa.amoeba.mysql.net.packet.BindValue; import com.meidusa.amoeba.mysql.net.packet.ExecutePacket; import com.meidusa.amoeba.net.MessageHandler; import com.meidusa.amoeba.net.poolable.ObjectPool; import com.meidusa.amoeba.net.poolable.PoolableObject; /** * @author struct * @author hexianmao */ public class PreparedStatmentExecuteMessageHandler extends CommandMessageHandler { private ExecutePacket packet; protected static class PreparedExecuteQueryRunnable extends QueryRunnable { private static Logger logger = Logger.getLogger(PreparedExecuteQueryRunnable.class); private ExecutePacket executePacket; PreparedExecuteQueryRunnable(CountDownLatch latch, PoolableObject conn, String query, Object parameter, ResultPacket packet){ super(latch, conn, query, parameter, packet); } @Override public void init(MessageHandler handler) { super.init(handler); executePacket = ((PreparedStatmentExecuteMessageHandler) handler).packet; } @Override protected void doRun(PoolableObject conn) { PreparedStatement pst = null; ResultSet rs = null; try { pst = ((java.sql.Connection) conn).prepareStatement(query); int i = 1; for (BindValue bindValue : executePacket.values) { if (!bindValue.isNull) { switch (bindValue.bufferType) { case MysqlDefs.FIELD_TYPE_TINY: pst.setByte(i++, bindValue.byteBinding); break; case MysqlDefs.FIELD_TYPE_SHORT: pst.setShort(i++, bindValue.shortBinding); break; case MysqlDefs.FIELD_TYPE_LONG: pst.setLong(i++, bindValue.longBinding); break; case MysqlDefs.FIELD_TYPE_LONGLONG: pst.setLong(i++, bindValue.longBinding); break; case MysqlDefs.FIELD_TYPE_FLOAT: pst.setFloat(i++, bindValue.floatBinding); break; case MysqlDefs.FIELD_TYPE_DOUBLE: pst.setDouble(i++, bindValue.doubleBinding); break; case MysqlDefs.FIELD_TYPE_TIME: pst.setTime(i++, (Time) bindValue.value); break; case MysqlDefs.FIELD_TYPE_DATE: case MysqlDefs.FIELD_TYPE_DATETIME: case MysqlDefs.FIELD_TYPE_TIMESTAMP: java.util.Date date = (java.util.Date) bindValue.value; pst.setDate(i++, new Date(date.getTime())); break; case MysqlDefs.FIELD_TYPE_VAR_STRING: case MysqlDefs.FIELD_TYPE_STRING: case MysqlDefs.FIELD_TYPE_VARCHAR: pst.setString(i++, (String) bindValue.value); break; case MysqlDefs.FIELD_TYPE_DECIMAL: case MysqlDefs.FIELD_TYPE_NEW_DECIMAL: pst.setBigDecimal(i++, (BigDecimal) bindValue.value); break; default: { logger.error("error type=" + bindValue.bufferType + " index=" + i); } } } else { pst.setObject(i++, null); } } if (isSelect(query)) { rs = pst.executeQuery(); MysqlResultSetPacket resultPacket = (MysqlResultSetPacket) packet; PoolableJdbcConnection poolableJdbcConnection = (PoolableJdbcConnection) conn; ResultSetUtil.resultSetToPacket(source, resultPacket, rs, poolableJdbcConnection.getResultSetHandler()); } else { MysqlSimpleResultPacket simplePacket = (MysqlSimpleResultPacket) packet; simplePacket.addResultCount(pst.executeUpdate()); } } catch (SQLException e) { logger.error("execute error", e); packet.setError(e.getErrorCode(), e.getMessage()); } finally { if (rs != null) { try { rs.close(); } catch (SQLException e) { } } if (pst != null) { try { pst.close(); } catch (SQLException e) { } } } } } public PreparedStatmentExecuteMessageHandler(MysqlClientConnection conn, PreparedStatmentInfo pInfo, ExecutePacket packet, ObjectPool[] pools, long timeout){ super(conn, pInfo.getPreparedStatment(), pInfo, pools, timeout); this.packet = packet; } @Override protected QueryRunnable newQueryRunnable(CountDownLatch latch, PoolableObject conn, String query, Object parameter, ResultPacket packet) { return new PreparedExecuteQueryRunnable(latch, conn, query, parameter, packet); } @Override protected ResultPacket newResultPacket(String query) { if (PreparedExecuteQueryRunnable.isSelect(query)) { MysqlResultSetPacket packet = new MysqlResultSetPacket(query); packet.setPrepared(true); return packet; } else { return new MysqlSimpleResultPacket(); } } }