com.continuent.tungsten.common.mysql
Class MySQLPacket

java.lang.Object
  extended by com.continuent.tungsten.common.mysql.MySQLPacket
Direct Known Subclasses:
MySQLAuthPacket, MySQLQueryPacket

public class MySQLPacket
extends java.lang.Object

A MySQL packet with helper functions to ease the reading and writting of bytes, integers, long integers, strings...

Version:
$Id: $
Author:
Csaba Simon, Gilles Rayrat

Field Summary
static int EOF_SERVER_STATUS_OFFSET
          EOF packet server status appears as a short at this offset
static int EOF_WARNING_COUNT_OFFSET
          EOF warning count appears as a short starting at this offset
static int ERROR_MESSAGE_OFFSET
          ODBC/JDBC SQL state appears as a byte at this offset
static int ERROR_NUMBER_OFFSET
          MySQL Errorno appears as a short at this offset
static int ERROR_SQL_STATE_OFFSET
          ODBC/JDBC SQL state appears as a byte at this offset
static int HEADER_LENGTH
          Length of the packet header
static int MAX_LENGTH
          Maximum packet length (16M)
static int PACKET_TYPE_OFFSET
          Packet type is a single byte at this offset
 
Constructor Summary
MySQLPacket(int size, byte packetNumber)
          Creates a new MySQLPacket object
MySQLPacket(int dataLength, byte[] buffer, byte packetNumber)
          Creates a new MySQLPacket object
 
Method Summary
 byte getByte()
          Returns one byte from the buffer.
 byte[] getByteBuffer()
          Returns the raw byte buffer.
 byte[] getBytes(int len)
          Returns len bytes from the buffer.
 int getDataLength()
          Gets the current length of the byteBuffer
 java.sql.Date getDate(int length)
          Reads a date from stream given its length and returns the corresponding Date
 double getDouble()
          Returns eight bytes from the buffer as a float
 long getFieldLength()
           
 float getFloat()
          Returns four bytes from the buffer as a float
 long getHourMinSec()
          Reads hours, minutes and seconds from stream and returns the corresponding number of milliseconds
 java.io.InputStream getInputStream()
          Retrieves the input stream that created this packet
 int getInt24()
          Returns three consecutive bytes as an integer (MySQL longint) from the buffer.
 int getInt32()
          Returns four consecutive bytes as an integer (MySQL long) from the buffer.
 byte[] getLenEncodedBytes()
          Returns a len encoded byte array from the buffer.
 java.lang.String getLenEncodedString(boolean stopAtNullChar)
          Returns a string from the buffer, where the encoded size is right before the actual string
 long getLong()
          Returns eight consecutive bytes as a long (MySQL longlong) from the buffer.
 byte getPacketNumber()
          Returns the packet number.
 int getPacketPosition()
          Retrieves the current byte buffer cursor position
 int getRemainingBytes()
          Returns the number of bytes remaining in the buffer
 short getShort()
          Aka.
 java.lang.String getString()
          Returns a string from the buffer.
 java.lang.String getString(int len)
          Returns a len length string from the buffer.
 java.sql.Time getTime(int length)
          Reads a time from stream given its length and returns the corresponding Time
 short getUnsignedByte()
          Reads one byte from the buffer considering it as an unsigned value and returns a corresponding short
 int getUnsignedInt24()
          Returns three consecutive bytes as an integer (MySQL longint) from the buffer considering it as an unsigned.
 long getUnsignedInt32()
          Returns four consecutive bytes as an integer (MySQL long) from the buffer.
 java.math.BigInteger getUnsignedLong()
          Returns eight consecutive bytes from the buffer (MySQL longlong) treated as unsigned value into a big integer .
 int getUnsignedShort()
          Aka.
 boolean hasCursor()
          Tells whether or not a cursor exists.
 boolean hasLastRowSent()
          Tells whether the end of a result set has been reached upon COM_STMT_FETCH command
 boolean hasMoreResults()
          Tells whether or not more results exist on the server.
 boolean isEmpty()
          Empty packets have a zero size data
 boolean isEOF()
          Whether or not this packet is a MySQL "EOF" packet
 boolean isError()
          Whether or not this packet is a MySQL "ERROR" packet
 boolean isLargePacket()
          Whether or not this packet is a large packet, thus part of a large query or result
 boolean isOK()
          Whether or not this packet is a MySQL "OK" packet
 boolean isServerFlagSet(short flag)
          Tests "server status" bytes in a OK or EOF packet to tell whether or not the given flag is set.
