package odbcmql import ( "fmt" "regexp" "strings" odb "git.wecise.com/wecise/odb-go/odb" "gitee.com/wecisecode/util/cast" ) func MatchValues(rtn *odb.Result, ks []string, ms []any) (x int, matchingvalues [][]any) { var matchingvalue any for _, dat := range rtn.Data { matchingvalues = append(matchingvalues, []any{}) m := false sv := "" match := true for i, k := range ks { matchingvalue = dat[k] m, sv = matchvalue(ms[i], matchingvalue) if !m { ks := strings.Split(k, ".") if len(ks) <= 1 { match = false break } else { k := "" for i := 0; match && i < len(ks); i++ { if matchingvalue == nil { if k != "" { k += "." } k += ks[i] matchingvalue = dat[k] if matchingvalue == nil && ks[i] == "len" { matchingvalue = 0 } } else { switch mv := matchingvalue.(type) { case map[string]any: matchingvalue = mv[ks[i]] if matchingvalue == nil && ks[i] == "len" { matchingvalue = len(mv) } case []any: if ks[i] == "len" { matchingvalue = len(mv) } else { n, e := cast.ToIntE(ks[i]) if e != nil { match = false break } matchingvalue = mv[n] } case string: if ks[i] == "len" { matchingvalue = len(mv) } else { n, e := cast.ToIntE(ks[i]) if e != nil { match = false break } matchingvalue = mv[n] } default: if ks[i] == "len" { matchingvalue = 0 } else { matchingvalue = nil } } } } m, sv = matchvalue(ms[i], matchingvalue) if !m { match = false break } } } matchingvalues[len(matchingvalues)-1] = append(matchingvalues[len(matchingvalues)-1], sv) } if match { x++ matchingvalues = matchingvalues[:len(matchingvalues)-1] } else { matchingvalues[len(matchingvalues)-1] = append(matchingvalues[len(matchingvalues)-1], sv) } } return } func matchvalue(matcher any, matchingvalue any) (bool, string) { switch m := matcher.(type) { case *regexp.Regexp: switch v := matchingvalue.(type) { case string: return m.MatchString(v), v default: sv := fmt.Sprintf("%#v", matchingvalue) return m.MatchString(sv), sv } case string: sv := "" switch matchingvalue.(type) { case int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64, bool: sv = fmt.Sprintf("%v", matchingvalue) case float32, float64: sv = fmt.Sprintf("%v", matchingvalue) fvrange := strings.Split(m, "~") if len(fvrange) > 1 { return sv >= fvrange[0] && sv <= fvrange[len(fvrange)-1], sv } default: sv = fmt.Sprintf("%#v", matchingvalue) } return sv == m, sv case *Action: switch m.Name { case "": return matchFuzzy(matchingvalue, m.Args) } } panic("未定义的匹配类型") } func matchFuzzy(matchingvalue any, mvrange []any) (bool, string) { sv := "" switch matchingvalue.(type) { case int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64, bool, float32, float64, string: sv = fmt.Sprintf("%v", matchingvalue) default: sv = fmt.Sprintf("%#v", matchingvalue) } if len(mvrange) == 0 { return false, sv } m1 := fmt.Sprintf("%v", mvrange[0]) m2 := fmt.Sprintf("%v", mvrange[len(mvrange)-1]) return sv >= m1 && sv <= m2, sv }