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