improve gdb.Model.Struct/Structs/Scan in error handling, it returns sql.ErrorNoRows if no records received after querying

This commit is contained in:
John
2019-07-03 19:38:52 +08:00
parent c90ed0d424
commit 23d346b291
6 changed files with 74 additions and 19 deletions

View File

@ -206,15 +206,12 @@ func (bs *dbBase) GetScan(objPointer interface{}, query string, args ...interfac
}
k = t.Elem().Kind()
switch k {
case reflect.Array:
case reflect.Slice:
case reflect.Array, reflect.Slice:
return bs.db.GetStructs(objPointer, query, args...)
case reflect.Struct:
return bs.db.GetStruct(objPointer, query, args...)
default:
return fmt.Errorf("element type should be type of struct/slice, unsupported: %v", k)
}
return nil
return fmt.Errorf("element type should be type of struct/slice, unsupported: %v", k)
}
// 数据库查询,获取查询字段值

View File

@ -8,6 +8,7 @@ package gdb
import (
"bytes"
"database/sql"
"errors"
"fmt"
"reflect"
@ -182,7 +183,7 @@ func printSql(v *Sql) {
// 格式化错误信息
func formatError(err error, query string, args ...interface{}) error {
if err != nil {
if err != nil && err != sql.ErrNoRows {
errStr := fmt.Sprintf("DB ERROR: %s\n", err.Error())
errStr += fmt.Sprintf("DB QUERY: %s\n", query)
if len(args) > 0 {

View File

@ -7,6 +7,8 @@
package gdb
import (
"database/sql"
"github.com/gogf/gf/g/encoding/gparser"
)
@ -33,5 +35,8 @@ func (r Record) ToMap() Map {
// 将Map变量映射到指定的struct对象中注意参数应当是一个对象的指针
func (r Record) ToStruct(pointer interface{}) error {
if r == nil {
return sql.ErrNoRows
}
return mapToStruct(r.ToMap(), pointer)
}

View File

@ -7,9 +7,11 @@
package gdb
import (
"database/sql"
"fmt"
"github.com/gogf/gf/g/encoding/gparser"
"reflect"
"github.com/gogf/gf/g/encoding/gparser"
)
// 将结果集转换为JSON字符串
@ -100,28 +102,32 @@ func (r Result) ToUintRecord(key string) map[uint]Record {
}
// 将结果列表转换为指定对象的slice。
func (r Result) ToStructs(objPointerSlice interface{}) error {
func (r Result) ToStructs(objPointerSlice interface{}) (err error) {
l := len(r)
if l == 0 {
return nil
return sql.ErrNoRows
}
t := reflect.TypeOf(objPointerSlice)
if t.Kind() != reflect.Ptr {
return fmt.Errorf("params should be type of pointer, but got: %v", t.Kind())
}
a := reflect.MakeSlice(t.Elem(), l, l)
itemType := a.Index(0).Type()
array := reflect.MakeSlice(t.Elem(), l, l)
itemType := array.Index(0).Type()
for i := 0; i < l; i++ {
if itemType.Kind() == reflect.Ptr {
e := reflect.New(itemType.Elem()).Elem()
r[i].ToStruct(e)
a.Index(i).Set(e.Addr())
if err = r[i].ToStruct(e); err != nil {
return err
}
array.Index(i).Set(e.Addr())
} else {
e := reflect.New(itemType).Elem()
r[i].ToStruct(e)
a.Index(i).Set(e)
if err = r[i].ToStruct(e); err != nil {
return err
}
array.Index(i).Set(e)
}
}
reflect.ValueOf(objPointerSlice).Elem().Set(a)
reflect.ValueOf(objPointerSlice).Elem().Set(array)
return nil
}

View File

@ -7,6 +7,7 @@
package gdb_test
import (
"database/sql"
"testing"
"github.com/gogf/gf/g"
@ -357,6 +358,19 @@ func TestModel_Struct(t *testing.T) {
gtest.Assert(user.NickName, "T111")
gtest.Assert(user.CreateTime.String(), "2018-10-10 00:01:10")
})
gtest.Case(t, func() {
type User struct {
Id int
Passport string
Password string
NickName string
CreateTime *gtime.Time
}
user := new(User)
err := db.Table("user").Where("id=-1").Struct(user)
gtest.Assert(err, sql.ErrNoRows)
})
}
func TestModel_Structs(t *testing.T) {
@ -404,6 +418,19 @@ func TestModel_Structs(t *testing.T) {
gtest.Assert(users[2].NickName, "T3")
gtest.Assert(users[0].CreateTime.String(), "2018-10-10 00:01:10")
})
gtest.Case(t, func() {
type User struct {
Id int
Passport string
Password string
NickName string
CreateTime *gtime.Time
}
var users []*User
err := db.Table("user").Where("id<0").Structs(&users)
gtest.Assert(err, sql.ErrNoRows)
})
}
func TestModel_Scan(t *testing.T) {
@ -483,6 +510,22 @@ func TestModel_Scan(t *testing.T) {
gtest.Assert(users[2].NickName, "T3")
gtest.Assert(users[0].CreateTime.String(), "2018-10-10 00:01:10")
})
gtest.Case(t, func() {
type User struct {
Id int
Passport string
Password string
NickName string
CreateTime *gtime.Time
}
user := new(User)
users := new([]*User)
err1 := db.Table("user").Where("id < 0").Scan(user)
err2 := db.Table("user").Where("id < 0").Scan(users)
gtest.Assert(err1, sql.ErrNoRows)
gtest.Assert(err2, sql.ErrNoRows)
})
}
func TestModel_OrderBy(t *testing.T) {

View File

@ -27,9 +27,12 @@ func main() {
// 7 反白显示
// 8 不可见
for b := 40; b <= 47; b++ { // 背景色彩 = 40-47
for f := 30; f <= 37; f++ { // 前景色彩 = 30-37
for d := range []int{0, 1, 4, 5, 7, 8} { // 显示方式 = 0,1,4,5,7,8
// 背景色彩 = 40-47
for b := 40; b <= 47; b++ {
// 前景色彩 = 30-37
for f := 30; f <= 37; f++ {
// 显示方式 = 0,1,4,5,7,8
for _, d := range []int{0, 1, 4, 5, 7, 8} {
fmt.Printf(" %c[%d;%d;%dm%s(f=%d,b=%d,d=%d)%c[0m ", 0x1B, d, b, f, "", f, b, d, 0x1B)
}
fmt.Println("")