feat(db): 实现数据库查询中的数组参数展开和空数组处理
- 在 Get 方法中添加无参数时的默认字段和 LIMIT 1 处理 - 实现 expandArrayPlaceholder 方法,自动展开 IN (?) 和 NOT IN (?) 中的数组参数 - 为空数组的 IN 条件生成 1=0 永假条件,NOT IN 生成 1=1 永真条件 - 在 queryWithRetry 和 execWithRetry 中集成数组占位符预处理 - 修复 where.go 中空切片条件的处理逻辑 - 添加完整的 IN/NOT IN 数组查询测试用例 - 更新 .gitignore 规则格式
This commit is contained in:
+31
-3
@@ -90,10 +90,29 @@ func (that *HoTimeDB) where(data Map) (string, []interface{}) {
|
||||
}
|
||||
|
||||
// 处理普通条件字段
|
||||
// 空切片的 IN 条件应该生成永假条件(1=0),而不是跳过
|
||||
if v != nil && reflect.ValueOf(v).Type().String() == "common.Slice" && len(v.(Slice)) == 0 {
|
||||
// 检查是否是 NOT IN(带 [!] 后缀)- NOT IN 空数组永真,跳过即可
|
||||
if !strings.HasSuffix(k, "[!]") {
|
||||
// IN 空数组 -> 生成永假条件
|
||||
if normalCondCount > 0 {
|
||||
where += " AND "
|
||||
}
|
||||
where += "1=0 "
|
||||
normalCondCount++
|
||||
}
|
||||
continue
|
||||
}
|
||||
if v != nil && strings.Contains(reflect.ValueOf(v).Type().String(), "[]") && len(ObjToSlice(v)) == 0 {
|
||||
// 检查是否是 NOT IN(带 [!] 后缀)- NOT IN 空数组永真,跳过即可
|
||||
if !strings.HasSuffix(k, "[!]") {
|
||||
// IN 空数组 -> 生成永假条件
|
||||
if normalCondCount > 0 {
|
||||
where += " AND "
|
||||
}
|
||||
where += "1=0 "
|
||||
normalCondCount++
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -110,17 +129,22 @@ func (that *HoTimeDB) where(data Map) (string, []interface{}) {
|
||||
}
|
||||
|
||||
// 添加 WHERE 关键字
|
||||
if len(where) != 0 {
|
||||
// 先去除首尾空格,检查是否有实际条件内容
|
||||
trimmedWhere := strings.TrimSpace(where)
|
||||
if len(trimmedWhere) != 0 {
|
||||
hasWhere := true
|
||||
for _, v := range vcond {
|
||||
if strings.Index(where, v) == 0 {
|
||||
if strings.Index(trimmedWhere, v) == 0 {
|
||||
hasWhere = false
|
||||
}
|
||||
}
|
||||
|
||||
if hasWhere {
|
||||
where = " WHERE " + where + " "
|
||||
where = " WHERE " + trimmedWhere + " "
|
||||
}
|
||||
} else {
|
||||
// 没有实际条件内容,重置 where
|
||||
where = ""
|
||||
}
|
||||
|
||||
// 处理特殊字符(按固定顺序:GROUP, HAVING, ORDER, LIMIT, OFFSET)
|
||||
@@ -322,6 +346,8 @@ func (that *HoTimeDB) handleDefaultCondition(k string, v interface{}, where stri
|
||||
if reflect.ValueOf(v).Type().String() == "common.Slice" || strings.Contains(reflect.ValueOf(v).Type().String(), "[]") {
|
||||
vs := ObjToSlice(v)
|
||||
if len(vs) == 0 {
|
||||
// IN 空数组 -> 生成永假条件
|
||||
where += "1=0 "
|
||||
return where, res
|
||||
}
|
||||
|
||||
@@ -352,6 +378,8 @@ func (that *HoTimeDB) handlePlainField(k string, v interface{}, where string, re
|
||||
} else if reflect.ValueOf(v).Type().String() == "common.Slice" || strings.Contains(reflect.ValueOf(v).Type().String(), "[]") {
|
||||
vs := ObjToSlice(v)
|
||||
if len(vs) == 0 {
|
||||
// IN 空数组 -> 生成永假条件
|
||||
where += "1=0 "
|
||||
return where, res
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user