Allow binding to []struct, not just []*struct
This commit is contained in:
parent
08dc7a5cc1
commit
e0ea582e37
2 changed files with 100 additions and 2 deletions
|
@ -188,7 +188,7 @@ func bind(rows *sql.Rows, obj interface{}, structType, sliceType reflect.Type, b
|
||||||
|
|
||||||
var ptrSlice reflect.Value
|
var ptrSlice reflect.Value
|
||||||
switch bkind {
|
switch bkind {
|
||||||
case kindPtrSliceStruct:
|
case kindSliceStruct, kindPtrSliceStruct:
|
||||||
ptrSlice = reflect.Indirect(reflect.ValueOf(obj))
|
ptrSlice = reflect.Indirect(reflect.ValueOf(obj))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +211,11 @@ func bind(rows *sql.Rows, obj interface{}, structType, sliceType reflect.Type, b
|
||||||
mut.Unlock()
|
mut.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var oneStruct reflect.Value
|
||||||
|
if bkind == kindSliceStruct {
|
||||||
|
oneStruct = reflect.Indirect(reflect.New(structType))
|
||||||
|
}
|
||||||
|
|
||||||
foundOne := false
|
foundOne := false
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
foundOne = true
|
foundOne = true
|
||||||
|
@ -220,6 +225,8 @@ func bind(rows *sql.Rows, obj interface{}, structType, sliceType reflect.Type, b
|
||||||
switch bkind {
|
switch bkind {
|
||||||
case kindStruct:
|
case kindStruct:
|
||||||
pointers = ptrsFromMapping(reflect.Indirect(reflect.ValueOf(obj)), mapping)
|
pointers = ptrsFromMapping(reflect.Indirect(reflect.ValueOf(obj)), mapping)
|
||||||
|
case kindSliceStruct:
|
||||||
|
pointers = ptrsFromMapping(oneStruct, mapping)
|
||||||
case kindPtrSliceStruct:
|
case kindPtrSliceStruct:
|
||||||
newStruct = reflect.New(structType)
|
newStruct = reflect.New(structType)
|
||||||
pointers = ptrsFromMapping(reflect.Indirect(newStruct), mapping)
|
pointers = ptrsFromMapping(reflect.Indirect(newStruct), mapping)
|
||||||
|
@ -233,6 +240,8 @@ func bind(rows *sql.Rows, obj interface{}, structType, sliceType reflect.Type, b
|
||||||
}
|
}
|
||||||
|
|
||||||
switch bkind {
|
switch bkind {
|
||||||
|
case kindSliceStruct:
|
||||||
|
ptrSlice.Set(reflect.Append(ptrSlice, oneStruct))
|
||||||
case kindPtrSliceStruct:
|
case kindPtrSliceStruct:
|
||||||
ptrSlice.Set(reflect.Append(ptrSlice, newStruct))
|
ptrSlice.Set(reflect.Append(ptrSlice, newStruct))
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,96 @@ type mockRowMaker struct {
|
||||||
rows []driver.Value
|
rows []driver.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBind(t *testing.T) {
|
func TestBindStruct(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testResults := struct {
|
||||||
|
ID int
|
||||||
|
Name string `boil:"test"`
|
||||||
|
}{}
|
||||||
|
|
||||||
|
query := &Query{
|
||||||
|
from: []string{"fun"},
|
||||||
|
}
|
||||||
|
|
||||||
|
db, mock, err := sqlmock.New()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := sqlmock.NewRows([]string{"id", "test"})
|
||||||
|
ret.AddRow(driver.Value(int64(35)), driver.Value("pat"))
|
||||||
|
mock.ExpectQuery(`SELECT \* FROM "fun";`).WillReturnRows(ret)
|
||||||
|
|
||||||
|
SetExecutor(query, db)
|
||||||
|
err = query.Bind(&testResults)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if id := testResults.ID; id != 35 {
|
||||||
|
t.Error("wrong ID:", id)
|
||||||
|
}
|
||||||
|
if name := testResults.Name; name != "pat" {
|
||||||
|
t.Error("wrong name:", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBindSlice(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testResults := []struct {
|
||||||
|
ID int
|
||||||
|
Name string `boil:"test"`
|
||||||
|
}{}
|
||||||
|
|
||||||
|
query := &Query{
|
||||||
|
from: []string{"fun"},
|
||||||
|
}
|
||||||
|
|
||||||
|
db, mock, err := sqlmock.New()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := sqlmock.NewRows([]string{"id", "test"})
|
||||||
|
ret.AddRow(driver.Value(int64(35)), driver.Value("pat"))
|
||||||
|
ret.AddRow(driver.Value(int64(12)), driver.Value("cat"))
|
||||||
|
mock.ExpectQuery(`SELECT \* FROM "fun";`).WillReturnRows(ret)
|
||||||
|
|
||||||
|
SetExecutor(query, db)
|
||||||
|
err = query.Bind(&testResults)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(testResults) != 2 {
|
||||||
|
t.Fatal("wrong number of results:", len(testResults))
|
||||||
|
}
|
||||||
|
if id := testResults[0].ID; id != 35 {
|
||||||
|
t.Error("wrong ID:", id)
|
||||||
|
}
|
||||||
|
if name := testResults[0].Name; name != "pat" {
|
||||||
|
t.Error("wrong name:", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if id := testResults[1].ID; id != 12 {
|
||||||
|
t.Error("wrong ID:", id)
|
||||||
|
}
|
||||||
|
if name := testResults[1].Name; name != "cat" {
|
||||||
|
t.Error("wrong name:", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBindPtrSlice(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testResults := []*struct {
|
testResults := []*struct {
|
||||||
|
|
Loading…
Reference in a new issue