coocood/qbs

FindAll(scanRows) Panic

NuVivo314 opened this issue · 1 comments

Hello,
First one, thank you for your work.

I found a bug in FindAll(qbs.scanRows).
Here is the error:

panic: reflect: call of reflect.Value.FieldByName on zero Value

goroutine 1 [running]:
reflect.flag.mustBe(0x0, 0x19, 0x100000001, 0x0)
        /opt/golang/src/pkg/reflect/value.go:241 +0xa2
reflect.Value.FieldByName(0x0, 0x0, 0x0, 0xf840074fc0, 0x2, ...)
        /opt/golang/src/pkg/reflect/value.go:688 +0x40
github.com/coocood/qbs.(*Qbs).scanRows(0xf840032780, 0x47fa38, 0xf840078440, 0x160, 0xf840077a20, ...)
        ./exp_qbs/src/github.com/coocood/qbs/qbs.go:218 +0x524
github.com/coocood/qbs.(*Qbs).doQueryRows(0xf840032780, 0x47e8b8, 0xf84006e180, 0xf840079000, 0xf8000001ca, ...)
        ./exp_qbs/src/github.com/coocood/qbs/qbs.go:192 +0x3ba
github.com/coocood/qbs.(*Qbs).FindAll(0xf840032780, 0x47e8b8, 0xf84006e180, 0xf84006e180, 0xf840060fc0, ...)
        ./exp_qbs/src/github.com/coocood/qbs/qbs.go:149 +0x1fd
main.main()
        ./exp_qbs/qbs_exp.go:80 +0xdcf

goroutine 2 [syscall]:
created by runtime.main
        /opt/golang/src/pkg/runtime/proc.c:221
exit status 2

Short snippet code:

 tmpFindAll := make([]*Event, 0)
 o.Limit(2).FindAll(&tmpFindAll)

My structure is nested, i thinks is linked.

So I tinker a fix:

diff --git a/qbs.go b/qbs.go
index d989102..2861dc3 100644

--- a/qbs.go
+++ b/qbs.go
@@ -215,9 +215,6 @@ func (q *Qbs) scanRows(rowValue reflect.Value, rows *sql.Rows) (err error) {
                paths := strings.Split(key, "___")
                if len(paths) == 2 {
                        subStruct := rowValue.Elem().FieldByName(snakeToUpperCamel(paths[0]))
+                       if subStruct.IsNil() {
+                               subStruct.Set(reflect.New(subStruct.Type().Elem()))
+                       }
                        subField := subStruct.Elem().FieldByName(snakeToUpperCamel(paths[1]))
                        if subField.IsValid() {
                                err = q.Dialect.SetModelValue(value, subField)

Thank you for your report and fix, I never test FindAll on nested struct. hence the bug.
If you create a pull request, I'll merge it.