Skip to content

Commit 71f1195

Browse files
authored
Merge pull request #1338 from volatiletech/fix/panic-struct-ptr
Fix panic with nil pointers in structs to bind
2 parents f10c023 + f0c6c11 commit 71f1195

File tree

2 files changed

+31
-31
lines changed

2 files changed

+31
-31
lines changed

queries/reflect.go

+25-23
Original file line numberDiff line numberDiff line change
@@ -83,27 +83,27 @@ func (q *Query) BindG(ctx context.Context, obj interface{}) error {
8383
//
8484
// Example usage:
8585
//
86-
// type JoinStruct struct {
87-
// // User1 can have it's struct fields bound to since it specifies
88-
// // ,bind in the struct tag, it will look specifically for
89-
// // fields that are prefixed with "user." returning from the query.
90-
// // For example "user.id" column name will bind to User1.ID
91-
// User1 *models.User `boil:"user,bind"`
92-
// // User2 will follow the same rules as noted above except it will use
93-
// // "friend." as the prefix it's looking for.
94-
// User2 *models.User `boil:"friend,bind"`
95-
// // RandomData will not be recursed into to look for fields to
96-
// // bind and will not be bound to because of the - for the name.
97-
// RandomData myStruct `boil:"-"`
98-
// // Date will not be recursed into to look for fields to bind because
99-
// // it does not specify ,bind in the struct tag. But it can be bound to
100-
// // as it does not specify a - for the name.
101-
// Date time.Time
102-
// }
86+
// type JoinStruct struct {
87+
// // User1 can have it's struct fields bound to since it specifies
88+
// // ,bind in the struct tag, it will look specifically for
89+
// // fields that are prefixed with "user." returning from the query.
90+
// // For example "user.id" column name will bind to User1.ID
91+
// User1 *models.User `boil:"user,bind"`
92+
// // User2 will follow the same rules as noted above except it will use
93+
// // "friend." as the prefix it's looking for.
94+
// User2 *models.User `boil:"friend,bind"`
95+
// // RandomData will not be recursed into to look for fields to
96+
// // bind and will not be bound to because of the - for the name.
97+
// RandomData myStruct `boil:"-"`
98+
// // Date will not be recursed into to look for fields to bind because
99+
// // it does not specify ,bind in the struct tag. But it can be bound to
100+
// // as it does not specify a - for the name.
101+
// Date time.Time
102+
// }
103103
//
104-
// models.Users(
105-
// qm.InnerJoin("users as friend on users.friend_id = friend.id")
106-
// ).Bind(&joinStruct)
104+
// models.Users(
105+
// qm.InnerJoin("users as friend on users.friend_id = friend.id")
106+
// ).Bind(&joinStruct)
107107
//
108108
// For custom objects that want to use eager loading, please see the
109109
// loadRelationships function.
@@ -368,6 +368,9 @@ func ptrFromMapping(val reflect.Value, mapping uint64, addressOf bool) reflect.V
368368

369369
val = val.Field(int(v))
370370
if val.Kind() == reflect.Ptr {
371+
if val.IsNil() {
372+
val = reflect.New(val.Type().Elem())
373+
}
371374
val = reflect.Indirect(val)
372375
}
373376
}
@@ -606,8 +609,7 @@ func parseNumeric(s string, t reflect.Type) interface{} {
606609
reflect.Uint32,
607610
reflect.Uint64:
608611
res, err = strconv.ParseUint(s, 0, t.Bits())
609-
case reflect.Float32,
610-
reflect.Float64:
612+
case reflect.Float32, reflect.Float64:
611613
res, err = strconv.ParseFloat(s, t.Bits())
612614
}
613615
if err != nil {
@@ -803,7 +805,7 @@ var specialWordReplacer = strings.NewReplacer(
803805

804806
// unTitleCase attempts to undo a title-cased string.
805807
//
806-
// DO NOT USE THIS METHOD IF YOU CAN AVOID IT
808+
// # DO NOT USE THIS METHOD IF YOU CAN AVOID IT
807809
//
808810
// Normally this would be easy but we have to deal with uppercased words
809811
// of varying lengths. We almost never use this function so it

queries/reflect_test.go

+6-8
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import (
1212
"testing"
1313
"time"
1414

15-
"github.com/volatiletech/sqlboiler/v4/drivers"
1615
"github.com/volatiletech/null/v8"
16+
"github.com/volatiletech/sqlboiler/v4/drivers"
1717

1818
"github.com/DATA-DOG/go-sqlmock"
1919
)
@@ -193,7 +193,7 @@ func testMakeMapping(byt ...byte) uint64 {
193193
func TestMakeStructMapping(t *testing.T) {
194194
t.Parallel()
195195

196-
var testStruct = struct {
196+
testStruct := struct {
197197
LastName string `boil:"different"`
198198
AwesomeName string `boil:"awesome_name"`
199199
Face string `boil:"-"`
@@ -249,8 +249,7 @@ func TestPtrFromMapping(t *testing.T) {
249249
Int: 5,
250250
IntP: new(int),
251251
NestedPtrsP: &NestedPtrs{
252-
Int: 6,
253-
IntP: new(int),
252+
Int: 6,
254253
},
255254
}
256255

@@ -399,10 +398,9 @@ func TestGetBoilTag(t *testing.T) {
399398
func TestBindChecks(t *testing.T) {
400399
t.Parallel()
401400

402-
type useless struct {
403-
}
401+
type useless struct{}
404402

405-
var tests = []struct {
403+
tests := []struct {
406404
BKind bindKind
407405
Fail bool
408406
Obj interface{}
@@ -623,7 +621,7 @@ func TestAssignBytes(t *testing.T) {
623621
t.Parallel()
624622

625623
var dst []byte
626-
var src = []byte("hello")
624+
src := []byte("hello")
627625

628626
Assign(&dst, src)
629627
if !bytes.Equal(dst, src) {

0 commit comments

Comments
 (0)