1 package pgtype
2
3 import (
4 "database/sql"
5 "database/sql/driver"
6 "encoding/json"
7 "fmt"
8 "reflect"
9 )
10
11 type JSONCodec struct{}
12
13 func (JSONCodec) FormatSupported(format int16) bool {
14 return format == TextFormatCode || format == BinaryFormatCode
15 }
16
17 func (JSONCodec) PreferredFormat() int16 {
18 return TextFormatCode
19 }
20
21 func (c JSONCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan {
22 switch value.(type) {
23 case string:
24 return encodePlanJSONCodecEitherFormatString{}
25 case []byte:
26 return encodePlanJSONCodecEitherFormatByteSlice{}
27
28
29
30 case json.RawMessage:
31 return encodePlanJSONCodecEitherFormatJSONRawMessage{}
32
33
34
35
36
37
38
39 case driver.Valuer:
40 return &encodePlanDriverValuer{m: m, oid: oid, formatCode: format}
41
42
43
44
45
46 case json.Marshaler:
47 return encodePlanJSONCodecEitherFormatMarshal{}
48 }
49
50
51
52 for _, f := range []TryWrapEncodePlanFunc{
53 TryWrapDerefPointerEncodePlan,
54 TryWrapFindUnderlyingTypeEncodePlan,
55 } {
56 if wrapperPlan, nextValue, ok := f(value); ok {
57 if nextPlan := c.PlanEncode(m, oid, format, nextValue); nextPlan != nil {
58 wrapperPlan.SetNext(nextPlan)
59 return wrapperPlan
60 }
61 }
62 }
63
64 return encodePlanJSONCodecEitherFormatMarshal{}
65 }
66
67 type encodePlanJSONCodecEitherFormatString struct{}
68
69 func (encodePlanJSONCodecEitherFormatString) Encode(value any, buf []byte) (newBuf []byte, err error) {
70 jsonString := value.(string)
71 buf = append(buf, jsonString...)
72 return buf, nil
73 }
74
75 type encodePlanJSONCodecEitherFormatByteSlice struct{}
76
77 func (encodePlanJSONCodecEitherFormatByteSlice) Encode(value any, buf []byte) (newBuf []byte, err error) {
78 jsonBytes := value.([]byte)
79 if jsonBytes == nil {
80 return nil, nil
81 }
82
83 buf = append(buf, jsonBytes...)
84 return buf, nil
85 }
86
87 type encodePlanJSONCodecEitherFormatJSONRawMessage struct{}
88
89 func (encodePlanJSONCodecEitherFormatJSONRawMessage) Encode(value any, buf []byte) (newBuf []byte, err error) {
90 jsonBytes := value.(json.RawMessage)
91 if jsonBytes == nil {
92 return nil, nil
93 }
94
95 buf = append(buf, jsonBytes...)
96 return buf, nil
97 }
98
99 type encodePlanJSONCodecEitherFormatMarshal struct{}
100
101 func (encodePlanJSONCodecEitherFormatMarshal) Encode(value any, buf []byte) (newBuf []byte, err error) {
102 jsonBytes, err := json.Marshal(value)
103 if err != nil {
104 return nil, err
105 }
106
107 buf = append(buf, jsonBytes...)
108 return buf, nil
109 }
110
111 func (JSONCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan {
112 switch target.(type) {
113 case *string:
114 return scanPlanAnyToString{}
115
116 case **string:
117
118
119
120
121
122
123 if wrapperPlan, nextDst, ok := TryPointerPointerScanPlan(target); ok {
124 if nextPlan := m.planScan(oid, format, nextDst); nextPlan != nil {
125 if _, failed := nextPlan.(*scanPlanFail); !failed {
126 wrapperPlan.SetNext(nextPlan)
127 return wrapperPlan
128 }
129 }
130 }
131
132 case *[]byte:
133 return scanPlanJSONToByteSlice{}
134 case BytesScanner:
135 return scanPlanBinaryBytesToBytesScanner{}
136
137
138
139
140 case sql.Scanner:
141 return &scanPlanSQLScanner{formatCode: format}
142 }
143
144 return scanPlanJSONToJSONUnmarshal{}
145 }
146
147 type scanPlanAnyToString struct{}
148
149 func (scanPlanAnyToString) Scan(src []byte, dst any) error {
150 p := dst.(*string)
151 *p = string(src)
152 return nil
153 }
154
155 type scanPlanJSONToByteSlice struct{}
156
157 func (scanPlanJSONToByteSlice) Scan(src []byte, dst any) error {
158 dstBuf := dst.(*[]byte)
159 if src == nil {
160 *dstBuf = nil
161 return nil
162 }
163
164 *dstBuf = make([]byte, len(src))
165 copy(*dstBuf, src)
166 return nil
167 }
168
169 type scanPlanJSONToBytesScanner struct{}
170
171 func (scanPlanJSONToBytesScanner) Scan(src []byte, dst any) error {
172 scanner := (dst).(BytesScanner)
173 return scanner.ScanBytes(src)
174 }
175
176 type scanPlanJSONToJSONUnmarshal struct{}
177
178 func (scanPlanJSONToJSONUnmarshal) Scan(src []byte, dst any) error {
179 if src == nil {
180 dstValue := reflect.ValueOf(dst)
181 if dstValue.Kind() == reflect.Ptr {
182 el := dstValue.Elem()
183 switch el.Kind() {
184 case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Interface:
185 el.Set(reflect.Zero(el.Type()))
186 return nil
187 }
188 }
189
190 return fmt.Errorf("cannot scan NULL into %T", dst)
191 }
192
193 elem := reflect.ValueOf(dst).Elem()
194 elem.Set(reflect.Zero(elem.Type()))
195
196 return json.Unmarshal(src, dst)
197 }
198
199 func (c JSONCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) {
200 if src == nil {
201 return nil, nil
202 }
203
204 dstBuf := make([]byte, len(src))
205 copy(dstBuf, src)
206 return dstBuf, nil
207 }
208
209 func (c JSONCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) {
210 if src == nil {
211 return nil, nil
212 }
213
214 var dst any
215 err := json.Unmarshal(src, &dst)
216 return dst, err
217 }
218
View as plain text