Thank you very much for your help. Following your suggestions and more experimentation, the problem ended up being that I was asserting int, string and bool types rather than *int, *string and *bool types. I should have gotten a not ok back, but apparently not. I will have to figure out why. The other odd thing was that after I fixed the ID field as below, the problem moved to the name field. After that, I ended up changing everything as you see below.
func (p *Person) GetBack(get []string, g []interface{}) error { for i, sp := range get { switch sp { case iD: xID, ok := g[i].(*int) if !ok { return fmt.Errorf("ID (int) type assertion failed") } p.ID = *xID case Name: xName, ok := g[i].(*string) if !ok { return fmt.Errorf("Name (string) type assertion failed") } p.Name = *xName case Email: xEmail, ok := g[i].(*string) if !ok { return fmt.Errorf("Email (string) type assertion failed") } p.Email = *xEmail case HashedPassword: xPass, ok := g[i].(*string) if !ok { return fmt.Errorf("Hashed Password (string) type assertion failed") } p.HashedPassword = *xPass case Created: xCreated, ok := g[i].(*time.Time) if !ok { return fmt.Errorf("Created (time.Time) type assertion failed") } p.Created = *xCreated case Role: xRole, ok := g[i].(*string) if !ok { return fmt.Errorf("Role (string) type assertion failed") } p.Role = *xRole case Active: xActive, ok := g[i].(*bool) if !ok { return fmt.Errorf("Active (bool) type assertion failed") } p.Active = *xActive case Online: xOnline, ok := g[i].(*bool) if !ok { return fmt.Errorf("Online (bool) type assertion failed") } p.Online = *xOnline } } return nil } On Monday, June 8, 2020 at 7:03:14 PM UTC-4, Saied Seghatoleslami wrote: > > 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/cdb7adee-9b11-4332-a1d3-842c86fa52a9o%40googlegroups.com.