-
Notifications
You must be signed in to change notification settings - Fork 0
/
storing.go
147 lines (115 loc) · 3.74 KB
/
storing.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package srm
import (
"github.com/CloudyKit/srm/change"
"github.com/CloudyKit/srm/scheme"
"github.com/CloudyKit/framework/validation"
"errors"
"reflect"
)
// storingContext a storing context holds data necessary to an store routine
type storingContext struct {
mode string
validation validation.Validator
result validation.Result
lastErr error
scheme, parentScheme *scheme.Scheme
namespace string
name, parentName string
model, parentModel reflect.Value
*Session
}
func (storingContext *storingContext) restoreContext(on *storingContext) {
*on = *storingContext
}
func (storingContext *storingContext) storeFields() {
// create a list of operations
operations := make([]change.Set, 0, len(storingContext.scheme.Fields()))
// walk the scheme fields
for _, field := range storingContext.scheme.Fields() {
switch field.RelKind {
// if the field is a value field / has no rel,
case scheme.HasNoRel:
// setup validation context
storingContext.validation.Name = field.Name
storingContext.validation.Value = storingContext.model.FieldByIndex(field.Index)
// run validation testers
for i := 0; i < len(field.Testers); i++ {
field.Testers[i](&storingContext.validation)
}
// check for validation errors
if storingContext.validation.Done().Bad() {
// stop the store routine
panic(storingContext)
}
// no errors, store set operation
operations = append(operations, change.Set{Field: field.Name, Value: storingContext.validation.Value})
case scheme.HasOneEmbed:
// take snapshot of the current state of the context
snapshot := *storingContext
// modify the context to store the child model
storingContext.parentModel = storingContext.model
storingContext.parentScheme = storingContext.scheme
storingContext.parentName = storingContext.name
storingContext.name = field.Name
storingContext.model = storingContext.model.FieldByIndex(field.Index)
storingContext.namespace, storingContext.scheme = storingContext.Session.namedScheme(field.Type)
// store the child model
storingContext.storeFields()
// set the field value with primary key of the child model
operations = append(operations, change.Set{
Field: field.Name,
Value: reflect.ValueOf(
storingContext.parentModel.
Interface().(IModel).
getModel(),
),
})
// restore the state of the context
snapshot.restoreContext(storingContext)
case scheme.HasManyEmbed:
panic(errors.New("TODO: not implemented yet!!!!"))
case scheme.Belongs:
if field.Type == storingContext.parentScheme.Type && field.RelSrc == storingContext.name {
operations = append(operations, change.Set{
Field: field.Name,
Value: reflect.ValueOf(
storingContext.parentModel.
Interface().(IModel).
getModel(),
),
})
} else {
operations = append(operations, change.Set{
Field: field.Name,
Value: reflect.ValueOf(
storingContext.model.FieldByIndex(field.Index).
Interface().(IModel).
getModel(),
),
})
}
}
}
// storingMode new will execute new in all fields
if storingContext.mode == "creating" {
} else if storingContext.mode == "updating" {
} else {
}
storingContext.storeRelations()
storingContext.storeThroughRelations()
}
func (storingContext *storingContext) storeThroughRelations() {
}
func (storingContext *storingContext) storeRelations() {
// make a snapshot of the state of the storingContext
snapshot := *storingContext
for _, field := range storingContext.scheme.Fields() {
switch field.RelKind {
case scheme.HasOne:
storingContext.parentModel = storingContext.model
snapshot.restoreContext(storingContext)
case scheme.HasMany:
snapshot.restoreContext(storingContext)
}
}
}