0
votes

I'm trying to learn Go. I'm working to unmarshal CSV records into structs so that I can then create inserts and import this data into my DB.

I am looking for a way to automate marshaling, in a similar manner as encoding

When I run main, I am receiving an error

panic: strconv.ParseInt: parsing "id": invalid syntax

I've written some code which is supposed to unmarshal my .csv records to struct

func Unmarshal(reader *csv.Reader, v interface{}) error {
    record, err := reader.Read()
    if err != nil {
        return err
    }
    s := reflect.ValueOf(v).Elem()
    if s.NumField() != len(record) {
        return &FieldMismatch{s.NumField(), len(record)}
    }
    for i := 0; i < s.NumField(); i++ {
        f := s.Field(i)
        switch f.Type().String() {
        case "string":
            f.SetString(record[i])
        case "int":
            ival, err := strconv.ParseInt(record[i], 10, 0)
            if err != nil {
                return err
            }
            f.SetInt(ival)
        default:
            return &UnsupportedType{f.Type().String()}
        }
    }
    return nil
}

I created this struct in another file:

type InsertToDatabase struct {
    ID         int `csv:"id"`
    groupId    int `csv:"group_id"`
    Name    string `csv:"name"`
    Status int `csv:"status"`
}

When main is run, it should run this bit of code and then parse through my .csv file to create inserts, which are then ran on my local DB.

var InsertTest InsertToDatabase
    reader := csv.NewReader(file)
    for {
        err := Unmarshal(reader, &InsertTest)
        if err == io.EOF {
            break
        }
        if err != nil {
            panic(err)
        }
        channel <- InsertTest
    }
}

Is there a way to improve readability of this code? Also, should I loop and call .Read to process one line at a time?

1

1 Answers

1
votes

When I run main, I am receiving an error

panic: strconv.ParseInt: parsing "id": invalid syntax

I would guess you are parsing the header line of the CSV file by accident.