use of io.mycat.backend.mysql.BindValue in project Mycat-Server by MyCATApache.
the class ExecutePacket method read.
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;
if (parameterCount > 0) {
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);
if (bv.isLongData) {
bv.value = pstmt.getLongData(i);
}
}
values[i] = bv;
}
}
use of io.mycat.backend.mysql.BindValue in project Mycat-Server by MyCATApache.
the class ServerPrepareHandler method execute.
@Override
public void execute(byte[] data) {
long pstmtId = ByteUtil.readUB4(data, 5);
PreparedStatement pstmt = null;
if ((pstmt = pstmtForId.get(pstmtId)) == null) {
source.writeErrMessage(ErrorCode.ER_ERROR_WHEN_EXECUTING_COMMAND, "Unknown pstmtId when executing.");
} else {
ExecutePacket packet = new ExecutePacket(pstmt);
try {
packet.read(data, source.getCharset());
} catch (UnsupportedEncodingException e) {
source.writeErrMessage(ErrorCode.ER_ERROR_WHEN_EXECUTING_COMMAND, e.getMessage());
return;
}
BindValue[] bindValues = packet.values;
// 还原sql中的动态参数为实际参数值
String sql = prepareStmtBindValue(pstmt, bindValues);
// 执行sql
source.getSession2().setPrepared(true);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("execute prepare sql: " + sql);
}
source.query(sql);
}
}
use of io.mycat.backend.mysql.BindValue in project Mycat-Server by MyCATApache.
the class ServerPrepareHandler method prepareStmtBindValue.
/**
* 组装sql语句,替换动态参数为实际参数值
* @param pstmt
* @param bindValues
* @return
*/
private String prepareStmtBindValue(PreparedStatement pstmt, BindValue[] bindValues) {
String sql = pstmt.getStatement();
int[] paramTypes = pstmt.getParametersType();
StringBuilder sb = new StringBuilder();
int idx = 0;
for (int i = 0, len = sql.length(); i < len; i++) {
char c = sql.charAt(i);
if (c != '?') {
sb.append(c);
continue;
}
// 处理占位符?
int paramType = paramTypes[idx];
BindValue bindValue = bindValues[idx];
idx++;
// 处理字段为空的情况
if (bindValue.isNull) {
sb.append("NULL");
continue;
}
// 非空情况, 根据字段类型获取值
switch(paramType & 0xff) {
case Fields.FIELD_TYPE_TINY:
sb.append(String.valueOf(bindValue.byteBinding));
break;
case Fields.FIELD_TYPE_SHORT:
sb.append(String.valueOf(bindValue.shortBinding));
break;
case Fields.FIELD_TYPE_LONG:
sb.append(String.valueOf(bindValue.intBinding));
break;
case Fields.FIELD_TYPE_LONGLONG:
sb.append(String.valueOf(bindValue.longBinding));
break;
case Fields.FIELD_TYPE_FLOAT:
sb.append(String.valueOf(bindValue.floatBinding));
break;
case Fields.FIELD_TYPE_DOUBLE:
sb.append(String.valueOf(bindValue.doubleBinding));
break;
case Fields.FIELD_TYPE_VAR_STRING:
case Fields.FIELD_TYPE_STRING:
case Fields.FIELD_TYPE_VARCHAR:
bindValue.value = varcharEscaper.asFunction().apply(String.valueOf(bindValue.value));
sb.append("'" + bindValue.value + "'");
break;
case Fields.FIELD_TYPE_TINY_BLOB:
case Fields.FIELD_TYPE_BLOB:
case Fields.FIELD_TYPE_MEDIUM_BLOB:
case Fields.FIELD_TYPE_LONG_BLOB:
if (bindValue.value instanceof ByteArrayOutputStream) {
byte[] bytes = ((ByteArrayOutputStream) bindValue.value).toByteArray();
sb.append("X'" + HexFormatUtil.bytesToHexString(bytes) + "'");
} else {
// 正常情况下不会走到else, 除非long data的存储方式(ByteArrayOutputStream)被修改
LOGGER.warn("bind value is not a instance of ByteArrayOutputStream, maybe someone change the implement of long data storage!");
sb.append("'" + bindValue.value + "'");
}
break;
case Fields.FIELD_TYPE_TIME:
case Fields.FIELD_TYPE_DATE:
case Fields.FIELD_TYPE_DATETIME:
case Fields.FIELD_TYPE_TIMESTAMP:
sb.append("'" + bindValue.value + "'");
break;
default:
bindValue.value = varcharEscaper.asFunction().apply(String.valueOf(bindValue.value));
sb.append(bindValue.value.toString());
break;
}
}
return sb.toString();
}
Aggregations