-
Notifications
You must be signed in to change notification settings - Fork 1
/
named.go
71 lines (64 loc) · 1.89 KB
/
named.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package dbx
import (
"fmt"
"reflect"
"regexp"
"sort"
"strings"
"github.com/microbun/dbx/reflectx"
)
var reg = regexp.MustCompile(":\\w+")
func namedCompile(query string, p map[string]interface{}) (string, []interface{}, error) {
args := make([]interface{}, 0)
matched := reg.FindAllString(query, -1)
placeholders := map[string]string{}
for _, parameter := range matched {
value, ok := p[parameter[1:]]
if !ok {
return "", nil, fmt.Errorf("`%s` not found ", parameter)
}
rt := reflect.TypeOf(value)
rv := reflect.ValueOf(value)
if reflectx.IsBasicType(rt) {
args = append(args, value)
placeholders[parameter] = "?"
} else if reflectx.IsSliceType(rt) {
if rt.Elem().String() == "uint8" {
args = append(args, value)
placeholders[parameter] = "?"
continue
}
if rt.Elem().String() != "[]uint8" && rt.Elem().String() != "[]int8" && !reflectx.IsBasicType(rt.Elem()) {
return "", nil, fmt.Errorf("unsupport args type at %s", parameter)
}
repeat := make([]string, 0)
if rv.Len() == 0 {
return "", nil, fmt.Errorf("`%s` len must be greater than 0", parameter)
}
for j := 0; j < rv.Len(); j++ {
args = append(args, rv.Index(j).Interface())
repeat = append(repeat, "?")
}
placeholders[parameter] = strings.Join(repeat, ",")
} else if reflectx.IsStructType(rt) {
if len(p) > 1 {
return "", nil, fmt.Errorf("unsupport args type at %s", parameter)
} else {
//解析结构体的参数
return "", nil, fmt.Errorf("unsupport key type %s", parameter)
}
} else {
return "", nil, fmt.Errorf("unsupport args type at %s", parameter)
}
}
params := make([]string, 0)
for p := range placeholders {
params = append(params, p)
}
sort.Sort(sort.Reverse(sort.StringSlice(params)))
for _, key := range params {
placeholder := placeholders[key]
query = strings.ReplaceAll(query, key, placeholder)
}
return query, args, nil
}