/
field.go
117 lines (97 loc) · 2.16 KB
/
field.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
package schema
import (
"fmt"
"reflect"
"github.com/uptrace/bun/dialect"
"github.com/uptrace/bun/internal/tagparser"
)
type Field struct {
StructField reflect.StructField
Tag tagparser.Tag
Type reflect.Type
Index []int
Name string // SQL name, .e.g. id
SQLName Safe // escaped SQL name, e.g. "id"
GoName string // struct field name, e.g. Id
DiscoveredSQLType string
UserSQLType string
CreateTableSQLType string
SQLDefault string
OnDelete string
OnUpdate string
IsPK bool
NotNull bool
NullZero bool
AutoIncrement bool
Append AppenderFunc
Scan ScannerFunc
IsZero IsZeroerFunc
}
func (f *Field) String() string {
return f.Name
}
func (f *Field) Clone() *Field {
cp := *f
cp.Index = cp.Index[:len(f.Index):len(f.Index)]
return &cp
}
func (f *Field) Value(strct reflect.Value) reflect.Value {
return fieldByIndexAlloc(strct, f.Index)
}
func (f *Field) HasZeroValue(v reflect.Value) bool {
for _, idx := range f.Index {
if v.Kind() == reflect.Ptr {
if v.IsNil() {
return true
}
v = v.Elem()
}
v = v.Field(idx)
}
return f.IsZero(v)
}
func (f *Field) AppendValue(fmter Formatter, b []byte, strct reflect.Value) []byte {
fv, ok := fieldByIndex(strct, f.Index)
if !ok {
return dialect.AppendNull(b)
}
if f.NullZero && f.IsZero(fv) {
return dialect.AppendNull(b)
}
if f.Append == nil {
panic(fmt.Errorf("bun: AppendValue(unsupported %s)", fv.Type()))
}
return f.Append(fmter, b, fv)
}
func (f *Field) ScanWithCheck(fv reflect.Value, src interface{}) error {
if f.Scan == nil {
return fmt.Errorf("bun: Scan(unsupported %s)", f.Type)
}
return f.Scan(fv, src)
}
func (f *Field) ScanValue(strct reflect.Value, src interface{}) error {
if src == nil {
if fv, ok := fieldByIndex(strct, f.Index); ok {
return f.ScanWithCheck(fv, src)
}
return nil
}
fv := fieldByIndexAlloc(strct, f.Index)
return f.ScanWithCheck(fv, src)
}
func (f *Field) markAsPK() {
f.IsPK = true
f.NotNull = true
f.NullZero = true
}
func indexEqual(ind1, ind2 []int) bool {
if len(ind1) != len(ind2) {
return false
}
for i, ind := range ind1 {
if ind != ind2[i] {
return false
}
}
return true
}