forked from go-rel/rel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
structset.go
104 lines (86 loc) · 1.99 KB
/
structset.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
package rel
import (
"time"
)
var (
now = time.Now
)
// Structset can be used as changes for repository insert or update operation.
// This will save every field in struct and it's association as long as it's loaded.
// This is the default changer used by repository.
type Structset struct {
doc *Document
}
// Build changes from structset.
func (s Structset) Build(changes *Changes) {
var (
pField = s.doc.PrimaryField()
t = now()
)
for _, field := range s.doc.Fields() {
switch field {
case pField:
continue
case "created_at", "inserted_at":
if typ, ok := s.doc.Type(field); ok && typ == rtTime {
if value, ok := s.doc.Value(field); ok && value.(time.Time).IsZero() {
changes.SetValue(field, t)
}
continue
}
case "updated_at":
if typ, ok := s.doc.Type(field); ok && typ == rtTime {
changes.SetValue(field, t)
continue
}
}
if value, ok := s.doc.Value(field); ok && !isZero(value) {
changes.SetValue(field, value)
}
}
for _, field := range s.doc.BelongsTo() {
s.buildAssoc(field, changes)
}
for _, field := range s.doc.HasOne() {
s.buildAssoc(field, changes)
}
for _, field := range s.doc.HasMany() {
s.buildAssocMany(field, changes)
}
}
func (s Structset) buildAssoc(field string, changes *Changes) {
var (
assoc = s.doc.Association(field)
)
if !assoc.IsZero() {
var (
doc, _ = assoc.Document()
ch = BuildChanges(Structset{doc: doc})
)
changes.SetAssoc(field, ch)
}
}
func (s Structset) buildAssocMany(field string, changes *Changes) {
var (
assoc = s.doc.Association(field)
)
if !assoc.IsZero() {
var (
col, _ = assoc.Collection()
chs = make([]Changes, col.Len())
)
for i := range chs {
chs[i] = BuildChanges(newStructset(col.Get(i)))
}
changes.SetAssoc(field, chs...)
}
}
func newStructset(doc *Document) Structset {
return Structset{
doc: doc,
}
}
// NewStructset from a struct.
func NewStructset(record interface{}) Structset {
return newStructset(NewDocument(record))
}