-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathupdate.go
129 lines (106 loc) · 2.62 KB
/
update.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
package dbr
import "reflect"
// UpdateStmt builds `UPDATE ...`
type UpdateStmt interface {
Builder
Where(query interface{}, value ...interface{}) UpdateStmt
Set(column string, value interface{}) UpdateStmt
SetMap(m map[string]interface{}) UpdateStmt
SetRecord(structValue interface{}) UpdateStmt
}
type updateStmt struct {
raw
Table string
Value map[string]interface{}
WhereCond []Builder
}
// Build builds `UPDATE ...` in dialect
func (b *updateStmt) Build(d Dialect, buf Buffer) error {
if b.raw.Query != "" {
return b.raw.Build(d, buf)
}
if b.Table == "" {
return ErrTableNotSpecified
}
if len(b.Value) == 0 {
return ErrColumnNotSpecified
}
buf.WriteString("UPDATE ")
buf.WriteString(d.QuoteIdent(b.Table))
buf.WriteString(" SET ")
i := 0
for col, v := range b.Value {
if i > 0 {
buf.WriteString(", ")
}
buf.WriteString(d.QuoteIdent(col))
buf.WriteString(" = ")
buf.WriteString(placeholder)
buf.WriteValue(v)
i++
}
if len(b.WhereCond) > 0 {
buf.WriteString(" WHERE ")
err := And(b.WhereCond...).Build(d, buf)
if err != nil {
return err
}
}
return nil
}
// Update creates an UpdateStmt
func Update(table string) UpdateStmt {
return createUpdateStmt(table)
}
func createUpdateStmt(table string) *updateStmt {
return &updateStmt{
Table: table,
Value: make(map[string]interface{}),
}
}
// UpdateBySql creates an UpdateStmt with raw query
func UpdateBySql(query string, value ...interface{}) UpdateStmt {
return createUpdateStmtBySQL(query, value)
}
func createUpdateStmtBySQL(query string, value []interface{}) *updateStmt {
return &updateStmt{
raw: raw{
Query: query,
Value: value,
},
Value: make(map[string]interface{}),
}
}
// Where adds a where condition
func (b *updateStmt) Where(query interface{}, value ...interface{}) UpdateStmt {
switch query := query.(type) {
case string:
b.WhereCond = append(b.WhereCond, Expr(query, value...))
case Builder:
b.WhereCond = append(b.WhereCond, query)
}
return b
}
// Set specifies a key-value pair
func (b *updateStmt) Set(column string, value interface{}) UpdateStmt {
b.Value[column] = value
return b
}
// SetMap specifies a list of key-value pair
func (b *updateStmt) SetMap(m map[string]interface{}) UpdateStmt {
for col, val := range m {
b.Set(col, val)
}
return b
}
// SetRecord specifies a record with field and values to set
func (b *updateStmt) SetRecord(structValue interface{}) UpdateStmt {
v := reflect.Indirect(reflect.ValueOf(structValue))
if v.Kind() == reflect.Struct {
sm := structMap(v.Type())
for col, index := range sm {
b.Set(col, v.FieldByIndex(index).Interface())
}
}
return b
}