1 Star 0 Fork 0

Bin/kir

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
param.go 3.36 KB
一键复制 编辑 原始数据 按行查看 历史
bin you 提交于 2024-09-20 00:29 . f
package main
import (
"encoding/binary"
"fmt"
"strings"
)
func parseParams(data []byte, stmt *preparedStatement) ([]interface{}, []byte, error) {
params := []interface{}{}
pos := 0 // 从数据的开始位置开始解析
// 跳过 flags (1 byte)
// pos += 1
// 跳过 iteration count (4 bytes),通常为 1
pos += 4
if pos >= len(data) {
return nil, nil, fmt.Errorf("数据不足以解析参数")
}
// 计算 NULL bitmap 的长度
nullBitmapLen := (stmt.params + 7) / 8
if pos+nullBitmapLen > len(data) {
return nil, nil, fmt.Errorf("数据不足以解析NULL bitmap")
}
nullBitmap := data[pos : pos+nullBitmapLen]
pos += nullBitmapLen
// 检查是否有新的参数绑定
var newParamTypes []byte
if pos < len(data) && data[pos] == 0x01 {
pos++ // 跳过 new params bound flag
if pos+stmt.params*2 > len(data) {
return nil, nil, fmt.Errorf("数据不足以解析新的参数类型")
}
newParamTypes = data[pos : pos+stmt.params*2]
pos += stmt.params * 2
}
// 如果没有新的参数类型,使用之前保存的类型
paramTypes := newParamTypes
if paramTypes == nil {
paramTypes = stmt.paramTypes
}
for i := 0; i < stmt.params; i++ {
if nullBitmap[i/8]&(1<<(i%8)) != 0 {
params = append(params, nil)
continue
}
if pos >= len(data) {
return nil, nil, fmt.Errorf("数据不足以解析参数值")
}
if len(paramTypes) <= i*2 {
return nil, nil, fmt.Errorf("参数类型信息不足")
}
paramType := binary.LittleEndian.Uint16(paramTypes[i*2:])
var param interface{}
var err error
switch paramType {
case 0x01: // MYSQL_TYPE_TINY
param, err = parseTiny(data, &pos)
case 0x02: // MYSQL_TYPE_SHORT
param, err = parseShort(data, &pos)
case 0x03: // MYSQL_TYPE_LONG
param, err = parseLong(data, &pos)
case 0x04: // MYSQL_TYPE_FLOAT
param, err = parseFloat(data, &pos)
case 0x05: // MYSQL_TYPE_DOUBLE
param, err = parseDouble(data, &pos)
case 0x07: // MYSQL_TYPE_TIMESTAMP
param, err = parseTimestamp(data, &pos)
case 0x0a: // MYSQL_TYPE_DATE
param, err = parseDate(data, &pos)
case 0x0b: // MYSQL_TYPE_TIME
param, err = parseTime(data, &pos)
case 0x0e: // MYSQL_TYPE_DATETIME
param, err = parseDatetime(data, &pos)
case 0x08: // MYSQL_TYPE_LONGLONG
param, err = parseLongLong(data, &pos)
case 0x0f, 0xfe: // MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VAR_STRING
param, err = parseVarString(data, &pos)
// 可以根据需要添加更多类型的解析
default:
return nil, nil, fmt.Errorf("不支持的参数类型: %d", paramType)
}
if err != nil {
return nil, nil, err
}
params = append(params, param)
}
return params, newParamTypes, nil
}
func reconstructSQL(sql string, params []interface{}) string {
parts := strings.Split(sql, "?")
if len(parts) != len(params)+1 {
return sql
}
var result strings.Builder
for i, part := range parts[:len(parts)-1] {
result.WriteString(part)
result.WriteString(formatParam(params[i]))
}
result.WriteString(parts[len(parts)-1])
return result.String()
}
func formatParam(param interface{}) string {
switch v := param.(type) {
case nil:
return "NULL"
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
return fmt.Sprintf("%d", v)
case float32, float64:
return fmt.Sprintf("%f", v)
case string:
return fmt.Sprintf("'%s'", strings.ReplaceAll(v, "'", "\\'"))
default:
return fmt.Sprintf("'%v'", v)
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/llyb120/kir.git
[email protected]:llyb120/kir.git
llyb120
kir
kir
master

搜索帮助