static MySQLPacket mysqlReadPacket(java.io.InputStream in, boolean dropLargePackets)
           
 int peekEOFServerStatus()
          Returns the bit mask for the server status from the MySQL "EOF" packet
 int peekEOFWarningCount()
          Returns the warning count from the MySQL "EOF" packet
 int peekErrorErrno()
          Returns the MySQL error number from the MySQL "ERROR" packet without modifying the packet
 java.lang.String peekErrorErrorMessage()
          Returns the MySQL error message from the MySQL "ERROR" packet without modifying the packet
 int peekErrorSQLState()
          Returns the MySQL error number from the MySQL "ERROR" packet without modifying the packet
 long peekFieldCount()
           
 java.lang.String peekString(int offset, int len)
          Returns a len length string from the buffer.
 java.lang.String peekStringAtOffset(int startPosition)
          Returns a string from the buffer.
 void preparePacketForStreaming()
          When streaming a packet, some data has possibly been already read in it.
 void putByte(byte b)
          Put a byte in the buffer.
 void putBytes(byte[] bytes)
          Put an array of bytes in the buffer.
 long putDate(java.sql.Date d)
          Puts a Date to the buffer as:
two bytes year one byte month one byte day
 void putDouble(double d)
          Puts a double in the buffer
 void putFieldLength(long length)
          Put a long as a len encoded value in the buffer.
 void putFloat(float f)
          Puts a float in the buffer
 long putHourMinSec(long millis)
          Converts a time in millis to hours, minutes and seconds and put it in the buffer
 void putInt16(int i)
          Put an integer in the buffer.
 void putInt24(int i)
          Put an integer (MySQL longint) in the buffer
 void putInt32(int i)
          Put an integer (MySQL long) in the buffer.
 void putLenBytes(byte[] bytes)
          Put a byte array as a len encoded bytes in the buffer.
 void putLenString(java.lang.String s)
          Put a string as a len encoded bytes in the buffer.
 void putLong(long i)
          Put a long (MySQL longlong) in the buffer.
 void putString(java.lang.String s)
          Put a string in the buffer.
 void putStringNoNull(java.lang.String s)
          Put a string in the buffer.
 void putTime(java.sql.Time t)
          Puts a jdbc Time in the buffer as:
Send sign (0 for > EPOCH, 1 for < EPOCH)
Then day (always zero for a time)
Finally Hour Minutes and Seconds using putHourMinSec(long)
Note that MySQL jdbc driver doesn't care about days and millis, so it is most probably unnecessary to send them...
 void putUnsignedInt32(long i)
          Put an unsigned integer (MySQL long) in the buffer.
 long readFieldLength()
          Returns the len encoded value as a long from buffer.
static MySQLPacket readPacket(java.io.InputStream in)
          Reads a MySQL packet from the input stream using a default partial read timeout of 5 seconds.
static MySQLPacket readPacket(java.io.InputStream in, boolean dropLargePackets)
          Reads a MySQL packet from the input stream.
static MySQLPacket readPacket(java.io.InputStream in, long timeoutMillis)
          Reads a MySQL packet from the input stream.
 void readRemainingPackets()
          Provided this packet is a large packet > 16M, reads the remaining packets and and adds their data to this packet data.
 void reset()
          Rewinds data buffer pointer to the first data byte.
 void setInputStream(java.io.InputStream inputStream)
          Retain creation input stream for further re-reads
 void setPacketPosition(int pos)
          Changes the byte buffer cursor position
 java.lang.String toString()
           
 void write(java.io.OutputStream out)
          Write out the content of the buffer to the output stream.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

HEADER_LENGTH

public static final int HEADER_LENGTH
Length of the packet header

See Also:
Constant Field Values

MAX_LENGTH

public static final int MAX_LENGTH
Maximum packet length (16M)

See Also:
Constant Field Values

PACKET_TYPE_OFFSET

public static final int PACKET_TYPE_OFFSET
Packet type is a single byte at this offset

See Also:
Constant Field Values

EOF_WARNING_COUNT_OFFSET

public static final int EOF_WARNING_COUNT_OFFSET
EOF warning count appears as a short starting at this offset

See Also:
Constant Field Values

EOF_SERVER_STATUS_OFFSET

public static final int EOF_SERVER_STATUS_OFFSET
EOF packet server status appears as a short at this offset

