-
Notifications
You must be signed in to change notification settings - Fork 1
/
builder-update.go
105 lines (94 loc) · 1.96 KB
/
builder-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
package finder
import (
"context"
"fmt"
"github.com/Masterminds/squirrel"
)
type OptimisticLock struct {
Name string
Value any
}
type ConfigUpdate struct {
DB Connection
QB *squirrel.StatementBuilderType
TableName string
TableAlias string
IDColumn *string
OptimisticLock *OptimisticLock
Input *[]any
Inserts *[]string
Selects *[]string
Joins *[]string
Wheres *[]squirrel.Sqlizer
}
func UpdateOne(updated Model, c *ConfigUpdate) error {
if c.TableName == "" {
c.TableName = updated.TableName()
}
if c.TableAlias == "" {
c.TableAlias = updated.TableName()
}
if c.OptimisticLock != nil {
if c.OptimisticLock.Name == "" {
c.OptimisticLock.Name = "updated_at"
}
}
if c.Inserts == nil {
return ErrInsertsNotAPointerSlice
}
if c.Input == nil {
return ErrInputNotAPointerSlice
}
id := updated.GetID()
if id == "" || id == "0" || id == ZeroedUUID {
return ErrNoProvidedID
}
subquery := c.QB.
Update(c.TableName).
Suffix("RETURNING *")
if c.IDColumn != nil {
w := fmt.Sprintf("%s=?", *c.IDColumn)
subquery = subquery.Where(w, id)
} else {
subquery = subquery.Where("id=?", id)
}
if c.OptimisticLock != nil {
subquery = subquery.Where(
c.OptimisticLock.Name+" = ?",
c.OptimisticLock.Value,
)
}
if c.Wheres != nil {
if len(*c.Wheres) != 0 {
for _, where := range *c.Wheres {
subquery = subquery.Where(where)
}
}
}
for i, column := range *c.Inserts {
subquery = subquery.Set(column, (*c.Input)[i])
}
with := subquery.
Prefix("WITH " + c.TableAlias + " AS (").
Suffix(")")
result := c.QB.Select(*c.Selects...).
PrefixExpr(with).
From(c.TableAlias)
if c.Joins != nil {
if len(*c.Joins) > 0 {
for _, join := range *c.Joins {
result = result.LeftJoin(join)
}
}
}
query, args, err := result.ToSql()
if err != nil {
return err
}
return c.DB.GetContext(
context.Background(),
updated,
query,
args...,
)
}