-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupdate.go
88 lines (72 loc) · 1.81 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
package query
import (
"errors"
"log/slog"
"strings"
)
type BulkUpdate struct {
sb *strings.Builder
keyCol string
keys []any
valueCols []string
values [][]any
}
func NewBulkUpdate(table, keyCol string, valueCols []string) *BulkUpdate {
sb := &strings.Builder{}
sb.WriteString("UPDATE ")
sb.WriteString(table)
sb.WriteString(" SET ")
return &BulkUpdate{
sb: sb,
keyCol: keyCol,
valueCols: valueCols,
values: make([][]any, len(valueCols)),
}
}
func (b *BulkUpdate) Add(key any, values ...any) error {
b.keys = append(b.keys, key)
for i := range b.values {
if i >= len(values) {
return errors.New("not enough values")
}
b.values[i] = append(b.values[i], values[i])
}
if len(values) > len(b.values) {
slog.Warn("too many values",
slog.Int("expected", len(b.values)),
slog.Int("actual", len(values)),
)
}
return nil
}
func (b *BulkUpdate) Query(whereQuery string, whereArgs ...any) (string, []any) {
args := make([]any, 0)
for i, valueCol := range b.valueCols {
b.sb.WriteString(valueCol)
b.sb.WriteString(" = ELT(FIELD(")
b.sb.WriteString(b.keyCol)
b.sb.WriteString(", ")
b.sb.WriteString(strings.Repeat("?, ", len(b.keys)-1))
b.sb.WriteString("?), ")
args = append(args, b.keys...)
b.sb.WriteString(strings.Repeat("?, ", len(b.values[i])-1))
b.sb.WriteString("?)")
args = append(args, b.values[i]...)
if i < len(b.valueCols)-1 {
b.sb.WriteString(", ")
}
}
b.sb.WriteString(" WHERE ")
b.sb.WriteString(b.keyCol)
b.sb.WriteString(" IN ")
b.sb.WriteString(strings.Repeat("?, ", len(b.keys)-1))
args = append(args, b.keys...)
b.sb.WriteString("?)")
if len(whereQuery) != 0 {
b.sb.WriteString(" AND (")
b.sb.WriteString(whereQuery)
b.sb.WriteString(")")
args = append(args, whereArgs...)
}
return b.sb.String(), args
}