See Also:
Constant Field Values

ERROR_NUMBER_OFFSET

public static final int ERROR_NUMBER_OFFSET
MySQL Errorno appears as a short at this offset

See Also:
Constant Field Values

ERROR_SQL_STATE_OFFSET

public static final int ERROR_SQL_STATE_OFFSET
ODBC/JDBC SQL state appears as a byte at this offset

See Also:
Constant Field Values

ERROR_MESSAGE_OFFSET

public static final int ERROR_MESSAGE_OFFSET
ODBC/JDBC SQL state appears as a byte at this offset

See Also:
Constant Field Values
Constructor Detail

MySQLPacket

public MySQLPacket(int dataLength,
                   byte[] buffer,
                   byte packetNumber)
Creates a new MySQLPacket object

Parameters:
buffer - the buffer
packetNumber - the packet number

MySQLPacket

public MySQLPacket(int size,
                   byte packetNumber)
Creates a new MySQLPacket object

Parameters:
size - the size of the buffer
packetNumber - the packet number
Method Detail

readPacket

public static MySQLPacket readPacket(java.io.InputStream in,
                                     boolean dropLargePackets)
Reads a MySQL packet from the input stream.

Parameters:
in - the data input stream from where we read the MySQL packet
dropLargePackets - whether or not to return null when a packet of 16Mb is read
Returns:
a MySQLPacket object or null if the MySQL packet cannot be read

mysqlReadPacket

public static MySQLPacket mysqlReadPacket(java.io.InputStream in,
                                          boolean dropLargePackets)
                                   throws java.io.IOException,
                                          java.io.EOFException
Throws:
java.io.IOException
java.io.EOFException

readPacket

public static MySQLPacket readPacket(java.io.InputStream in,
                                     long timeoutMillis)
Reads a MySQL packet from the input stream.

Parameters:
in - the data input stream from where we read the MySQL packet
timeoutMillis - Number of milliseconds we will pause while waiting for data from the the network during a packet.
Returns:
a MySQLPacket object or null if the MySQL packet cannot be read

readPacket

public static MySQLPacket readPacket(java.io.InputStream in)
Reads a MySQL packet from the input stream using a default partial read timeout of 5 seconds.

Parameters:
in - the data input stream from where we read the MySQL packet
Returns:
a MySQLPacket object or null if the MySQL packet cannot be read

getByteBuffer

public byte[] getByteBuffer()
Returns the raw byte buffer.


getPacketNumber

public byte getPacketNumber()
Returns the packet number.

Returns:
the packet number

getDataLength

public int getDataLength()
Gets the current length of the byteBuffer

Returns:
the byte buffer length

isLargePacket

public boolean isLargePacket()
Whether or not this packet is a large packet, thus part of a large query or result


isEmpty

public boolean isEmpty()
Empty packets have a zero size data

Returns:
true if the data length is zero

getPacketPosition

public int getPacketPosition()
Retrieves the current byte buffer cursor position

Returns:
the position field

setPacketPosition

public void setPacketPosition(int pos)
Changes the byte buffer cursor position

Parameters:
pos - the new position

peekErrorErrno

public int peekErrorErrno()
Returns the MySQL error number from the MySQL "ERROR" packet without modifying the packet

Returns:
int as value of error

peekErrorSQLState

public int peekErrorSQLState()
Returns the MySQL error number from the MySQL "ERROR" packet without modifying the packet

Returns:
int as value of error

peekErrorErrorMessage

public java.lang.String peekErrorErrorMessage()
Returns the MySQL error message from the MySQL "ERROR" packet without modifying the packet

Returns:
String with error message

peekEOFServerStatus

public int peekEOFServerStatus()
Returns the bit mask for the server status from the MySQL "EOF" packet

Returns:
int as value of EOF server status

peekEOFWarningCount

public int peekEOFWarningCount()
Returns the warning count from the MySQL "EOF" packet

Returns:
int as value of EOF warning count

preparePacketForStreaming

public void preparePacketForStreaming()
When streaming a packet, some data has possibly been already read in it. In order to send it, we need to scroll the cursor to the last data byte position


isOK

public boolean isOK()
Whether or not this packet is a MySQL "OK" packet

Returns:
true if this packet is a OK packet

isError

public boolean isError()
Whether or not this packet is a MySQL "ERROR" packet

Returns:
true if this packet is a ERROR packet

isEOF

