/* * Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software;Designed and Developed mainly by many Chinese * opensource volunteers. you can redistribute it and/or modify it under the * terms of the GNU General Public License version 2 only, as published by the * Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Any questions about this component can be directed to it's project Web address * https://code.google.com/p/opencloudb/. * */ package org.opencloudb.net.mysql; import java.io.UnsupportedEncodingException; import org.opencloudb.mysql.BindValue; import org.opencloudb.mysql.BindValueUtil; import org.opencloudb.mysql.MySQLMessage; import org.opencloudb.mysql.PreparedStatement; /** * <pre> * Bytes Name * ----- ---- * 1 code * 4 statement_id * 1 flags * 4 iteration_count * (param_count+7)/8 null_bit_map * 1 new_parameter_bound_flag (if new_params_bound == 1:) * n*2 type of parameters * n values for the parameters * -------------------------------------------------------------------------------- * code: always COM_EXECUTE * * statement_id: statement identifier * * flags: reserved for future use. In MySQL 4.0, always 0. * In MySQL 5.0: * 0: CURSOR_TYPE_NO_CURSOR * 1: CURSOR_TYPE_READ_ONLY * 2: CURSOR_TYPE_FOR_UPDATE * 4: CURSOR_TYPE_SCROLLABLE * * iteration_count: reserved for future use. Currently always 1. * * null_bit_map: A bitmap indicating parameters that are NULL. * Bits are counted from LSB, using as many bytes * as necessary ((param_count+7)/8) * i.e. if the first parameter (parameter 0) is NULL, then * the least significant bit in the first byte will be 1. * * new_parameter_bound_flag: Contains 1 if this is the first time * that "execute" has been called, or if * the parameters have been rebound. * * type: Occurs once for each parameter; * The highest significant bit of this 16-bit value * encodes the unsigned property. The other 15 bits * are reserved for the type (only 8 currently used). * This block is sent when parameters have been rebound * or when a prepared statement is executed for the * first time. * * values: for all non-NULL values, each parameters appends its value * as described in Row Data Packet: Binary (column values) * @see http://dev.mysql.com/doc/internals/en/execute-packet.html * </pre> * * @author mycat */ public class ExecutePacket extends MySQLPacket { public byte code; public long statementId; public byte flags; public long iterationCount; public byte[] nullBitMap; public byte newParameterBoundFlag; public BindValue[] values; protected PreparedStatement pstmt; public ExecutePacket(PreparedStatement pstmt) { this.pstmt = pstmt; this.values = new BindValue[pstmt.getParametersNumber()]; } public void read(byte[] data, String charset) throws UnsupportedEncodingException { MySQLMessage mm = new MySQLMessage(data); packetLength = mm.readUB3(); packetId = mm.read(); code = mm.read(); statementId = mm.readUB4(); flags = mm.read(); iterationCount = mm.readUB4(); // 读取NULL指示器数据 int parameterCount = values.length; nullBitMap = new byte[(parameterCount + 7) / 8]; for (int i = 0; i < nullBitMap.length; i++) { nullBitMap[i] = mm.read(); } // 当newParameterBoundFlag==1时,更新参数类型。 newParameterBoundFlag = mm.read(); if (newParameterBoundFlag == (byte) 1) { for (int i = 0; i < parameterCount; i++) { pstmt.getParametersType()[i] = mm.readUB2(); } } // 设置参数类型和读取参数值 byte[] nullBitMap = this.nullBitMap; for (int i = 0; i < parameterCount; i++) { BindValue bv = new BindValue(); bv.type = pstmt.getParametersType()[i]; if ((nullBitMap[i / 8] & (1 << (i & 7))) != 0) { bv.isNull = true; } else { BindValueUtil.read(mm, bv, charset); } values[i] = bv; } } @Override public int calcPacketSize() { // TODO Auto-generated method stub return 0; } @Override protected String getPacketInfo() { return "MySQL Execute Packet"; } }