mysql 协议的ColumnDefinition包及解析

时间:2022-04-26 11:50:20

git

https://github.com/sea-boat/mysql-protocol

概况

ColumnDefinition包属于服务端返回ResultSet时的其中一部分包,用于描述结果集的字段信息。

mysql通信报文结构

类型 名字 描述
int<3> payload长度 按照the least significant byte first存储,3个字节的payload和1个字节的序列号组合成报文头
int<1> 序列号
string payload 报文体,长度即为前面指定的payload长度

ColumnDefinition包

Payload

lenenc_str     catalog
lenenc_str schema
lenenc_str table
lenenc_str org_table
lenenc_str name
lenenc_str org_name
lenenc_int length of fixed-length fields [0c]
2 character set
4 column length
1 type
2 flags
1 decimals
2 filler [00] [00]
if command was COM_FIELD_LIST {
lenenc_int length of default-values
string[$len] default values
}

更多详情 : http://dev.mysql.com/doc/internals/en/com-query-response.html#column-definition

ColumnCount包类

/**
*
* <pre><b>column definition command packet.</b></pre>
* @author
* <pre>seaboat</pre>
* <pre><b>email: </b>849586227@qq.com</pre>
* <pre><b>blog: </b>http://blog.csdn.net/wangyangzhizhou</pre>
* @version 1.0
* @see http://dev.mysql.com/doc/internals/en/com-query-response.html#column-definition
*/

public class ColumnDefinitionPacket extends MySQLPacket {
private static final byte[] DEFAULT_CATALOG = "def".getBytes();
private static final byte NEXT_LENGTH = 0x0c;
private static final byte[] FILLER = { 00, 00 };

public byte[] catalog = DEFAULT_CATALOG;// always "def"
public byte[] schema;
public byte[] table;
public byte[] orgTable;
public byte[] name;
public byte[] orgName;
public byte nextLength = NEXT_LENGTH;// always 0x0c
public int charsetSet;
public long length;
public int type;
public int flags;
public byte decimals;
public byte[] filler = FILLER;
public byte[] defaultValues;

public void read(byte[] data) {
MySQLMessage mm = new MySQLMessage(data);
this.packetLength = mm.readUB3();
this.packetId = mm.read();
this.catalog = mm.readBytesWithLength();
this.schema = mm.readBytesWithLength();
this.table = mm.readBytesWithLength();
this.orgTable = mm.readBytesWithLength();
this.name = mm.readBytesWithLength();
this.orgName = mm.readBytesWithLength();
this.nextLength = mm.read();
this.charsetSet = mm.readUB2();
this.length = mm.readUB4();
this.type = mm.read() & 0xff;
this.flags = mm.readUB2();
this.decimals = mm.read();
this.filler = mm.readBytes(2);
if (mm.hasRemaining()) {
this.defaultValues = mm.readBytesWithLength();
}
}

@Override
public void write(ByteBuffer buffer) {
int size = calcPacketSize();
BufferUtil.writeUB3(buffer, size);
buffer.put(packetId);
BufferUtil.writeWithLength(buffer, catalog, (byte) 0);
BufferUtil.writeWithLength(buffer, schema, (byte) 0);
BufferUtil.writeWithLength(buffer, table, (byte) 0);
BufferUtil.writeWithLength(buffer, orgTable, (byte) 0);
BufferUtil.writeWithLength(buffer, name, (byte) 0);
BufferUtil.writeWithLength(buffer, orgName, (byte) 0);
buffer.put(NEXT_LENGTH);
BufferUtil.writeUB2(buffer, charsetSet);
BufferUtil.writeUB4(buffer, length);
buffer.put((byte) (type & 0xff));
BufferUtil.writeUB2(buffer, flags);
buffer.put(decimals);
buffer.put(FILLER);
if (defaultValues != null) {
//only use for show columns
BufferUtil.writeWithLength(buffer, defaultValues);
}
}

@Override
public int calcPacketSize() {
int size = (catalog == null ? 1 : BufferUtil.getLength(catalog));
size += (schema == null ? 1 : BufferUtil.getLength(schema));
size += (table == null ? 1 : BufferUtil.getLength(table));
size += (orgTable == null ? 1 : BufferUtil.getLength(orgTable));
size += (name == null ? 1 : BufferUtil.getLength(name));
size += (orgName == null ? 1 : BufferUtil.getLength(orgName));
size += 13;
if (defaultValues != null) {
size += BufferUtil.getLength(defaultValues);
}
return size;
}

@Override
protected String getPacketInfo() {
return "MySQL Column Definition Packet";
}

}