-
Notifications
You must be signed in to change notification settings - Fork 17
/
field-iteration.go
92 lines (72 loc) · 1.99 KB
/
field-iteration.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
package crud
import (
"reflect"
"github.com/azer/crud/v2/meta"
"github.com/azer/crud/v2/sql"
"github.com/azer/snakecase"
)
// Take any kind of struct and return a FieldIteration instance
// which helps walking the fields of the given struct one by one
// reading its name, value and SQL options
func NewFieldIteration(st interface{}) *FieldIteration {
rvalue, rtype := meta.Get(st)
length := rvalue.NumField()
return &FieldIteration{
Index: -1,
Length: length,
ReflectType: rtype,
ReflectValue: rvalue,
}
}
type FieldIteration struct {
Index int
Length int
ReflectValue reflect.Value
ReflectType reflect.Type
}
func (iteration *FieldIteration) Next() bool {
if iteration.Index+1 >= iteration.Length {
return false
}
iteration.Index += 1
return true
}
func (iteration *FieldIteration) TypeField() reflect.StructField {
return iteration.ReflectType.Field(iteration.Index)
}
func (iteration *FieldIteration) ValueField() reflect.Value {
return iteration.ReflectValue.Field(iteration.Index)
}
func (iteration *FieldIteration) SQLOptions() (*sql.Options, error) {
result, err := sql.NewOptions(iteration.TypeField().Tag.Get("sql"))
if err != nil {
return nil, err
}
if result.Ignore {
return result, nil
}
if len(result.Name) == 0 {
result.Name = snakecase.SnakeCase(iteration.Name())
}
if len(result.Type) == 0 {
sqlType, err := sql.MatchType(iteration.TypeField().Type.String())
if err != nil {
return nil, err
}
result.Type = sqlType
result.Length = sql.Types[result.Type]
}
return result, nil
}
func (iteration *FieldIteration) Value() interface{} {
return iteration.ReflectValue.Field(iteration.Index).Interface()
}
func (iteration *FieldIteration) Name() string {
return iteration.TypeField().Name
}
func (iteration *FieldIteration) IsEmbeddedStruct() bool {
if _, ok := sql.TypeDict[iteration.TypeField().Type.String()]; ok {
return false
}
return iteration.ReflectValue.Field(iteration.Index).Kind() == reflect.Struct
}