Execution additional tests.
This commit is contained in:
parent
486e45db5c
commit
13c671fa3f
3 changed files with 68 additions and 28 deletions
|
|
@ -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() + "'"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 }'")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue