@@ -32,111 +32,111 @@ type columnInfo struct {
3232 Format string
3333}
3434
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 )
3737 if err == nil {
38- fieldValue .SetBool (value )
38+ value .SetBool (actualValue )
3939 }
4040
4141 return err
4242}
4343
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 )
4646 if err == nil {
47- fieldValue .SetInt (value )
47+ value .SetInt (actualValue )
4848 }
4949
5050 return err
5151}
5252
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 )
5555 if err == nil {
56- fieldValue .SetUint (value )
56+ value .SetUint (actualValue )
5757 }
5858
5959 return err
6060}
6161
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 )
6464 if err == nil {
65- fieldValue .SetFloat (value )
65+ value .SetFloat (actualValue )
6666 }
6767
6868 return err
6969}
7070
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 )
7373 if err == nil {
74- fieldValue .Set (reflect .ValueOf (value ))
74+ value .Set (reflect .ValueOf (actualValue ))
7575 }
7676
7777 return err
7878}
7979
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 ()
8282
83- switch fieldKind {
83+ switch kind {
8484 case reflect .String :
85- fieldValue .SetString (stringValue )
85+ value .SetString (stringValue )
8686 return nil
8787
8888 case reflect .Bool :
89- return setBoolFieldValue ( fieldValue , stringValue )
89+ return setBoolValue ( value , stringValue )
9090
9191 case reflect .Int :
92- return setIntFieldValue ( fieldValue , stringValue , bits .UintSize )
92+ return setIntValue ( value , stringValue , bits .UintSize )
9393
9494 case reflect .Int8 :
95- return setIntFieldValue ( fieldValue , stringValue , 8 )
95+ return setIntValue ( value , stringValue , 8 )
9696
9797 case reflect .Int16 :
98- return setIntFieldValue ( fieldValue , stringValue , 16 )
98+ return setIntValue ( value , stringValue , 16 )
9999
100100 case reflect .Int32 :
101- return setIntFieldValue ( fieldValue , stringValue , 32 )
101+ return setIntValue ( value , stringValue , 32 )
102102
103103 case reflect .Int64 :
104- return setIntFieldValue ( fieldValue , stringValue , 64 )
104+ return setIntValue ( value , stringValue , 64 )
105105
106106 case reflect .Uint :
107- return setUintFieldValue ( fieldValue , stringValue , bits .UintSize )
107+ return setUintValue ( value , stringValue , bits .UintSize )
108108
109109 case reflect .Uint8 :
110- return setUintFieldValue ( fieldValue , stringValue , 8 )
110+ return setUintValue ( value , stringValue , 8 )
111111
112112 case reflect .Uint16 :
113- return setUintFieldValue ( fieldValue , stringValue , 16 )
113+ return setUintValue ( value , stringValue , 16 )
114114
115115 case reflect .Uint32 :
116- return setUintFieldValue ( fieldValue , stringValue , 32 )
116+ return setUintValue ( value , stringValue , 32 )
117117
118118 case reflect .Uint64 :
119- return setUintFieldValue ( fieldValue , stringValue , 64 )
119+ return setUintValue ( value , stringValue , 64 )
120120
121121 case reflect .Float32 :
122- return setFloatFieldValue ( fieldValue , stringValue , 32 )
122+ return setFloatValue ( value , stringValue , 32 )
123123
124124 case reflect .Float64 :
125- return setFloatFieldValue ( fieldValue , stringValue , 64 )
125+ return setFloatValue ( value , stringValue , 64 )
126126
127127 case reflect .Struct :
128- fieldTypeString := fieldValue .Type ().String ()
128+ typeString := value .Type ().String ()
129129
130- switch fieldTypeString {
130+ switch typeString {
131131 case "time.Time" :
132- return setTimeFieldValue ( fieldValue , stringValue , format )
132+ return setTimeValue ( value , stringValue , format )
133133
134134 default :
135- return fmt .Errorf ("unsupported struct type %s" , fieldTypeString )
135+ return fmt .Errorf ("unsupported struct type %s" , typeString )
136136 }
137137
138138 default :
139- return fmt .Errorf ("unsupported field kind %s" , fieldKind )
139+ return fmt .Errorf ("unsupported value kind %s" , kind )
140140 }
141141}
142142
@@ -227,7 +227,7 @@ func ReadRowsFromReader(reader io.Reader, hasHeader bool, rows interface{}) erro
227227 row := reflect .New (rowType ).Elem ()
228228
229229 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 {
231231 return err
232232 }
233233 }
@@ -251,3 +251,70 @@ func ReadRowsFromFile(fileName string, hasHeader bool, rows interface{}) error {
251251
252252 return ReadRowsFromReader (file , hasHeader , rows )
253253}
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