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
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(&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.