public boolean isEOF()
Whether or not this packet is a MySQL "EOF" packet

Returns:
true if this packet is a EOF packet

isServerFlagSet

public boolean isServerFlagSet(short flag)
Tests "server status" bytes in a OK or EOF packet to tell whether or not the given flag is set. A warning will be printed if the packet is neither an EOF nor a OK, and false will be returned

Returns:
true if and only if the packet is OK or EOF packet and if the given flag is set in the server status bytes.

hasMoreResults

public boolean hasMoreResults()
Tells whether or not more results exist on the server.

Returns:
true if and only if the packet is a OK or EOF packet and that SERVER_MORE_RESULTS_EXISTS is set in the server status bytes.

hasCursor

public boolean hasCursor()
Tells whether or not a cursor exists.

Returns:
true if and only if the packet is a OK or EOF packet and that SERVER_STATUS_CURSOR_EXISTS is set in the server status bytes.

hasLastRowSent

public boolean hasLastRowSent()
Tells whether the end of a result set has been reached upon COM_STMT_FETCH command

Returns:
true if and only if the packet is a OK or EOF packet and that SERVER_STATUS_LAST_ROW_SENT is set in the server status bytes.

peekFieldCount

public long peekFieldCount()

getRemainingBytes

public int getRemainingBytes()
Returns the number of bytes remaining in the buffer

Returns:
remaining bytes to read

getByte

public byte getByte()
Returns one byte from the buffer.

Returns:
one byte from the buffer

getUnsignedByte

public short getUnsignedByte()
Reads one byte from the buffer considering it as an unsigned value and returns a corresponding short

Returns:
one byte from the buffer

getBytes

public byte[] getBytes(int len)
Returns len bytes from the buffer.

Parameters:
len - the number of bytes to return
Returns:
len bytes from the buffer

getUnsignedShort

public int getUnsignedShort()
Aka. getUnsignedInt16(), returns two consecutive bytes from the buffer considering them as an unsigned value

Returns:
an integer corresponding to 2 buffer bytes treated as an unsigned value

getShort

public short getShort()
Aka. getInt16(), returns two consecutive bytes from the buffer considering them as signed value

Returns:
an integer corresponding to the 2 bytes treated as a signed value

getLenEncodedBytes

public byte[] getLenEncodedBytes()
Returns a len encoded byte array from the buffer.

Returns:
a len encoded byte array from the buffer

getInt32

public int getInt32()
Returns four consecutive bytes as an integer (MySQL long) from the buffer.

Returns:
four consecutive bytes as an integer (MySQL long) from the buffer

getUnsignedInt32

public long getUnsignedInt32()
Returns four consecutive bytes as an integer (MySQL long) from the buffer.

Returns:
an integer (MySQL long) based from the buffer

getUnsignedInt24

public int getUnsignedInt24()
Returns three consecutive bytes as an integer (MySQL longint) from the buffer considering it as an unsigned.

Returns:
an integer (MySQL longint) from the buffer treated as an unsigned

getInt24

public int getInt24()
Returns three consecutive bytes as an integer (MySQL longint) from the buffer.

Returns:
three consecutive bytes as an integer (MySQL longint) from the buffer.

getLong

public long getLong()
Returns eight consecutive bytes as a long (MySQL longlong) from the buffer.

Returns:
eight consecutive bytes as a long (MySQL longlong) from the buffer

getUnsignedLong

public java.math.BigInteger getUnsignedLong()
Returns eight consecutive bytes from the buffer (MySQL longlong) treated as unsigned value into a big integer .

Returns:
the corresponding bigInteger

getFloat

public float getFloat()
Returns four bytes from the buffer as a float


getDouble

public double getDouble()
Returns eight bytes from the buffer as a float


getString

public java.lang.String getString()
Returns a string from the buffer.

Returns:
a string from the buffer

peekStringAtOffset

public java.lang.String peekStringAtOffset(int startPosition)
Returns a string from the buffer.

Returns:
a string from the buffer

peekString

public java.lang.String peekString(int offset,
                                   int len)
Returns a len length string from the buffer.

Parameters:
len - the length of the string
Returns:
a len length string from the buffer

getString

public java.lang.String getString(int len)
Returns a len length string from the buffer.

Parameters:
len - the length of the string
Returns:
a len length string from the buffer

getLenEncodedString

public java.lang.String getLenEncodedString(boolean stopAtNullChar)
Returns a string from the buffer, where the encoded size is right before the actual string

