Skip to content

Commit

Permalink
DbClientEx.ListType 支持 []time.Time 的元素赋值。 Resolve #16
Browse files Browse the repository at this point in the history
  • Loading branch information
cmstar committed Jan 3, 2024
1 parent 1b3002c commit 048367c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 27 deletions.
55 changes: 28 additions & 27 deletions db_client_ex.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,19 +347,20 @@ func (c *DbClientEx) MustScalarFloat64(query string, args ...any) (value *float6
// 若值不是目标类型,则尝试转换类型。
//
// 例1,获取可空字段:
// var s *string
// v, ok, err := client.ScalarType(reflect.TypeOf(s), querySomeNullable)
// if err != nil && ok {
// s = v.(*string)
// }
//
// var s *string
// v, ok, err := client.ScalarType(reflect.TypeOf(s), querySomeNullable)
// if err != nil && ok {
// s = v.(*string)
// }
//
// 例2,获取非空字段:
// var s string
// v, ok, err := client.ScalarType(reflect.TypeOf(s), querySomeNonNullable)
// if err != nil && ok {
// s = v.(string)
// }
//
// var s string
// v, ok, err := client.ScalarType(reflect.TypeOf(s), querySomeNonNullable)
// if err != nil && ok {
// s = v.(string)
// }
func (c *DbClientEx) ScalarType(typ reflect.Type, query string, args ...any) (value any, ok bool, err error) {
v, ok, err := c.Scalar(query, args...)
if !ok || err != nil {
Expand All @@ -384,9 +385,9 @@ func (c *DbClientEx) MustScalarType(typ reflect.Type, query string, args ...any)
// 若值不是目标类型,则尝试转换类型。
//
// 下面两行代码等价:
// client.ScalarOf("", query)
// client.ScalarType(reflect.TypeOf(""), query)
//
// client.ScalarOf("", query)
// client.ScalarType(reflect.TypeOf(""), query)
func (c *DbClientEx) ScalarOf(example any, query string, args ...any) (value any, ok bool, err error) {
exampleTyp := reflect.TypeOf(example)
return c.ScalarType(exampleTyp, query, args...)
Expand All @@ -405,12 +406,12 @@ func (c *DbClientEx) MustScalarOf(example any, query string, args ...any) (value
// ListOf 将查询结果的每一行转换到指定类型。返回转换后的元素的列表,需给定列表中的元素的类型。若查询没有命中行,返回空集。
//
// 注意,给定的 elemTyp 是元素的类型,返回的则是该元素的 slice :
// list, err := ListType(reflect.TypeOf(0), query)
// if err != nil {
// return err
// }
// infos := list.([]int)
//
// list, err := ListType(reflect.TypeOf(0), query)
// if err != nil {
// return err
// }
// infos := list.([]int)
func (c *DbClientEx) ListType(elemTyp reflect.Type, query string, args ...any) (any, error) {
rows, err := c.Rows(query, args...)
if err != nil {
Expand All @@ -422,7 +423,7 @@ func (c *DbClientEx) ListType(elemTyp reflect.Type, query string, args ...any) (
for underTyp.Kind() == reflect.Ptr {
underTyp = underTyp.Elem()
}
complex := underTyp.Kind() == reflect.Struct || underTyp.Kind() == reflect.Map
complex := !conv.IsSimpleType(underTyp)
vList := reflect.MakeSlice(reflect.SliceOf(elemTyp), 0, 0)

for rows.Next() {
Expand Down Expand Up @@ -463,8 +464,8 @@ func (c *DbClientEx) ListType(elemTyp reflect.Type, query string, args ...any) (
// MustListType 类似 ListType ,但出现错误时不返回 error ,而是 panic 。
//
// 注意,给定的 elemTyp 是元素的类型,返回的则是该元素的 slice :
// list := MustListType(reflect.TypeOf(0), query).([]int)
//
// list := MustListType(reflect.TypeOf(0), query).([]int)
func (c *DbClientEx) MustListType(elemTyp reflect.Type, query string, args ...any) any {
v, err := c.ListType(elemTyp, query, args...)
if err != nil {
Expand All @@ -476,22 +477,22 @@ func (c *DbClientEx) MustListType(elemTyp reflect.Type, query string, args ...an
// ListOf 将查询结果的每一行转换到指定类型。返回转换后的元素的列表,需给定列表中的元素的类型。若查询没有命中行,返回空集。
//
// 注意,给定的 elemTyp 是元素的类型,返回的则是该元素的 slice :
// type Info struct { /* fields */ }
// list, err := ListOf(new(Info), query)
// if err != nil {
// return err
// }
// infos := list.([]*Info)
//
// type Info struct { /* fields */ }
// list, err := ListOf(new(Info), query)
// if err != nil {
// return err
// }
// infos := list.([]*Info)
func (c *DbClientEx) ListOf(elemExample any, query string, args ...any) (any, error) {
elemTyp := reflect.TypeOf(elemExample)
return c.ListType(elemTyp, query, args...)
}

// MustListOf 类似 ListOf ,但出现错误时不返回 error ,而是 panic 。
// type Info struct { /* fields */ }
// list := MustListOf(new(Info), query).([]*Info)
//
// type Info struct { /* fields */ }
// list := MustListOf(new(Info), query).([]*Info)
func (c *DbClientEx) MustListOf(elemExample any, query string, args ...any) any {
elemTyp := reflect.TypeOf(elemExample)
v, err := c.ListType(elemTyp, query, args...)
Expand Down
21 changes: 21 additions & 0 deletions mysql/mysql_db_client_ex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,27 @@ func TestDbClientEx_ListType(t *testing.T) {
t.Fatalf("expect length=0, got %v", len(list))
}
})

t.Run("time", func(t *testing.T) {
query := `SELECT dateTimeTest FROM go_TypeTest WHERE id IN (@p1)`
res, err := c.ListType(reflect.TypeOf(time.Time{}), query, 1)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

v, ok := res.([]time.Time)
if !ok {
t.Fatalf("expect []time.Time, got %T", res)
}

if len(v) != 1 {
t.Fatalf("expect length=1, got %v", len(v))
}

if v[0] != time.Date(2021, 7, 1, 15, 38, 50, 0, time.UTC) {
t.Fatalf("expect DateTimeTest=2021-07-01 15:38:50, got %v", v)
}
})
}

func TestDbClientEx_MustListType(t *testing.T) {
Expand Down

0 comments on commit 048367c

Please sign in to comment.