|
|
@@ -0,0 +1,144 @@
|
|
|
+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 "<FUZZY>":
|
|
|
+ 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
|
|
|
+}
|