...
1 package pgtype
2
3 import (
4 "database/sql/driver"
5 "encoding/hex"
6 "fmt"
7 )
8
9 type Bytea struct {
10 Bytes []byte
11 Status Status
12 }
13
14 func (dst *Bytea) Set(src interface{}) error {
15 if src == nil {
16 *dst = Bytea{Status: Null}
17 return nil
18 }
19
20 if value, ok := src.(interface{ Get() interface{} }); ok {
21 value2 := value.Get()
22 if value2 != value {
23 return dst.Set(value2)
24 }
25 }
26
27 switch value := src.(type) {
28 case []byte:
29 if value != nil {
30 *dst = Bytea{Bytes: value, Status: Present}
31 } else {
32 *dst = Bytea{Status: Null}
33 }
34 default:
35 if originalSrc, ok := underlyingBytesType(src); ok {
36 return dst.Set(originalSrc)
37 }
38 return fmt.Errorf("cannot convert %v to Bytea", value)
39 }
40
41 return nil
42 }
43
44 func (dst Bytea) Get() interface{} {
45 switch dst.Status {
46 case Present:
47 return dst.Bytes
48 case Null:
49 return nil
50 default:
51 return dst.Status
52 }
53 }
54
55 func (src *Bytea) AssignTo(dst interface{}) error {
56 switch src.Status {
57 case Present:
58 switch v := dst.(type) {
59 case *[]byte:
60 buf := make([]byte, len(src.Bytes))
61 copy(buf, src.Bytes)
62 *v = buf
63 return nil
64 default:
65 if nextDst, retry := GetAssignToDstType(dst); retry {
66 return src.AssignTo(nextDst)
67 }
68 return fmt.Errorf("unable to assign to %T", dst)
69 }
70 case Null:
71 return NullAssignTo(dst)
72 }
73
74 return fmt.Errorf("cannot decode %#v into %T", src, dst)
75 }
76
77
78
79 func (dst *Bytea) DecodeText(ci *ConnInfo, src []byte) error {
80 if src == nil {
81 *dst = Bytea{Status: Null}
82 return nil
83 }
84
85 if len(src) < 2 || src[0] != '\\' || src[1] != 'x' {
86 return fmt.Errorf("invalid hex format")
87 }
88
89 buf := make([]byte, (len(src)-2)/2)
90 _, err := hex.Decode(buf, src[2:])
91 if err != nil {
92 return err
93 }
94
95 *dst = Bytea{Bytes: buf, Status: Present}
96 return nil
97 }
98
99 func (dst *Bytea) DecodeBinary(ci *ConnInfo, src []byte) error {
100 if src == nil {
101 *dst = Bytea{Status: Null}
102 return nil
103 }
104
105 *dst = Bytea{Bytes: src, Status: Present}
106 return nil
107 }
108
109 func (src Bytea) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) {
110 switch src.Status {
111 case Null:
112 return nil, nil
113 case Undefined:
114 return nil, errUndefined
115 }
116
117 buf = append(buf, `\x`...)
118 buf = append(buf, hex.EncodeToString(src.Bytes)...)
119 return buf, nil
120 }
121
122 func (src Bytea) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) {
123 switch src.Status {
124 case Null:
125 return nil, nil
126 case Undefined:
127 return nil, errUndefined
128 }
129
130 return append(buf, src.Bytes...), nil
131 }
132
133
134 func (dst *Bytea) Scan(src interface{}) error {
135 if src == nil {
136 *dst = Bytea{Status: Null}
137 return nil
138 }
139
140 switch src := src.(type) {
141 case string:
142 return dst.DecodeText(nil, []byte(src))
143 case []byte:
144 buf := make([]byte, len(src))
145 copy(buf, src)
146 *dst = Bytea{Bytes: buf, Status: Present}
147 return nil
148 }
149
150 return fmt.Errorf("cannot scan %T", src)
151 }
152
153
154 func (src Bytea) Value() (driver.Value, error) {
155 switch src.Status {
156 case Present:
157 return src.Bytes, nil
158 case Null:
159 return nil, nil
160 default:
161 return nil, errUndefined
162 }
163 }
164
View as plain text