mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
improve gdb.Model.Struct/Structs/Scan in error handling, it returns sql.ErrorNoRows if no records received after querying
This commit is contained in:
@ -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)
|
||||
}
|
||||
|
||||
// 数据库查询,获取查询字段值
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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("")
|
||||
|
||||
Reference in New Issue
Block a user