remove unused files
[platform/upstream/gcc48.git] / libgo / go / database / sql / convert.go
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Type conversions for Scan.
6
7 package sql
8
9 import (
10         "database/sql/driver"
11         "errors"
12         "fmt"
13         "reflect"
14         "strconv"
15 )
16
17 var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
18
19 // driverArgs converts arguments from callers of Stmt.Exec and
20 // Stmt.Query into driver Values.
21 //
22 // The statement ds may be nil, if no statement is available.
23 func driverArgs(ds *driverStmt, args []interface{}) ([]driver.Value, error) {
24         dargs := make([]driver.Value, len(args))
25         var si driver.Stmt
26         if ds != nil {
27                 si = ds.si
28         }
29         cc, ok := si.(driver.ColumnConverter)
30
31         // Normal path, for a driver.Stmt that is not a ColumnConverter.
32         if !ok {
33                 for n, arg := range args {
34                         var err error
35                         dargs[n], err = driver.DefaultParameterConverter.ConvertValue(arg)
36                         if err != nil {
37                                 return nil, fmt.Errorf("sql: converting Exec argument #%d's type: %v", n, err)
38                         }
39                 }
40                 return dargs, nil
41         }
42
43         // Let the Stmt convert its own arguments.
44         for n, arg := range args {
45                 // First, see if the value itself knows how to convert
46                 // itself to a driver type.  For example, a NullString
47                 // struct changing into a string or nil.
48                 if svi, ok := arg.(driver.Valuer); ok {
49                         sv, err := svi.Value()
50                         if err != nil {
51                                 return nil, fmt.Errorf("sql: argument index %d from Value: %v", n, err)
52                         }
53                         if !driver.IsValue(sv) {
54                                 return nil, fmt.Errorf("sql: argument index %d: non-subset type %T returned from Value", n, sv)
55                         }
56                         arg = sv
57                 }
58
59                 // Second, ask the column to sanity check itself. For
60                 // example, drivers might use this to make sure that
61                 // an int64 values being inserted into a 16-bit
62                 // integer field is in range (before getting
63                 // truncated), or that a nil can't go into a NOT NULL
64                 // column before going across the network to get the
65                 // same error.
66                 var err error
67                 ds.Lock()
68                 dargs[n], err = cc.ColumnConverter(n).ConvertValue(arg)
69                 ds.Unlock()
70                 if err != nil {
71                         return nil, fmt.Errorf("sql: converting argument #%d's type: %v", n, err)
72                 }
73                 if !driver.IsValue(dargs[n]) {
74                         return nil, fmt.Errorf("sql: driver ColumnConverter error converted %T to unsupported type %T",
75                                 arg, dargs[n])
76                 }
77         }
78
79         return dargs, nil
80 }
81
82 // convertAssign copies to dest the value in src, converting it if possible.
83 // An error is returned if the copy would result in loss of information.
84 // dest should be a pointer type.
85 func convertAssign(dest, src interface{}) error {
86         // Common cases, without reflect.
87         switch s := src.(type) {
88         case string:
89                 switch d := dest.(type) {
90                 case *string:
91                         if d == nil {
92                                 return errNilPtr
93                         }
94                         *d = s
95                         return nil
96                 case *[]byte:
97                         if d == nil {
98                                 return errNilPtr
99                         }
100                         *d = []byte(s)
101                         return nil
102                 }
103         case []byte:
104                 switch d := dest.(type) {
105                 case *string:
106                         if d == nil {
107                                 return errNilPtr
108                         }
109                         *d = string(s)
110                         return nil
111                 case *interface{}:
112                         if d == nil {
113                                 return errNilPtr
114                         }
115                         *d = cloneBytes(s)
116                         return nil
117                 case *[]byte:
118                         if d == nil {
119                                 return errNilPtr
120                         }
121                         *d = cloneBytes(s)
122                         return nil
123                 case *RawBytes:
124                         if d == nil {
125                                 return errNilPtr
126                         }
127                         *d = s
128                         return nil
129                 }
130         case nil:
131                 switch d := dest.(type) {
132                 case *interface{}:
133                         if d == nil {
134                                 return errNilPtr
135                         }
136                         *d = nil
137                         return nil
138                 case *[]byte:
139                         if d == nil {
140                                 return errNilPtr
141                         }
142                         *d = nil
143                         return nil
144                 case *RawBytes:
145                         if d == nil {
146                                 return errNilPtr
147                         }
148                         *d = nil
149                         return nil
150                 }
151         }
152
153         var sv reflect.Value
154
155         switch d := dest.(type) {
156         case *string:
157                 sv = reflect.ValueOf(src)
158                 switch sv.Kind() {
159                 case reflect.Bool,
160                         reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
161                         reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
162                         reflect.Float32, reflect.Float64:
163                         *d = fmt.Sprintf("%v", src)
164                         return nil
165                 }
166         case *[]byte:
167                 sv = reflect.ValueOf(src)
168                 switch sv.Kind() {
169                 case reflect.Bool,
170                         reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
171                         reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
172                         reflect.Float32, reflect.Float64:
173                         *d = []byte(fmt.Sprintf("%v", src))
174                         return nil
175                 }
176         case *RawBytes:
177                 sv = reflect.ValueOf(src)
178                 switch sv.Kind() {
179                 case reflect.Bool,
180                         reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
181                         reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
182                         reflect.Float32, reflect.Float64:
183                         *d = RawBytes(fmt.Sprintf("%v", src))
184                         return nil
185                 }
186         case *bool:
187                 bv, err := driver.Bool.ConvertValue(src)
188                 if err == nil {
189                         *d = bv.(bool)
190                 }
191                 return err
192         case *interface{}:
193                 *d = src
194                 return nil
195         }
196
197         if scanner, ok := dest.(Scanner); ok {
198                 return scanner.Scan(src)
199         }
200
201         dpv := reflect.ValueOf(dest)
202         if dpv.Kind() != reflect.Ptr {
203                 return errors.New("destination not a pointer")
204         }
205         if dpv.IsNil() {
206                 return errNilPtr
207         }
208
209         if !sv.IsValid() {
210                 sv = reflect.ValueOf(src)
211         }
212
213         dv := reflect.Indirect(dpv)
214         if dv.Kind() == sv.Kind() {
215                 dv.Set(sv)
216                 return nil
217         }
218
219         switch dv.Kind() {
220         case reflect.Ptr:
221                 if src == nil {
222                         dv.Set(reflect.Zero(dv.Type()))
223                         return nil
224                 } else {
225                         dv.Set(reflect.New(dv.Type().Elem()))
226                         return convertAssign(dv.Interface(), src)
227                 }
228         case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
229                 s := asString(src)
230                 i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
231                 if err != nil {
232                         return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
233                 }
234                 dv.SetInt(i64)
235                 return nil
236         case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
237                 s := asString(src)
238                 u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
239                 if err != nil {
240                         return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
241                 }
242                 dv.SetUint(u64)
243                 return nil
244         case reflect.Float32, reflect.Float64:
245                 s := asString(src)
246                 f64, err := strconv.ParseFloat(s, dv.Type().Bits())
247                 if err != nil {
248                         return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
249                 }
250                 dv.SetFloat(f64)
251                 return nil
252         }
253
254         return fmt.Errorf("unsupported driver -> Scan pair: %T -> %T", src, dest)
255 }
256
257 func cloneBytes(b []byte) []byte {
258         if b == nil {
259                 return nil
260         } else {
261                 c := make([]byte, len(b))
262                 copy(c, b)
263                 return c
264         }
265 }
266
267 func asString(src interface{}) string {
268         switch v := src.(type) {
269         case string:
270                 return v
271         case []byte:
272                 return string(v)
273         }
274         return fmt.Sprintf("%v", src)
275 }