@@ -32,111 +32,111 @@ type columnInfo struct {
32
32
Format string
33
33
}
34
34
35
- func setBoolFieldValue ( fieldValue reflect.Value , stringValue string ) error {
36
- value , err := strconv .ParseBool (stringValue )
35
+ func setBoolValue ( value reflect.Value , stringValue string ) error {
36
+ actualValue , err := strconv .ParseBool (stringValue )
37
37
if err == nil {
38
- fieldValue .SetBool (value )
38
+ value .SetBool (actualValue )
39
39
}
40
40
41
41
return err
42
42
}
43
43
44
- func setIntFieldValue ( fieldValue reflect.Value , stringValue string , bitSize int ) error {
45
- value , err := strconv .ParseInt (stringValue , 10 , bitSize )
44
+ func setIntValue ( value reflect.Value , stringValue string , bitSize int ) error {
45
+ actualValue , err := strconv .ParseInt (stringValue , 10 , bitSize )
46
46
if err == nil {
47
- fieldValue .SetInt (value )
47
+ value .SetInt (actualValue )
48
48
}
49
49
50
50
return err
51
51
}
52
52
53
- func setUintFieldValue ( fieldValue reflect.Value , stringValue string , bitSize int ) error {
54
- value , err := strconv .ParseUint (stringValue , 10 , bitSize )
53
+ func setUintValue ( value reflect.Value , stringValue string , bitSize int ) error {
54
+ actualValue , err := strconv .ParseUint (stringValue , 10 , bitSize )
55
55
if err == nil {
56
- fieldValue .SetUint (value )
56
+ value .SetUint (actualValue )
57
57
}
58
58
59
59
return err
60
60
}
61
61
62
- func setFloatFieldValue ( fieldValue reflect.Value , stringValue string , bitSize int ) error {
63
- value , err := strconv .ParseFloat (stringValue , bitSize )
62
+ func setFloatValue ( value reflect.Value , stringValue string , bitSize int ) error {
63
+ actualValue , err := strconv .ParseFloat (stringValue , bitSize )
64
64
if err == nil {
65
- fieldValue .SetFloat (value )
65
+ value .SetFloat (actualValue )
66
66
}
67
67
68
68
return err
69
69
}
70
70
71
- func setTimeFieldValue ( fieldValue reflect.Value , stringValue string , format string ) error {
72
- value , err := time .Parse (format , stringValue )
71
+ func setTimeValue ( value reflect.Value , stringValue string , format string ) error {
72
+ actualValue , err := time .Parse (format , stringValue )
73
73
if err == nil {
74
- fieldValue .Set (reflect .ValueOf (value ))
74
+ value .Set (reflect .ValueOf (actualValue ))
75
75
}
76
76
77
77
return err
78
78
}
79
79
80
- func setFieldValue ( fieldValue reflect.Value , stringValue string , format string ) error {
81
- fieldKind := fieldValue .Kind ()
80
+ func setValue ( value reflect.Value , stringValue string , format string ) error {
81
+ kind := value .Kind ()
82
82
83
- switch fieldKind {
83
+ switch kind {
84
84
case reflect .String :
85
- fieldValue .SetString (stringValue )
85
+ value .SetString (stringValue )
86
86
return nil
87
87
88
88
case reflect .Bool :
89
- return setBoolFieldValue ( fieldValue , stringValue )
89
+ return setBoolValue ( value , stringValue )
90
90
91
91
case reflect .Int :
92
- return setIntFieldValue ( fieldValue , stringValue , bits .UintSize )
92
+ return setIntValue ( value , stringValue , bits .UintSize )
93
93
94
94
case reflect .Int8 :
95
- return setIntFieldValue ( fieldValue , stringValue , 8 )
95
+ return setIntValue ( value , stringValue , 8 )
96
96
97
97
case reflect .Int16 :
98
- return setIntFieldValue ( fieldValue , stringValue , 16 )
98
+ return setIntValue ( value , stringValue , 16 )
99
99
100
100
case reflect .Int32 :
101
- return setIntFieldValue ( fieldValue , stringValue , 32 )
101
+ return setIntValue ( value , stringValue , 32 )
102
102
103
103
case reflect .Int64 :
104
- return setIntFieldValue ( fieldValue , stringValue , 64 )
104
+ return setIntValue ( value , stringValue , 64 )
105
105
106
106
case reflect .Uint :
107
- return setUintFieldValue ( fieldValue , stringValue , bits .UintSize )
107
+ return setUintValue ( value , stringValue , bits .UintSize )
108
108
109
109
case reflect .Uint8 :
110
- return setUintFieldValue ( fieldValue , stringValue , 8 )
110
+ return setUintValue ( value , stringValue , 8 )
111
111
112
112
case reflect .Uint16 :
113
- return setUintFieldValue ( fieldValue , stringValue , 16 )
113
+ return setUintValue ( value , stringValue , 16 )
114
114
115
115
case reflect .Uint32 :
116
- return setUintFieldValue ( fieldValue , stringValue , 32 )
116
+ return setUintValue ( value , stringValue , 32 )
117
117
118
118
case reflect .Uint64 :
119
- return setUintFieldValue ( fieldValue , stringValue , 64 )
119
+ return setUintValue ( value , stringValue , 64 )
120
120
121
121
case reflect .Float32 :
122
- return setFloatFieldValue ( fieldValue , stringValue , 32 )
122
+ return setFloatValue ( value , stringValue , 32 )
123
123
124
124
case reflect .Float64 :
125
- return setFloatFieldValue ( fieldValue , stringValue , 64 )
125
+ return setFloatValue ( value , stringValue , 64 )
126
126
127
127
case reflect .Struct :
128
- fieldTypeString := fieldValue .Type ().String ()
128
+ typeString := value .Type ().String ()
129
129
130
- switch fieldTypeString {
130
+ switch typeString {
131
131
case "time.Time" :
132
- return setTimeFieldValue ( fieldValue , stringValue , format )
132
+ return setTimeValue ( value , stringValue , format )
133
133
134
134
default :
135
- return fmt .Errorf ("unsupported struct type %s" , fieldTypeString )
135
+ return fmt .Errorf ("unsupported struct type %s" , typeString )
136
136
}
137
137
138
138
default :
139
- return fmt .Errorf ("unsupported field kind %s" , fieldKind )
139
+ return fmt .Errorf ("unsupported value kind %s" , kind )
140
140
}
141
141
}
142
142
@@ -227,7 +227,7 @@ func ReadRowsFromReader(reader io.Reader, hasHeader bool, rows interface{}) erro
227
227
row := reflect .New (rowType ).Elem ()
228
228
229
229
for _ , column := range columns {
230
- if err = setFieldValue (row .Field (column .FieldIndex ), record [column .ColumnIndex ], column .Format ); err != nil {
230
+ if err = setValue (row .Field (column .FieldIndex ), record [column .ColumnIndex ], column .Format ); err != nil {
231
231
return err
232
232
}
233
233
}
@@ -251,3 +251,70 @@ func ReadRowsFromFile(fileName string, hasHeader bool, rows interface{}) error {
251
251
252
252
return ReadRowsFromReader (file , hasHeader , rows )
253
253
}
254
+
255
+ // Read table from reader.
256
+ func ReadTableFromReader (reader io.Reader , hasHeader bool , table interface {}) error {
257
+ tablePtrType := reflect .TypeOf (table )
258
+ if tablePtrType .Kind () != reflect .Ptr {
259
+ return errors .New ("table not a pointer" )
260
+ }
261
+
262
+ tableType := tablePtrType .Elem ()
263
+ if tableType .Kind () != reflect .Struct {
264
+ return errors .New ("table not a pointer to struct" )
265
+ }
266
+
267
+ for i := 0 ; i < tableType .NumField (); i ++ {
268
+ if tableType .Field (i ).Type .Kind () != reflect .Slice {
269
+ return errors .New ("table fields must be all slices" )
270
+ }
271
+ }
272
+
273
+ tableValue := reflect .ValueOf (table ).Elem ()
274
+
275
+ columns := getStructFieldsAsColumns (tableType )
276
+
277
+ csvReader := csv .NewReader (reader )
278
+
279
+ if hasHeader {
280
+ if err := readHeader (* csvReader , columns ); err != nil {
281
+ return err
282
+ }
283
+ }
284
+
285
+ for {
286
+ record , err := csvReader .Read ()
287
+ if err == io .EOF {
288
+ break
289
+ }
290
+
291
+ if err != nil {
292
+ return err
293
+ }
294
+
295
+ for _ , column := range columns {
296
+ sliceValue := tableValue .Field (column .FieldIndex )
297
+
298
+ itemValue := reflect .New (sliceValue .Type ().Elem ()).Elem ()
299
+ if err = setValue (itemValue , record [column .ColumnIndex ], column .Format ); err != nil {
300
+ return err
301
+ }
302
+
303
+ sliceValue .Set (reflect .Append (sliceValue , itemValue ))
304
+ }
305
+ }
306
+
307
+ return nil
308
+ }
309
+
310
+ // Read table from file.
311
+ func ReadTableFromFile (fileName string , hasHeader bool , rows interface {}) error {
312
+ file , err := os .Open (fileName )
313
+ if err != nil {
314
+ return err
315
+ }
316
+
317
+ defer file .Close ()
318
+
319
+ return ReadTableFromReader (file , hasHeader , rows )
320
+ }
0 commit comments