-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.go
131 lines (122 loc) · 3.77 KB
/
parser.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package drivers
import (
"errors"
"fmt"
"github.com/gohouse/gorose"
"reflect"
"sort"
"strings"
)
func (b Builder) buildTableName(rft reflect.Type, prefix string) (tab string) {
return BackQuotes(fmt.Sprintf("%s%s", prefix, gorose.StructsToTableName(rft)))
}
func (b Builder) toSqlInsert(c *gorose.Context, data any, ignoreCase string, onDuplicateKeys []string) (sql4prepare string, values []any, err error) {
rfv := reflect.Indirect(reflect.ValueOf(data))
var fields []string
var valuesPlaceholderArr []string
switch rfv.Kind() {
case reflect.Map:
keys := rfv.MapKeys()
sort.Slice(keys, func(i, j int) bool {
return keys[i].String() < keys[j].String()
})
var valuesPlaceholderTmp []string
for _, key := range keys {
fields = append(fields, BackQuotes(key.String()))
valuesPlaceholderTmp = append(valuesPlaceholderTmp, "?")
values = append(values, rfv.MapIndex(key).Interface())
}
valuesPlaceholderArr = append(valuesPlaceholderArr, fmt.Sprintf("(%s)", strings.Join(valuesPlaceholderTmp, ",")))
case reflect.Slice:
if rfv.Len() == 0 {
return
}
if rfv.Type().Elem().Kind() == reflect.Map {
// 先获取到插入字段
keys := rfv.Index(0).MapKeys()
sort.Slice(keys, func(i, j int) bool {
return keys[i].String() < keys[j].String()
})
for _, key := range keys {
fields = append(fields, BackQuotes(key.String()))
}
// 组合插入数据
for i := 0; i < rfv.Len(); i++ {
var valuesPlaceholderTmp []string
for _, key := range keys {
valuesPlaceholderTmp = append(valuesPlaceholderTmp, "?")
values = append(values, rfv.Index(i).MapIndex(key).Interface())
}
valuesPlaceholderArr = append(valuesPlaceholderArr, fmt.Sprintf("(%s)", strings.Join(valuesPlaceholderTmp, ",")))
}
} else {
err = errors.New("only map(slice) data supported")
return
}
default:
err = errors.New("only map(slice) data supported")
return
}
if err != nil {
return
}
var onDuplicateKey string
if len(onDuplicateKeys) > 0 {
var tmp []string
for _, v := range onDuplicateKeys {
tmp = append(tmp, fmt.Sprintf("%s=VALUES(%s)", BackQuotes(v), BackQuotes(v)))
}
onDuplicateKey = fmt.Sprintf("ON DUPLICATE KEY UPDATE %s", strings.Join(tmp, ", "))
}
var tables string
tables, _, err = b.ToSqlTable(c)
if err != nil {
return
}
sql4prepare = NamedSprintf("INSERT :ignoreCase INTO :tables (:fields) VALUES :placeholder :onDuplicateKey", ignoreCase, tables, strings.Join(fields, ","), strings.Join(valuesPlaceholderArr, ","), onDuplicateKey)
return
}
func (b Builder) toSqlUpdateReal(c *gorose.Context, data any) (sql4prepare string, values []any, err error) {
rfv := reflect.Indirect(reflect.ValueOf(data))
var updates []string
switch rfv.Kind() {
case reflect.Map:
keys := rfv.MapKeys()
sort.Slice(keys, func(i, j int) bool {
return keys[i].String() < keys[j].String()
})
for _, key := range keys {
updates = append(updates, fmt.Sprintf("%s = ?", BackQuotes(key.String())))
values = append(values, rfv.MapIndex(key).Interface())
}
default:
err = errors.New("only map data supported")
return
}
var tables string
tables, _, err = b.ToSqlTable(c)
if err != nil {
return
}
wheres, binds, err := b.ToSqlWhere(c)
if err != nil {
return sql4prepare, values, err
}
values = append(values, binds...)
sql4prepare = NamedSprintf("UPDATE :tables SET :updates :wheres", tables, strings.Join(updates, ", "), wheres)
return
}
func (b Builder) toSqlDelete(c *gorose.Context) (sql4prepare string, values []any, err error) {
var tables string
tables, _, err = b.ToSqlTable(c)
if err != nil {
return
}
wheres, binds, err := b.ToSqlWhere(c)
if err != nil {
return sql4prepare, values, err
}
values = append(values, binds...)
sql4prepare = NamedSprintf("DELETE FROM :tables :wheres", tables, wheres)
return
}