1 package pgtype
2
3 import (
4 "database/sql/driver"
5 "encoding/json"
6 "fmt"
7 )
8
9 type TextScanner interface {
10 ScanText(v Text) error
11 }
12
13 type TextValuer interface {
14 TextValue() (Text, error)
15 }
16
17 type Text struct {
18 String string
19 Valid bool
20 }
21
22 func (t *Text) ScanText(v Text) error {
23 *t = v
24 return nil
25 }
26
27 func (t Text) TextValue() (Text, error) {
28 return t, nil
29 }
30
31
32 func (dst *Text) Scan(src any) error {
33 if src == nil {
34 *dst = Text{}
35 return nil
36 }
37
38 switch src := src.(type) {
39 case string:
40 *dst = Text{String: src, Valid: true}
41 return nil
42 case []byte:
43 *dst = Text{String: string(src), Valid: true}
44 return nil
45 }
46
47 return fmt.Errorf("cannot scan %T", src)
48 }
49
50
51 func (src Text) Value() (driver.Value, error) {
52 if !src.Valid {
53 return nil, nil
54 }
55 return src.String, nil
56 }
57
58 func (src Text) MarshalJSON() ([]byte, error) {
59 if !src.Valid {
60 return []byte("null"), nil
61 }
62
63 return json.Marshal(src.String)
64 }
65
66 func (dst *Text) UnmarshalJSON(b []byte) error {
67 var s *string
68 err := json.Unmarshal(b, &s)
69 if err != nil {
70 return err
71 }
72
73 if s == nil {
74 *dst = Text{}
75 } else {
76 *dst = Text{String: *s, Valid: true}
77 }
78
79 return nil
80 }
81
82 type TextCodec struct{}
83
84 func (TextCodec) FormatSupported(format int16) bool {
85 return format == TextFormatCode || format == BinaryFormatCode
86 }
87
88 func (TextCodec) PreferredFormat() int16 {
89 return TextFormatCode
90 }
91
92 func (TextCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan {
93 switch format {
94 case TextFormatCode, BinaryFormatCode:
95 switch value.(type) {
96 case string:
97 return encodePlanTextCodecString{}
98 case []byte:
99 return encodePlanTextCodecByteSlice{}
100 case TextValuer:
101 return encodePlanTextCodecTextValuer{}
102 }
103 }
104
105 return nil
106 }
107
108 type encodePlanTextCodecString struct{}
109
110 func (encodePlanTextCodecString) Encode(value any, buf []byte) (newBuf []byte, err error) {
111 s := value.(string)
112 buf = append(buf, s...)
113 return buf, nil
114 }
115
116 type encodePlanTextCodecByteSlice struct{}
117
118 func (encodePlanTextCodecByteSlice) Encode(value any, buf []byte) (newBuf []byte, err error) {
119 s := value.([]byte)
120 buf = append(buf, s...)
121 return buf, nil
122 }
123
124 type encodePlanTextCodecStringer struct{}
125
126 func (encodePlanTextCodecStringer) Encode(value any, buf []byte) (newBuf []byte, err error) {
127 s := value.(fmt.Stringer)
128 buf = append(buf, s.String()...)
129 return buf, nil
130 }
131
132 type encodePlanTextCodecTextValuer struct{}
133
134 func (encodePlanTextCodecTextValuer) Encode(value any, buf []byte) (newBuf []byte, err error) {
135 text, err := value.(TextValuer).TextValue()
136 if err != nil {
137 return nil, err
138 }
139
140 if !text.Valid {
141 return nil, nil
142 }
143
144 buf = append(buf, text.String...)
145 return buf, nil
146 }
147
148 func (TextCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan {
149
150 switch format {
151 case TextFormatCode, BinaryFormatCode:
152 switch target.(type) {
153 case *string:
154 return scanPlanTextAnyToString{}
155 case *[]byte:
156 return scanPlanAnyToNewByteSlice{}
157 case BytesScanner:
158 return scanPlanAnyToByteScanner{}
159 case TextScanner:
160 return scanPlanTextAnyToTextScanner{}
161 }
162 }
163
164 return nil
165 }
166
167 func (c TextCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) {
168 return c.DecodeValue(m, oid, format, src)
169 }
170
171 func (c TextCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) {
172 if src == nil {
173 return nil, nil
174 }
175
176 return string(src), nil
177 }
178
179 type scanPlanTextAnyToString struct{}
180
181 func (scanPlanTextAnyToString) Scan(src []byte, dst any) error {
182 if src == nil {
183 return fmt.Errorf("cannot scan NULL into %T", dst)
184 }
185
186 p := (dst).(*string)
187 *p = string(src)
188
189 return nil
190 }
191
192 type scanPlanAnyToNewByteSlice struct{}
193
194 func (scanPlanAnyToNewByteSlice) Scan(src []byte, dst any) error {
195 p := (dst).(*[]byte)
196 if src == nil {
197 *p = nil
198 } else {
199 *p = make([]byte, len(src))
200 copy(*p, src)
201 }
202
203 return nil
204 }
205
206 type scanPlanAnyToByteScanner struct{}
207
208 func (scanPlanAnyToByteScanner) Scan(src []byte, dst any) error {
209 p := (dst).(BytesScanner)
210 return p.ScanBytes(src)
211 }
212
213 type scanPlanTextAnyToTextScanner struct{}
214
215 func (scanPlanTextAnyToTextScanner) Scan(src []byte, dst any) error {
216 scanner := (dst).(TextScanner)
217
218 if src == nil {
219 return scanner.ScanText(Text{})
220 }
221
222 return scanner.ScanText(Text{String: string(src), Valid: true})
223 }
224
View as plain text