Skip to content

Instantly share code, notes, and snippets.

@shanemhansen
Created September 6, 2013 19:17
Show Gist options
  • Save shanemhansen/6468600 to your computer and use it in GitHub Desktop.
Save shanemhansen/6468600 to your computer and use it in GitHub Desktop.
diff --git a/sqlx.go b/sqlx.go
index 5ea0a4a..ed0bead 100644
--- a/sqlx.go
+++ b/sqlx.go
@@ -3,7 +3,6 @@ package sqlx
import (
"database/sql"
"errors"
- "fmt"
"io/ioutil"
"log"
"path/filepath"
@@ -713,14 +712,29 @@ func getFieldmap(t reflect.Type) (fm fieldmap, err error) {
var f reflect.StructField
var name string
-
- for i := 0; i < t.NumField(); i++ {
- f = t.Field(i)
- name = strings.ToLower(f.Name)
- if tag := f.Tag.Get("db"); tag != "" {
- name = tag
- }
- fm[name] = i
+ queue := []reflect.Type{t}
+ i:=0
+ for {
+ if len(queue) == 0 {
+ break
+ }
+ t := queue[0]
+ queue = queue[1:]
+ for j:=0; j< t.NumField(); j++ {
+ f = t.Field(j)
+ field_type := f.Type.Kind()
+ if field_type == reflect.Struct {
+ queue = append(queue, f.Type)
+ continue
+ }
+ name = strings.ToLower(f.Name)
+ if tag := f.Tag.Get("db"); tag != "" {
+ name = tag
+ }
+ i++
+ fm[name] = i
+ }
+
}
fieldmapCache[t] = fm
return fm, nil
@@ -735,7 +749,6 @@ func getFields(fm fieldmap, columns []string) ([]int, error) {
// find that name in the struct
num, ok = fm[name]
if !ok {
- fmt.Println(fm)
return fields, errors.New("Could not find name " + name + " in interface")
}
fields[i] = num
@@ -748,9 +761,23 @@ func getFields(fm fieldmap, columns []string) ([]int, error) {
// The values interface must be initialized to the length of fields, ie
// make([]interface{}, len(fields)).
func setValues(fields []int, vptr reflect.Value, values []interface{}) {
- for i, field := range fields {
- values[i] = vptr.Field(field).Addr().Interface()
- }
+ queue := []reflect.Value{vptr}
+ i:=0
+ for {
+ if len(queue) == 0 {
+ break
+ }
+ t := queue[0]
+ queue = queue[1:]
+ for j:=0; j< t.NumField(); j++ {
+ if t.Field(j).Kind() == reflect.Struct {
+ queue = append(queue, t.Field(j))
+ continue
+ }
+ values[i] = t.Field(j).Addr().Interface()
+ i++
+ }
+ }
}
// StructScan's a single Row (result of QueryRowx) into dest
@@ -822,7 +849,6 @@ func StructScan(rows *sql.Rows, dest interface{}) error {
if err != nil {
return err
}
-
columns, err := rows.Columns()
if err != nil {
return err
@@ -838,9 +864,7 @@ func StructScan(rows *sql.Rows, dest interface{}) error {
// create a new struct type (which returns PtrTo) and indirect it
vp = reflect.New(base)
v = reflect.Indirect(vp)
-
setValues(fields, v, values)
-
// scan into the struct field pointers and append to our results
err = rows.Scan(values...)
if err != nil {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment