package com.meidusa.amoeba.mysql.net.packet; import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.Date; import org.apache.log4j.Logger; import com.meidusa.amoeba.mysql.jdbc.MysqlDefs; import com.meidusa.amoeba.util.StaticString; import com.meidusa.amoeba.util.ThreadLocalMap; public class PacketUtil { private static Logger logger = Logger.getLogger(PacketUtil.class); public static void resultToBindValue(BindValue bindValue,int columnIndex,ResultSet rs, FieldPacket fieldPacket) throws SQLException{ switch (bindValue.bufferType & 0xff) { case MysqlDefs.FIELD_TYPE_TINY: bindValue.byteBinding = rs.getByte(columnIndex); bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_SHORT: bindValue.shortBinding = rs.getShort(columnIndex); bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_LONG: bindValue.longBinding = rs.getLong(columnIndex); bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_LONGLONG: bindValue.longBinding = rs.getLong(columnIndex); bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_FLOAT: bindValue.floatBinding = rs.getFloat(columnIndex); bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_DOUBLE: bindValue.doubleBinding = rs.getDouble(columnIndex); bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_TIME: bindValue.value = rs.getTime(columnIndex); if(bindValue.value == null) { bindValue.isNull = true; } bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_DATE: case MysqlDefs.FIELD_TYPE_DATETIME: case MysqlDefs.FIELD_TYPE_TIMESTAMP: Timestamp time = rs.getTimestamp(columnIndex); bindValue.value = time; if(bindValue.value == null) { bindValue.isNull = true; } /** * */ if(time != null && (bindValue.bufferType & 0xff) == MysqlDefs.FIELD_TYPE_DATE){ Calendar sessionCalendar = (Calendar)ThreadLocalMap.get(StaticString.CALENDAR); if(sessionCalendar == null){ sessionCalendar = Calendar.getInstance(); ThreadLocalMap.put(StaticString.CALENDAR, sessionCalendar); } sessionCalendar.setTime(time); byte hour =((byte) sessionCalendar.get(Calendar.HOUR_OF_DAY)); byte minute = ((byte) sessionCalendar .get(Calendar.MINUTE)); byte second = ((byte) sessionCalendar.get(Calendar.SECOND)); if(hour>0 || minute>0||second>0){ fieldPacket.type = MysqlDefs.FIELD_TYPE_TIMESTAMP; } } bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_VAR_STRING: case MysqlDefs.FIELD_TYPE_STRING: case MysqlDefs.FIELD_TYPE_VARCHAR: bindValue.value = rs.getString(columnIndex); if(bindValue.value == null){ bindValue.isNull= true; } bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_DECIMAL: case MysqlDefs.FIELD_TYPE_NEW_DECIMAL: bindValue.value = rs.getBigDecimal(columnIndex); if(bindValue.value == null) { bindValue.isNull = true;; } bindValue.isSet =true; return; default:{ logger.error("error type=" + bindValue.bufferType); } } } /** * read packetBuffer to stroe in BindValue * @param packet * @param bindValue */ public static void readBindValue(MysqlPacketBuffer packet, BindValue bindValue) { // // Handle primitives first // switch (bindValue.bufferType & 0xff) { case MysqlDefs.FIELD_TYPE_TINY: bindValue.byteBinding = packet.readByte(); bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_SHORT: bindValue.shortBinding = (short)packet.readInt(); bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_LONG: bindValue.longBinding = packet.readLong(); bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_LONGLONG: bindValue.longBinding = packet.readLongLong(); bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_FLOAT: bindValue.floatBinding = packet.readFloat(); bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_DOUBLE: bindValue.doubleBinding = packet.readDouble(); bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_TIME: bindValue.value = readTime(packet); if(bindValue.value == null)bindValue.isNull = true; bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_DATE: case MysqlDefs.FIELD_TYPE_DATETIME: case MysqlDefs.FIELD_TYPE_TIMESTAMP: bindValue.value = readDate(packet); if(bindValue.value == null)bindValue.isNull = true; bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_VAR_STRING: case MysqlDefs.FIELD_TYPE_STRING: case MysqlDefs.FIELD_TYPE_VARCHAR: String charset = packet.getConnection().getCharset(); bindValue.value = packet.readLengthCodedString(charset); if(bindValue.value == null)bindValue.isNull = true; bindValue.isSet =true; return; case MysqlDefs.FIELD_TYPE_DECIMAL: case MysqlDefs.FIELD_TYPE_NEW_DECIMAL: charset = packet.getConnection().getCharset(); bindValue.value = new BigDecimal(packet.readLengthCodedString(charset)); if(bindValue.value == null)bindValue.isNull = true; bindValue.isSet =true; return; default:{ logger.error("error type=" + bindValue.bufferType); } } } /** * Method storeBinding. * * @param packet * @param bindValue * @param mysql * DOCUMENT ME! * * @throws SQLException * DOCUMENT ME! */ public static void storeBinding(MysqlPacketBuffer packet, BindValue bindValue,String encoding){ Object value = bindValue.value; // // Handle primitives first // switch (bindValue.bufferType & 0xff) { case MysqlDefs.FIELD_TYPE_TINY: packet.writeByte(bindValue.byteBinding); return; case MysqlDefs.FIELD_TYPE_SHORT: packet.writeInt(bindValue.shortBinding); return; case MysqlDefs.FIELD_TYPE_LONG: packet.writeLong(bindValue.longBinding); return; case MysqlDefs.FIELD_TYPE_LONGLONG: packet.writeLongLong(bindValue.longBinding); return; case MysqlDefs.FIELD_TYPE_FLOAT: packet.writeFloat(bindValue.floatBinding); return; case MysqlDefs.FIELD_TYPE_DOUBLE: packet.writeDouble(bindValue.doubleBinding); return; case MysqlDefs.FIELD_TYPE_TIME: storeTime(packet, (Time) value); return; case MysqlDefs.FIELD_TYPE_DATE: case MysqlDefs.FIELD_TYPE_DATETIME: case MysqlDefs.FIELD_TYPE_TIMESTAMP: storeDateTime(packet, (java.util.Date) value); return; case MysqlDefs.FIELD_TYPE_VAR_STRING: case MysqlDefs.FIELD_TYPE_STRING: case MysqlDefs.FIELD_TYPE_VARCHAR:{ if (value instanceof byte[]) { packet.writeLenBytes((byte[]) value); }else{ packet.writeLengthCodedString((String)value,encoding); } return; } case MysqlDefs.FIELD_TYPE_DECIMAL: case MysqlDefs.FIELD_TYPE_NEW_DECIMAL:{ if (value instanceof byte[]) { packet.writeLenBytes((byte[]) value); }else{ packet.writeLengthCodedString(value != null?value.toString():null,encoding); } return; } default:{ logger.error("error type=" + bindValue.bufferType); } } } public static void storeDateTime(MysqlPacketBuffer intoBuf, Date dt) { if(dt == null){ intoBuf.writeByte((byte)0); return; } Calendar sessionCalendar = (Calendar)ThreadLocalMap.get(StaticString.CALENDAR); if(sessionCalendar == null){ sessionCalendar = Calendar.getInstance(); ThreadLocalMap.put(StaticString.CALENDAR, sessionCalendar); } java.util.Date oldTime = sessionCalendar.getTime(); try { sessionCalendar.setTime(dt); if (dt instanceof java.sql.Date) { sessionCalendar.set(Calendar.HOUR_OF_DAY, 0); sessionCalendar.set(Calendar.MINUTE, 0); sessionCalendar.set(Calendar.SECOND, 0); } byte length = (byte) 7; if (dt instanceof java.sql.Timestamp) { length = (byte) 11; } intoBuf.writeByte(length); // length int year = sessionCalendar.get(Calendar.YEAR); int month = sessionCalendar.get(Calendar.MONTH) + 1; int date = sessionCalendar.get(Calendar.DAY_OF_MONTH); intoBuf.writeInt(year); intoBuf.writeByte((byte) month); intoBuf.writeByte((byte) date); if (dt instanceof java.sql.Date) { intoBuf.writeByte((byte) 0); intoBuf.writeByte((byte) 0); intoBuf.writeByte((byte) 0); } else { intoBuf.writeByte((byte) sessionCalendar .get(Calendar.HOUR_OF_DAY)); intoBuf.writeByte((byte) sessionCalendar .get(Calendar.MINUTE)); intoBuf.writeByte((byte) sessionCalendar .get(Calendar.SECOND)); } if (length == 11) { intoBuf.writeLong(((java.sql.Timestamp) dt).getNanos()); } } finally { sessionCalendar.setTime(oldTime); } } public static void storeTime(MysqlPacketBuffer intoBuf, Time tm){ if(tm == null){ intoBuf.writeByte((byte)0); return; } intoBuf.writeByte((byte) 8); // length intoBuf.writeByte((byte) 0); // neg flag intoBuf.writeLong(0); // tm->day, not used Calendar cal = (Calendar)ThreadLocalMap.get(StaticString.CALENDAR); synchronized (cal) { cal.setTime(tm); intoBuf.writeByte((byte) cal.get(Calendar.HOUR_OF_DAY)); intoBuf.writeByte((byte) cal.get(Calendar.MINUTE)); intoBuf.writeByte((byte) cal.get(Calendar.SECOND)); // intoBuf.writeLongInt(0); // tm-second_part } } public static Time readTime(MysqlPacketBuffer intoBuf){ intoBuf.readByte(); intoBuf.readByte(); intoBuf.readLong(); int hour = intoBuf.readByte(); int minute = intoBuf.readByte(); int second = intoBuf.readByte(); Calendar cal = (Calendar)ThreadLocalMap.get(StaticString.CALENDAR); cal.set(0, 0, 0, hour, minute, second); return new Time(cal.getTimeInMillis()); } public static Date readDate(MysqlPacketBuffer intoBuf){ byte length = intoBuf.readByte(); // length int year = intoBuf.readInt(); byte month = (byte)(intoBuf.readByte()-1); //���ݰ����·ݷ�Χ��1-12���� java�������·���0-11 byte date = intoBuf.readByte(); int hour = intoBuf.readByte(); int minute = intoBuf.readByte(); int second = intoBuf.readByte(); if (length == 11) { long nanos = intoBuf.readLong(); Calendar cal = (Calendar)ThreadLocalMap.get(StaticString.CALENDAR); if (cal == null) { cal = Calendar.getInstance(); ThreadLocalMap.put(StaticString.CALENDAR, cal); } cal.set(year, month, date, hour, minute, second); Timestamp time = new Timestamp(cal.getTimeInMillis()); time.setNanos((int)nanos); return time; }else{ Calendar cal = Calendar.getInstance(); cal.set(year, month, date, hour, minute, second); return cal.getTime(); } } }