1 package pgtype
2
3 import (
4 "database/sql/driver"
5 "encoding/binary"
6 "fmt"
7 "math"
8 "strconv"
9
10 "github.com/jackc/pgio"
11 )
12
13 type Float4 struct {
14 Float float32
15 Status Status
16 }
17
18 func (dst *Float4) Set(src interface{}) error {
19 if src == nil {
20 *dst = Float4{Status: Null}
21 return nil
22 }
23
24 if value, ok := src.(interface{ Get() interface{} }); ok {
25 value2 := value.Get()
26 if value2 != value {
27 return dst.Set(value2)
28 }
29 }
30
31 switch value := src.(type) {
32 case float32:
33 *dst = Float4{Float: value, Status: Present}
34 case float64:
35 *dst = Float4{Float: float32(value), Status: Present}
36 case int8:
37 *dst = Float4{Float: float32(value), Status: Present}
38 case uint8:
39 *dst = Float4{Float: float32(value), Status: Present}
40 case int16:
41 *dst = Float4{Float: float32(value), Status: Present}
42 case uint16:
43 *dst = Float4{Float: float32(value), Status: Present}
44 case int32:
45 f32 := float32(value)
46 if int32(f32) == value {
47 *dst = Float4{Float: f32, Status: Present}
48 } else {
49 return fmt.Errorf("%v cannot be exactly represented as float32", value)
50 }
51 case uint32:
52 f32 := float32(value)
53 if uint32(f32) == value {
54 *dst = Float4{Float: f32, Status: Present}
55 } else {
56 return fmt.Errorf("%v cannot be exactly represented as float32", value)
57 }
58 case int64:
59 f32 := float32(value)
60 if int64(f32) == value {
61 *dst = Float4{Float: f32, Status: Present}
62 } else {
63 return fmt.Errorf("%v cannot be exactly represented as float32", value)
64 }
65 case uint64:
66 f32 := float32(value)
67 if uint64(f32) == value {
68 *dst = Float4{Float: f32, Status: Present}
69 } else {
70 return fmt.Errorf("%v cannot be exactly represented as float32", value)
71 }
72 case int:
73 f32 := float32(value)
74 if int(f32) == value {
75 *dst = Float4{Float: f32, Status: Present}
76 } else {
77 return fmt.Errorf("%v cannot be exactly represented as float32", value)
78 }
79 case uint:
80 f32 := float32(value)
81 if uint(f32) == value {
82 *dst = Float4{Float: f32, Status: Present}
83 } else {
84 return fmt.Errorf("%v cannot be exactly represented as float32", value)
85 }
86 case string:
87 num, err := strconv.ParseFloat(value, 32)
88 if err != nil {
89 return err
90 }
91 *dst = Float4{Float: float32(num), Status: Present}
92 case *float64:
93 if value == nil {
94 *dst = Float4{Status: Null}
95 } else {
96 return dst.Set(*value)
97 }
98 case *float32:
99 if value == nil {
100 *dst = Float4{Status: Null}
101 } else {
102 return dst.Set(*value)
103 }
104 case *int8:
105 if value == nil {
106 *dst = Float4{Status: Null}
107 } else {
108 return dst.Set(*value)
109 }
110 case *uint8:
111 if value == nil {
112 *dst = Float4{Status: Null}
113 } else {
114 return dst.Set(*value)
115 }
116 case *int16:
117 if value == nil {
118 *dst = Float4{Status: Null}
119 } else {
120 return dst.Set(*value)
121 }
122 case *uint16:
123 if value == nil {
124 *dst = Float4{Status: Null}
125 } else {
126 return dst.Set(*value)
127 }
128 case *int32:
129 if value == nil {
130 *dst = Float4{Status: Null}
131 } else {
132 return dst.Set(*value)
133 }
134 case *uint32:
135 if value == nil {
136 *dst = Float4{Status: Null}
137 } else {
138 return dst.Set(*value)
139 }
140 case *int64:
141 if value == nil {
142 *dst = Float4{Status: Null}
143 } else {
144 return dst.Set(*value)
145 }
146 case *uint64:
147 if value == nil {
148 *dst = Float4{Status: Null}
149 } else {
150 return dst.Set(*value)
151 }
152 case *int:
153 if value == nil {
154 *dst = Float4{Status: Null}
155 } else {
156 return dst.Set(*value)
157 }
158 case *uint:
159 if value == nil {
160 *dst = Float4{Status: Null}
161 } else {
162 return dst.Set(*value)
163 }
164 case *string:
165 if value == nil {
166 *dst = Float4{Status: Null}
167 } else {
168 return dst.Set(*value)
169 }
170 default:
171 if originalSrc, ok := underlyingNumberType(src); ok {
172 return dst.Set(originalSrc)
173 }
174 return fmt.Errorf("cannot convert %v to Float8", value)
175 }
176
177 return nil
178 }
179
180 func (dst Float4) Get() interface{} {
181 switch dst.Status {
182 case Present:
183 return dst.Float
184 case Null:
185 return nil
186 default:
187 return dst.Status
188 }
189 }
190
191 func (src *Float4) AssignTo(dst interface{}) error {
192 return float64AssignTo(float64(src.Float), src.Status, dst)
193 }
194
195 func (dst *Float4) DecodeText(ci *ConnInfo, src []byte) error {
196 if src == nil {
197 *dst = Float4{Status: Null}
198 return nil
199 }
200
201 n, err := strconv.ParseFloat(string(src), 32)
202 if err != nil {
203 return err
204 }
205
206 *dst = Float4{Float: float32(n), Status: Present}
207 return nil
208 }
209
210 func (dst *Float4) DecodeBinary(ci *ConnInfo, src []byte) error {
211 if src == nil {
212 *dst = Float4{Status: Null}
213 return nil
214 }
215
216 if len(src) != 4 {
217 return fmt.Errorf("invalid length for float4: %v", len(src))
218 }
219
220 n := int32(binary.BigEndian.Uint32(src))
221
222 *dst = Float4{Float: math.Float32frombits(uint32(n)), Status: Present}
223 return nil
224 }
225
226 func (src Float4) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
227 switch src.Status {
228 case Null:
229 return nil, nil
230 case Undefined:
231 return nil, errUndefined
232 }
233
234 buf = append(buf, strconv.FormatFloat(float64(src.Float), 'f', -1, 32)...)
235 return buf, nil
236 }
237
238 func (src Float4) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
239 switch src.Status {
240 case Null:
241 return nil, nil
242 case Undefined:
243 return nil, errUndefined
244 }
245
246 buf = pgio.AppendUint32(buf, math.Float32bits(src.Float))
247 return buf, nil
248 }
249
250
251 func (dst *Float4) Scan(src interface{}) error {
252 if src == nil {
253 *dst = Float4{Status: Null}
254 return nil
255 }
256
257 switch src := src.(type) {
258 case float64:
259 *dst = Float4{Float: float32(src), Status: Present}
260 return nil
261 case string:
262 return dst.DecodeText(nil, []byte(src))
263 case []byte:
264 srcCopy := make([]byte, len(src))
265 copy(srcCopy, src)
266 return dst.DecodeText(nil, srcCopy)
267 }
268
269 return fmt.Errorf("cannot scan %T", src)
270 }
271
272
273 func (src Float4) Value() (driver.Value, error) {
274 switch src.Status {
275 case Present:
276 return float64(src.Float), nil
277 case Null:
278 return nil, nil
279 default:
280 return nil, errUndefined
281 }
282 }
283
View as plain text