I am scanning database tables into a structure explicitly (with &struct.field) that works just fine (working path below).
But my tables have different columns, so I am working to generalize the API. There are two methods that build and reverse a []interface{} to be supplied to scan. I have listed them in the problem path. The last item is the people data in the use case. It scans every column correctly except the first one that is the ID. The problem path always returns zero for the ID field while the working path works fine. I have been staring at it for a day and experimenting with different ideas but no success Any thoughts? //=============================. Working Path ============================= //Person is the target for scan. type Person struct { ID int Name string Email string HashedPassword string Created time.Time Role string Active bool Online bool } //inside the "get" method to get the data person := broker.Person{} for rows.Next() { err := rows.Scan(&person.ID, &person.Name, &person.Email, //g...) &person.HashedPassword, &person.Created, &person.Active) if err != nil { if errors.Is(err, sql.ErrNoRows) { return broker.ErrNoRecord } return err } newPeople = append(newPeople, person) //=============================. Problem Path ============================= person := broker.Person{} g := person.GetItems(e.Get) for rows.Next() { err := rows.Scan(g...) if err != nil { if errors.Is(err, sql.ErrNoRows) { return broker.ErrNoRecord } return err } person.GetBack(e.Get, g) newPeople = append(newPeople, person) //note that iD, Name, Email... are constants //GetItems uses the get string to generate an interface to be passed to the //sql.Execute statement for the INSERT sql command. func (p *Person) GetItems(get []string) []interface{} { var g = []interface{}{} for _, sp := range get { switch sp { case iD: g = append(g, &p.ID) case Name: g = append(g, &p.Name) case Email: g = append(g, &p.Email) case HashedPassword: g = append(g, &p.HashedPassword) case Created: g = append(g, &p.Created) case Role: g = append(g, &p.Role) case Active: g = append(g, &p.Active) case Online: g = append(g, &p.Online) } } return g } //GetBack reverses the get item and takes the interface items and gets the //underlying data back. func (p *Person) GetBack(get []string, g []interface{}) error { var ok bool for i, sp := range get { switch sp { case iD: p.ID, ok = g[i].(int) if !ok { return fmt.Errorf("ID (int) type assertion failed") } case Name: p.Name, ok = g[i].(string) if !ok { return fmt.Errorf("Name (string) type assertion failed") } case Email: p.Email, ok = g[i].(string) if !ok { return fmt.Errorf("Email (string) type assertion failed") } case HashedPassword: p.HashedPassword, ok = g[i].(string) if !ok { return fmt.Errorf("Hashed Password (string) type assertion failed") } case Created: p.Created, ok = g[i].(time.Time) if !ok { return fmt.Errorf("Created (time.Time) type assertion failed") } case Role: p.Role, ok = g[i].(string) if !ok { return fmt.Errorf("Role (string) type assertion failed") } case Active: p.Active, ok = g[i].(bool) if !ok { return fmt.Errorf("Active (bool) type assertion failed") } case Online: p.Online, ok = g[i].(bool) if !ok { return fmt.Errorf("Online (bool) type assertion failed") } } } return nil } exchange := Exchange{ Table: table, Put: []string{}, Spec: []string{iD}, Get: []string{iD, Name, Email, HashedPassword, Created, Active, Online}, People: []Person{ Person{ID: id}, }, Action: "get", } -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/5435cf93-5cc0-481d-8a32-13232c9afd60o%40googlegroups.com.