Created
September 6, 2013 19:17
-
-
Save shanemhansen/6468600 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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