Search in sources :

Example 1 with BindValue

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;
    }
}
Also used : MySQLMessage(io.mycat.backend.mysql.MySQLMessage) BindValue(io.mycat.backend.mysql.BindValue)

Example 2 with BindValue

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);
    }
}
Also used : ExecutePacket(io.mycat.net.mysql.ExecutePacket) UnsupportedEncodingException(java.io.UnsupportedEncodingException) PreparedStatement(io.mycat.backend.mysql.PreparedStatement) BindValue(io.mycat.backend.mysql.BindValue)

Example 3 with BindValue

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();
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) BindValue(io.mycat.backend.mysql.BindValue)

Aggregations

BindValue (io.mycat.backend.mysql.BindValue)3 MySQLMessage (io.mycat.backend.mysql.MySQLMessage)1 PreparedStatement (io.mycat.backend.mysql.PreparedStatement)1 ExecutePacket (io.mycat.net.mysql.ExecutePacket)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1