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
> ) 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
> Createdtime.Time
> Role string
> Active bool
> Online bool
> }
>
> //inside the "get" method to get the data
>
> person := broker.Person{}
> for rows.Next() {
> err := rows.Scan(, , , //g...)
> , , )
> 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, )
> case Name:
> g = append(g, )
> case Email:
> g = append(g, )
> case HashedPassword:
> g = append(g, )
> case Created:
> g = append(g, )
> case Role:
> g = append(g, )
> case Active:
> g = append(g, )
> case Online:
> g = append(g, )
> }
> }
> 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