Execution additional tests.

This commit is contained in:
go-jet 2019-08-13 17:20:35 +02:00
parent 486e45db5c
commit 13c671fa3f
3 changed files with 68 additions and 28 deletions

View file

@ -115,7 +115,7 @@ func mapRowToSlice(scanContext *scanContext, groupKey string, slicePtrValue refl
return return
} }
utils.TypeMustBe(sliceElemType, reflect.Struct, "jet: unsupported slice element type at '"+fieldToString(field)+"'.") utils.TypeMustBe(sliceElemType, reflect.Struct, "jet: unsupported slice element type"+fieldToString(field))
structGroupKey := scanContext.getGroupKey(sliceElemType, field) structGroupKey := scanContext.getGroupKey(sliceElemType, field)
@ -270,7 +270,7 @@ func mapRowToStruct(scanContext *scanContext, groupKey string, structPtrValue re
err = scanner.Scan(cellValue) err = scanner.Scan(cellValue)
if err != nil { if err != nil {
err = fmt.Errorf("%s, at struct field: %s %s of type %s. ", err.Error(), field.Name, field.Type.String(), structType.String()) panic("jet: " + err.Error() + ", " + fieldToString(&field) + " of type " + structType.String())
return return
} }
updated = true updated = true
@ -280,12 +280,7 @@ func mapRowToStruct(scanContext *scanContext, groupKey string, structPtrValue re
if cellValue != nil { if cellValue != nil {
updated = true updated = true
initializeValueIfNilPtr(fieldValue) initializeValueIfNilPtr(fieldValue)
err = setReflectValue(reflect.ValueOf(cellValue), fieldValue) setReflectValue(reflect.ValueOf(cellValue), fieldValue)
if err != nil {
err = fmt.Errorf("%s, at struct field: %s %s of type %s. ", err.Error(), field.Name, field.Type.String(), structType.String())
return
}
} }
} }
} }
@ -381,7 +376,7 @@ func getSliceElemPtrAt(slicePtrValue reflect.Value, index int) reflect.Value {
func appendElemToSlice(slicePtrValue reflect.Value, objPtrValue reflect.Value) error { func appendElemToSlice(slicePtrValue reflect.Value, objPtrValue reflect.Value) error {
if slicePtrValue.IsNil() { if slicePtrValue.IsNil() {
panic("Slice is nil") panic("jet: internal, slice is nil")
} }
sliceValue := slicePtrValue.Elem() sliceValue := slicePtrValue.Elem()
sliceElemType := sliceValue.Type().Elem() sliceElemType := sliceValue.Type().Elem()
@ -392,8 +387,12 @@ func appendElemToSlice(slicePtrValue reflect.Value, objPtrValue reflect.Value) e
newElemValue = objPtrValue.Elem() newElemValue = objPtrValue.Elem()
} }
if newElemValue.Type().ConvertibleTo(sliceElemType) {
newElemValue = newElemValue.Convert(sliceElemType)
}
if !newElemValue.Type().AssignableTo(sliceElemType) { if !newElemValue.Type().AssignableTo(sliceElemType) {
return fmt.Errorf("jet: can't append %s to %s slice ", newElemValue.Type().String(), sliceValue.Type().String()) panic("jet: can't append " + newElemValue.Type().String() + " to " + sliceValue.Type().String() + " slice")
} }
sliceValue.Set(reflect.Append(sliceValue, newElemValue)) sliceValue.Set(reflect.Append(sliceValue, newElemValue))
@ -473,7 +472,7 @@ func valueToString(value reflect.Value) string {
valueInterface = value.Interface() valueInterface = value.Interface()
} }
if t, ok := valueInterface.(time.Time); ok { if t, ok := valueInterface.(fmt.Stringer); ok {
return t.String() return t.String()
} }
@ -535,21 +534,24 @@ func tryAssign(source, destination reflect.Value) bool {
return false return false
} }
func setReflectValue(source, destination reflect.Value) error { func setReflectValue(source, destination reflect.Value) {
if tryAssign(source, destination) { if tryAssign(source, destination) {
return nil return
} }
if destination.Kind() == reflect.Ptr { if destination.Kind() == reflect.Ptr {
if source.Kind() == reflect.Ptr { if source.Kind() == reflect.Ptr {
if !source.IsNil() { if !source.IsNil() {
if destination.IsNil() { if destination.IsNil() {
initializeValueIfNilPtr(destination) initializeValueIfNilPtr(destination)
} }
tryAssign(source.Elem(), destination.Elem()) if tryAssign(source.Elem(), destination.Elem()) {
return
}
} else {
return
} }
} else { } else {
if source.CanAddr() { if source.CanAddr() {
@ -562,20 +564,23 @@ func setReflectValue(source, destination reflect.Value) error {
} }
if tryAssign(source, destination) { if tryAssign(source, destination) {
return nil return
} }
if tryAssign(source.Elem(), destination.Elem()) { if tryAssign(source.Elem(), destination.Elem()) {
return nil return
} }
} }
} else { } else {
if source.Kind() == reflect.Ptr { if source.Kind() == reflect.Ptr {
if source.IsNil() {
return
}
source = source.Elem() source = source.Elem()
} }
if tryAssign(source, destination) { if tryAssign(source, destination) {
return nil return
} }
} }
@ -804,7 +809,7 @@ func (s *scanContext) rowElem(index int) interface{} {
valuer, ok := s.row[index].(driver.Valuer) valuer, ok := s.row[index].(driver.Valuer)
if !ok { if !ok {
panic("Scan value doesn't implement driver.Valuer") panic("jet: internal error, scan value doesn't implement driver.Valuer")
} }
value, err := valuer.Value() value, err := valuer.Value()
@ -852,5 +857,5 @@ func fieldToString(field *reflect.StructField) string {
return "" return ""
} }
return field.Name + " " + field.Type.String() return " at '" + field.Name + " " + field.Type.String() + "'"
} }

View file

@ -49,8 +49,10 @@ func Generate(destDir string, dbConn DBConnection) error {
} }
func openConnection(dbConn DBConnection) (*sql.DB, error) { func openConnection(dbConn DBConnection) (*sql.DB, error) {
var connString = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", dbConn.User, dbConn.Password, dbConn.Host, dbConn.Port, dbConn.DBName) var connectionString = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", dbConn.User, dbConn.Password, dbConn.Host, dbConn.Port, dbConn.DBName)
db, err := sql.Open("mysql", connString) db, err := sql.Open("mysql", connectionString)
fmt.Println("Connecting to MySQL database: " + connectionString)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -1,6 +1,8 @@
package postgres package postgres
import ( import (
"fmt"
"github.com/go-jet/jet/execution"
"github.com/go-jet/jet/internal/testutils" "github.com/go-jet/jet/internal/testutils"
. "github.com/go-jet/jet/postgres" . "github.com/go-jet/jet/postgres"
"github.com/go-jet/jet/tests/.gentestdata/jetdb/dvds/model" "github.com/go-jet/jet/tests/.gentestdata/jetdb/dvds/model"
@ -33,9 +35,17 @@ func TestScanToInvalidDestination(t *testing.T) {
testutils.AssertQueryPanicErr(t, query, db, []**struct{}{}, "jet: destination has to be a pointer to slice or pointer to struct") testutils.AssertQueryPanicErr(t, query, db, []**struct{}{}, "jet: destination has to be a pointer to slice or pointer to struct")
}) })
t.Run("map dest", func(t *testing.T) {
testutils.AssertQueryPanicErr(t, query, db, &map[string]string{}, "jet: destination has to be a pointer to slice or pointer to struct")
})
t.Run("map dest", func(t *testing.T) { t.Run("map dest", func(t *testing.T) {
testutils.AssertQueryPanicErr(t, query, db, []map[string]string{}, "jet: destination has to be a pointer to slice or pointer to struct") testutils.AssertQueryPanicErr(t, query, db, []map[string]string{}, "jet: destination has to be a pointer to slice or pointer to struct")
}) })
t.Run("map dest", func(t *testing.T) {
testutils.AssertQueryPanicErr(t, query, db, &[]map[string]string{}, "jet: unsupported slice element type")
})
} }
func TestScanToValidDestination(t *testing.T) { func TestScanToValidDestination(t *testing.T) {
@ -45,6 +55,12 @@ func TestScanToValidDestination(t *testing.T) {
assert.NilError(t, err) assert.NilError(t, err)
}) })
t.Run("global query function scan", func(t *testing.T) {
queryStr, args := query.Sql()
err := execution.Query(nil, db, queryStr, args, &struct{}{})
assert.NilError(t, err)
})
t.Run("pointer to slice", func(t *testing.T) { t.Run("pointer to slice", func(t *testing.T) {
err := query.Query(db, &[]struct{}{}) err := query.Query(db, &[]struct{}{})
@ -75,6 +91,8 @@ func TestScanToStruct(t *testing.T) {
SELECT(Inventory.AllColumns). SELECT(Inventory.AllColumns).
ORDER_BY(Inventory.InventoryID) ORDER_BY(Inventory.InventoryID)
fmt.Println(query.DebugSql())
t.Run("one struct", func(t *testing.T) { t.Run("one struct", func(t *testing.T) {
dest := model.Inventory{} dest := model.Inventory{}
err := query.LIMIT(1).Query(db, &dest) err := query.LIMIT(1).Query(db, &dest)
@ -166,11 +184,19 @@ func TestScanToStruct(t *testing.T) {
dest := Inventory{} dest := Inventory{}
err := query.Query(db, &dest) testutils.AssertQueryPanicErr(t, query, db, &dest, `jet: Scan: unable to scan type int32 into UUID, at 'InventoryID uuid.UUID' of type postgres.Inventory`)
assert.Error(t, err, `Scan: unable to scan type int32 into UUID, at struct field: InventoryID uuid.UUID of type postgres.Inventory. `)
}) })
t.Run("type mismatch base type", func(t *testing.T) {
type Inventory struct {
InventoryID int32
FilmID bool
}
dest := []Inventory{}
testutils.AssertQueryPanicErr(t, query.OFFSET(10), db, &dest, `jet: can't set int16 to bool`)
})
} }
func TestScanToNestedStruct(t *testing.T) { func TestScanToNestedStruct(t *testing.T) {
@ -410,11 +436,18 @@ func TestScanToSlice(t *testing.T) {
}) })
t.Run("slice type mismatch ", func(t *testing.T) { t.Run("slice type convertible", func(t *testing.T) {
var dest []int var dest []int
err := query.Query(db, &dest) err := query.Query(db, &dest)
assert.Error(t, err, `jet: can't append int32 to []int slice `) assert.NilError(t, err)
})
t.Run("slice type mismatch", func(t *testing.T) {
var dest []bool
testutils.AssertQueryPanicErr(t, query, db, &dest, `jet: can't append int32 to []bool slice`)
//assert.Error(t, err, `jet: can't append int32 to []bool slice `)
}) })
}) })
@ -655,7 +688,7 @@ func TestScanToSlice(t *testing.T) {
} }
} }
testutils.AssertQueryPanicErr(t, query, db, &dest, "jet: unsupported slice element type at 'Cities []**struct { *model.City }'.") testutils.AssertQueryPanicErr(t, query, db, &dest, "jet: unsupported slice element type at 'Cities []**struct { *model.City }'")
}) })
} }