mirror of
https://gitee.com/johng/gf.git
synced 2024-12-01 19:57:40 +08:00
it returns error when Scan
to a none empty slice with empty Result
for package gdb
(#2858)
This commit is contained in:
parent
3df5969348
commit
ac3481ed43
@ -8,6 +8,7 @@ package mssql_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -804,8 +805,7 @@ func Test_DB_ToJson(t *testing.T) {
|
|||||||
t.Assert(users[0].CreateTime, resultJson.Get("0.CREATE_TIME").String())
|
t.Assert(users[0].CreateTime, resultJson.Get("0.CREATE_TIME").String())
|
||||||
|
|
||||||
result = nil
|
result = nil
|
||||||
err = result.Structs(&users)
|
t.Assert(result.Structs(&users), sql.ErrNoRows)
|
||||||
t.AssertNil(err)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
gtest.C(t, func(t *gtest.T) {
|
gtest.C(t, func(t *gtest.T) {
|
||||||
|
@ -8,6 +8,7 @@ package mysql_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -892,8 +893,7 @@ func Test_DB_ToJson(t *testing.T) {
|
|||||||
t.Assert(users[0].CreateTime, resultJson.Get("0.create_time").String())
|
t.Assert(users[0].CreateTime, resultJson.Get("0.create_time").String())
|
||||||
|
|
||||||
result = nil
|
result = nil
|
||||||
err = result.Structs(&users)
|
t.Assert(result.Structs(&users), sql.ErrNoRows)
|
||||||
t.AssertNil(err)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
gtest.C(t, func(t *gtest.T) {
|
gtest.C(t, func(t *gtest.T) {
|
||||||
|
@ -301,7 +301,7 @@ func Test_Structs_Empty(t *testing.T) {
|
|||||||
all, err := db.Model(table).Where("id>100").All()
|
all, err := db.Model(table).Where("id>100").All()
|
||||||
t.AssertNil(err)
|
t.AssertNil(err)
|
||||||
users := make([]User, 10)
|
users := make([]User, 10)
|
||||||
t.Assert(all.Structs(&users), nil)
|
t.Assert(all.Structs(&users), sql.ErrNoRows)
|
||||||
})
|
})
|
||||||
gtest.C(t, func(t *gtest.T) {
|
gtest.C(t, func(t *gtest.T) {
|
||||||
all, err := db.Model(table).Where("id>100").All()
|
all, err := db.Model(table).Where("id>100").All()
|
||||||
@ -320,7 +320,7 @@ func Test_Structs_Empty(t *testing.T) {
|
|||||||
all, err := db.Model(table).Where("id>100").All()
|
all, err := db.Model(table).Where("id>100").All()
|
||||||
t.AssertNil(err)
|
t.AssertNil(err)
|
||||||
users := make([]*User, 10)
|
users := make([]*User, 10)
|
||||||
t.Assert(all.Structs(&users), nil)
|
t.Assert(all.Structs(&users), sql.ErrNoRows)
|
||||||
})
|
})
|
||||||
gtest.C(t, func(t *gtest.T) {
|
gtest.C(t, func(t *gtest.T) {
|
||||||
all, err := db.Model(table).Where("id>100").All()
|
all, err := db.Model(table).Where("id>100").All()
|
||||||
|
@ -4665,3 +4665,44 @@ func Test_Builder_OmitEmptyWhere(t *testing.T) {
|
|||||||
t.Assert(count, int64(TableSize))
|
t.Assert(count, int64(TableSize))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_Scan_Nil_Result_Error(t *testing.T) {
|
||||||
|
table := createInitTable()
|
||||||
|
defer dropTable(table)
|
||||||
|
|
||||||
|
type S struct {
|
||||||
|
Id int
|
||||||
|
Name string
|
||||||
|
Age int
|
||||||
|
Score int
|
||||||
|
}
|
||||||
|
gtest.C(t, func(t *gtest.T) {
|
||||||
|
var s *S
|
||||||
|
err := db.Model(table).Where("id", 1).Scan(&s)
|
||||||
|
t.AssertNil(err)
|
||||||
|
t.Assert(s.Id, 1)
|
||||||
|
})
|
||||||
|
gtest.C(t, func(t *gtest.T) {
|
||||||
|
var s *S
|
||||||
|
err := db.Model(table).Where("id", 100).Scan(&s)
|
||||||
|
t.AssertNil(err)
|
||||||
|
t.Assert(s, nil)
|
||||||
|
})
|
||||||
|
gtest.C(t, func(t *gtest.T) {
|
||||||
|
var s S
|
||||||
|
err := db.Model(table).Where("id", 100).Scan(&s)
|
||||||
|
t.Assert(err, sql.ErrNoRows)
|
||||||
|
})
|
||||||
|
gtest.C(t, func(t *gtest.T) {
|
||||||
|
var ss []*S
|
||||||
|
err := db.Model(table).Scan(&ss)
|
||||||
|
t.AssertNil(err)
|
||||||
|
t.Assert(len(ss), TableSize)
|
||||||
|
})
|
||||||
|
// If the result is empty, it returns error.
|
||||||
|
gtest.C(t, func(t *gtest.T) {
|
||||||
|
var ss = make([]*S, 10)
|
||||||
|
err := db.Model(table).WhereGT("id", 100).Scan(&ss)
|
||||||
|
t.Assert(err, sql.ErrNoRows)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@ package sqlite_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -839,8 +840,7 @@ func Test_DB_ToJson(t *testing.T) {
|
|||||||
t.Assert(users[0].CreateTime, resultJson.Get("0.create_time").String())
|
t.Assert(users[0].CreateTime, resultJson.Get("0.create_time").String())
|
||||||
|
|
||||||
result = nil
|
result = nil
|
||||||
err = result.Structs(&users)
|
t.Assert(result.Structs(&users), sql.ErrNoRows)
|
||||||
t.AssertNil(err)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
gtest.C(t, func(t *gtest.T) {
|
gtest.C(t, func(t *gtest.T) {
|
||||||
|
@ -8,6 +8,7 @@ package sqlitecgo_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -839,8 +840,7 @@ func Test_DB_ToJson(t *testing.T) {
|
|||||||
t.Assert(users[0].CreateTime, resultJson.Get("0.create_time").String())
|
t.Assert(users[0].CreateTime, resultJson.Get("0.create_time").String())
|
||||||
|
|
||||||
result = nil
|
result = nil
|
||||||
err = result.Structs(&users)
|
t.Assert(result.Structs(&users), sql.ErrNoRows)
|
||||||
t.AssertNil(err)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
gtest.C(t, func(t *gtest.T) {
|
gtest.C(t, func(t *gtest.T) {
|
||||||
|
@ -7,10 +7,12 @@
|
|||||||
package gdb
|
package gdb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/container/gvar"
|
"github.com/gogf/gf/v2/container/gvar"
|
||||||
"github.com/gogf/gf/v2/encoding/gjson"
|
"github.com/gogf/gf/v2/encoding/gjson"
|
||||||
|
"github.com/gogf/gf/v2/internal/empty"
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -191,5 +193,12 @@ func (r Result) RecordKeyUint(key string) map[uint]Record {
|
|||||||
// Structs converts `r` to struct slice.
|
// Structs converts `r` to struct slice.
|
||||||
// Note that the parameter `pointer` should be type of *[]struct/*[]*struct.
|
// Note that the parameter `pointer` should be type of *[]struct/*[]*struct.
|
||||||
func (r Result) Structs(pointer interface{}) (err error) {
|
func (r Result) Structs(pointer interface{}) (err error) {
|
||||||
|
// If the result is empty and the target pointer is not empty, it returns error.
|
||||||
|
if r.IsEmpty() {
|
||||||
|
if !empty.IsEmpty(pointer, true) {
|
||||||
|
return sql.ErrNoRows
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return gconv.StructsTag(r, pointer, OrmTagForStruct)
|
return gconv.StructsTag(r, pointer, OrmTagForStruct)
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ func TryCatch(ctx context.Context, try func(ctx context.Context), catch ...func(
|
|||||||
|
|
||||||
// IsNil checks whether given `value` is nil.
|
// IsNil checks whether given `value` is nil.
|
||||||
// Parameter `traceSource` is used for tracing to the source variable if given `value` is type
|
// Parameter `traceSource` is used for tracing to the source variable if given `value` is type
|
||||||
// of pinter that also points to a pointer. It returns nil if the source is nil when `traceSource`
|
// of pointer that also points to a pointer. It returns nil if the source is nil when `traceSource`
|
||||||
// is true.
|
// is true.
|
||||||
// Note that it might use reflect feature which affects performance a little.
|
// Note that it might use reflect feature which affects performance a little.
|
||||||
func IsNil(value interface{}, traceSource ...bool) bool {
|
func IsNil(value interface{}, traceSource ...bool) bool {
|
||||||
@ -90,8 +90,12 @@ func IsNil(value interface{}, traceSource ...bool) bool {
|
|||||||
// IsEmpty checks whether given `value` empty.
|
// IsEmpty checks whether given `value` empty.
|
||||||
// It returns true if `value` is in: 0, nil, false, "", len(slice/map/chan) == 0.
|
// It returns true if `value` is in: 0, nil, false, "", len(slice/map/chan) == 0.
|
||||||
// Or else it returns true.
|
// Or else it returns true.
|
||||||
func IsEmpty(value interface{}) bool {
|
//
|
||||||
return empty.IsEmpty(value)
|
// The parameter `traceSource` is used for tracing to the source variable if given `value` is type of pointer
|
||||||
|
// that also points to a pointer. It returns true if the source is empty when `traceSource` is true.
|
||||||
|
// Note that it might use reflect feature which affects performance a little.
|
||||||
|
func IsEmpty(value interface{}, traceSource ...bool) bool {
|
||||||
|
return empty.IsEmpty(value, traceSource...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestFromCtx retrieves and returns the Request object from context.
|
// RequestFromCtx retrieves and returns the Request object from context.
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the MIT License.
|
||||||
|
// If a copy of the MIT was not distributed with this file,
|
||||||
|
// You can obtain one at https://github.com/gogf/gf.
|
||||||
|
|
||||||
package g_test
|
package g_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -37,7 +37,11 @@ type iTime interface {
|
|||||||
// IsEmpty checks whether given `value` empty.
|
// IsEmpty checks whether given `value` empty.
|
||||||
// It returns true if `value` is in: 0, nil, false, "", len(slice/map/chan) == 0,
|
// It returns true if `value` is in: 0, nil, false, "", len(slice/map/chan) == 0,
|
||||||
// or else it returns false.
|
// or else it returns false.
|
||||||
func IsEmpty(value interface{}) bool {
|
//
|
||||||
|
// The parameter `traceSource` is used for tracing to the source variable if given `value` is type of pointer
|
||||||
|
// that also points to a pointer. It returns true if the source is empty when `traceSource` is true.
|
||||||
|
// Note that it might use reflect feature which affects performance a little.
|
||||||
|
func IsEmpty(value interface{}, traceSource ...bool) bool {
|
||||||
if value == nil {
|
if value == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -88,6 +92,11 @@ func IsEmpty(value interface{}) bool {
|
|||||||
return len(result) == 0
|
return len(result) == 0
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
// Finally, using reflect.
|
||||||
|
var rv reflect.Value
|
||||||
|
if v, ok := value.(reflect.Value); ok {
|
||||||
|
rv = v
|
||||||
|
} else {
|
||||||
// =========================
|
// =========================
|
||||||
// Common interfaces checks.
|
// Common interfaces checks.
|
||||||
// =========================
|
// =========================
|
||||||
@ -115,11 +124,7 @@ func IsEmpty(value interface{}) bool {
|
|||||||
}
|
}
|
||||||
return len(f.MapStrAny()) == 0
|
return len(f.MapStrAny()) == 0
|
||||||
}
|
}
|
||||||
// Finally, using reflect.
|
|
||||||
var rv reflect.Value
|
|
||||||
if v, ok := value.(reflect.Value); ok {
|
|
||||||
rv = v
|
|
||||||
} else {
|
|
||||||
rv = reflect.ValueOf(value)
|
rv = reflect.ValueOf(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,21 +174,27 @@ func IsEmpty(value interface{}) bool {
|
|||||||
reflect.Array:
|
reflect.Array:
|
||||||
return rv.Len() == 0
|
return rv.Len() == 0
|
||||||
|
|
||||||
|
case reflect.Ptr:
|
||||||
|
if len(traceSource) > 0 && traceSource[0] {
|
||||||
|
return IsEmpty(rv.Elem())
|
||||||
|
}
|
||||||
|
return rv.IsNil()
|
||||||
|
|
||||||
case
|
case
|
||||||
reflect.Func,
|
reflect.Func,
|
||||||
reflect.Ptr,
|
|
||||||
reflect.Interface,
|
reflect.Interface,
|
||||||
reflect.UnsafePointer:
|
reflect.UnsafePointer:
|
||||||
if rv.IsNil() {
|
return rv.IsNil()
|
||||||
|
|
||||||
|
case reflect.Invalid:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsNil checks whether given `value` is nil, especially for interface{} type value.
|
// IsNil checks whether given `value` is nil, especially for interface{} type value.
|
||||||
// Parameter `traceSource` is used for tracing to the source variable if given `value` is type of pinter
|
// Parameter `traceSource` is used for tracing to the source variable if given `value` is type of pointer
|
||||||
// that also points to a pointer. It returns nil if the source is nil when `traceSource` is true.
|
// that also points to a pointer. It returns nil if the source is nil when `traceSource` is true.
|
||||||
// Note that it might use reflect feature which affects performance a little.
|
// Note that it might use reflect feature which affects performance a little.
|
||||||
func IsNil(value interface{}, traceSource ...bool) bool {
|
func IsNil(value interface{}, traceSource ...bool) bool {
|
||||||
|
@ -62,7 +62,7 @@ func newFilePool(p *Pool, path string, flag int, perm os.FileMode, ttl time.Dura
|
|||||||
// File retrieves file item from the file pointer pool and returns it. It creates one if
|
// File retrieves file item from the file pointer pool and returns it. It creates one if
|
||||||
// the file pointer pool is empty.
|
// the file pointer pool is empty.
|
||||||
// Note that it should be closed when it will never be used. When it's closed, it is not
|
// Note that it should be closed when it will never be used. When it's closed, it is not
|
||||||
// really closed the underlying file pointer but put back to the file pinter pool.
|
// really closed the underlying file pointer but put back to the file pointer pool.
|
||||||
func (p *Pool) File() (*File, error) {
|
func (p *Pool) File() (*File, error) {
|
||||||
if v, err := p.pool.Get(); err != nil {
|
if v, err := p.pool.Get(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
Loading…
Reference in New Issue
Block a user