/
sql.tmpl.nulljson.go
114 lines (107 loc) · 2.5 KB
/
sql.tmpl.nulljson.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
package main
// Arguments to format are:
// SqlJsonType: NullJson type name
// ValueType: value type name
// NilValue: nil value of map type
const tmplNullJson = `
// {{.SqlJsonType}} represents an interface that may be null.
// {{.SqlJsonType}} implements the Scanner interface so
// it can be used as a scan destination, similar to sql.NullString.
type {{.SqlJsonType}} struct {
Data {{.ValueType}}
Valid bool // Valid is true if Data is not NULL
}
// Scan implements the sql.Scanner interface.
func (nj *{{.SqlJsonType}}) Scan(src interface{}) error {
if src == nil {
nj.Data, nj.Valid = {{.NilValue}}, false
return nil
}
nj.Valid = true
var err error
switch src := src.(type) {
case string:
if len(src) > 0 {
var v interface{} = &nj.Data
switch v := v.(type) {
{{- if .ProtoJson }}
case proto.Message:
err = protojson.UnmarshalOptions{
AllowPartial: true,
DiscardUnknown: true,
}.Unmarshal([]byte(src), v)
{{- end}}
default:
err = json.Unmarshal([]byte(src), v)
}
}
case []byte:
if len(src) > 0 {
var v interface{} = &nj.Data
switch v := v.(type) {
{{- if .ProtoJson }}
case proto.Message:
err = protojson.UnmarshalOptions{
AllowPartial: true,
DiscardUnknown: true,
}.Unmarshal(src, v)
{{- end}}
default:
err = json.Unmarshal(src, v)
}
}
case time.Time:
srcBytes, _ := json.Marshal(src)
var v interface{} = &nj.Data
switch v := v.(type) {
case proto.Message:
{{- if .ProtoJson }}
err = protojson.UnmarshalOptions{
AllowPartial: true,
DiscardUnknown: true,
}.Unmarshal(srcBytes, v)
{{- end}}
default:
err = json.Unmarshal(srcBytes, v)
}
case nil:
nj.Data = {{.NilValue}}
err = nil
default:
srcBytes, _ := json.Marshal(src)
var v interface{} = &nj.Data
switch v := v.(type) {
{{- if .ProtoJson }}
case proto.Message:
err = protojson.UnmarshalOptions{
AllowPartial: true,
DiscardUnknown: true,
}.Unmarshal(srcBytes, v)
{{- end}}
default:
err = json.Unmarshal(srcBytes, v)
}
}
if err == nil {
return nil
}
return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T: %w", src, nj.Data, err)
}
// Value implements the driver.Valuer interface.
func (nj {{.SqlJsonType}}) Value() (driver.Value, error) {
if !nj.Valid {
return nil, nil
}
var v interface{} = &nj.Data
switch v := v.(type) {
{{- if .ProtoJson }}
case proto.Message:
return protojson.MarshalOptions{
AllowPartial: true,
}.Marshal(v)
{{- end}}
default:
return json.Marshal(v)
}
}
`