Parameters:
stopAtNullChar - whether or not to consider the string ends with the null character. When false, the string length will always be the decoded length
Returns:
string with decoded length

getTime

public java.sql.Time getTime(int length)
Reads a time from stream given its length and returns the corresponding Time

Parameters:
length - size of the time data
Returns:
jdbc Time decoded from stream

getHourMinSec

public long getHourMinSec()
Reads hours, minutes and seconds from stream and returns the corresponding number of milliseconds

Returns:
milliseconds decoded from stream

getDate

public java.sql.Date getDate(int length)
Reads a date from stream given its length and returns the corresponding Date

Parameters:
length - size of the date data
Returns:
jdbc Date decoded from stream

putByte

public void putByte(byte b)
Put a byte in the buffer.

Parameters:
b - the byte to put in the buffer

putBytes

public void putBytes(byte[] bytes)
Put an array of bytes in the buffer.

Parameters:
bytes - the byte array

putFieldLength

public void putFieldLength(long length)
Put a long as a len encoded value in the buffer.

Parameters:
length - the value to put in the buffer

getFieldLength

public long getFieldLength()

putInt16

public void putInt16(int i)
Put an integer in the buffer.

Parameters:
i - the integer to put in the buffer

putLenBytes

public void putLenBytes(byte[] bytes)
Put a byte array as a len encoded bytes in the buffer.

Parameters:
bytes - the byte array to put in the buffer

putLenString

public void putLenString(java.lang.String s)
Put a string as a len encoded bytes in the buffer.

Parameters:
s - the string to put in the buffer

putInt32

public void putInt32(int i)
Put an integer (MySQL long) in the buffer.

Parameters:
i - the value to put in the buffer

putUnsignedInt32

public void putUnsignedInt32(long i)
Put an unsigned integer (MySQL long) in the buffer.

Parameters:
i - the value to put in the buffer

putInt24

public void putInt24(int i)
Put an integer (MySQL longint) in the buffer

Parameters:
i - the value to put in the buffer

putLong

public void putLong(long i)
Put a long (MySQL longlong) in the buffer.

Parameters:
i - the value to put in the buffer

putFloat

public void putFloat(float f)
Puts a float in the buffer


putDouble

public void putDouble(double d)
Puts a double in the buffer


putString

public void putString(java.lang.String s)
Put a string in the buffer.

Parameters:
s - the value to put in the buffer

putStringNoNull

public void putStringNoNull(java.lang.String s)
Put a string in the buffer. No null terminated.

Parameters:
s - the value to put in the buffer

putHourMinSec

public long putHourMinSec(long millis)
Converts a time in millis to hours, minutes and seconds and put it in the buffer

Parameters:
millis - milliseconds since EPOCH
Returns:
the actual number of millis written (without the millis info)

putTime

public void putTime(java.sql.Time t)
Puts a jdbc Time in the buffer as:
Send sign (0 for > EPOCH, 1 for < EPOCH)
Then day (always zero for a time)
Finally Hour Minutes and Seconds using putHourMinSec(long)
Note that MySQL jdbc driver doesn't care about days and millis, so it is most probably unnecessary to send them...

Parameters:
t - the Time object to write

putDate

public long putDate(java.sql.Date d)
Puts a Date to the buffer as:
two bytes year one byte month one byte day

Parameters:
d - jdbc date to write
Returns:
the rounded date as milliseconds actually put (without hh mm ss ms information)

reset

public void reset()
Rewinds data buffer pointer to the first data byte.


write

public void write(java.io.OutputStream out)
           throws java.io.IOException
Write out the content of the buffer to the output stream.

Parameters:
out - the output stream
Throws:
java.io.IOException - if an error happens when writting to the output stream

readFieldLength

public long readFieldLength()
Returns the len encoded value as a long from buffer.

Returns:
the len encoded value as a long from buffer

getInputStream

public java.io.InputStream getInputStream()
Retrieves the input stream that created this packet

Returns:
the input stream used to read the current packet

setInputStream

public void setInputStream(java.io.InputStream inputStream)
Retain creation input stream for further re-reads

Parameters:
inputStream - the input stream that created this packet

readRemainingPackets

public void readRemainingPackets()
Provided this packet is a large packet > 16M, reads the remaining packets and and adds their data to this packet data. The result will consist in one large packet with all data in. Note that the new packet's header will be invalid


toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object