/
update.go
76 lines (67 loc) · 1.47 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
package y
import (
"reflect"
sq "github.com/lann/squirrel"
)
// Changer updates object values
type Changer struct {
proxy *Proxy
values Values
}
func (c *Changer) modify() sq.Eq {
modified := sq.Eq{}
for name, val := range c.values {
f := c.proxy.Field(name)
if f.Interface() != val {
modified[name] = val
f.Set(reflect.ValueOf(val))
}
}
return modified
}
func (c *Changer) primary() sq.Eq {
pks := sq.Eq{}
for _, pk := range c.proxy.schema.xinfo.pk {
pks[pk] = c.proxy.Field(pk).Interface()
}
return pks
}
func (c *Changer) prepare(clauses sq.Eq, where sq.Eq) sq.UpdateBuilder {
return sq.Update(c.proxy.schema.table).SetMap(clauses).Where(where)
}
// Update saves object changes in db after version validation
func (c *Changer) Update(db DB) (updated bool, err error) {
// load origin
err = c.proxy.Load(db)
if err != nil {
return
}
oldv := c.proxy.Version()
newv := oldv + 1
// find changes
clauses := c.modify()
if len(clauses) == 0 {
return
}
// set new version
clauses[_version] = newv
c.proxy.Field(_version).SetInt(newv)
// set where condition
where := c.primary()
where[_version] = oldv
// save
result, err := exec(c.prepare(clauses, where), db)
if err != nil {
return
}
count, err := result.RowsAffected()
updated = count == 1
return
}
func makeChanger(p *Proxy, v Values) *Changer {
return &Changer{p, v}
}
// Update saves object changes
func Update(db DB, p *Proxy, v Values) (bool, error) {
return makeChanger(p, v).Update(db)
}