mirror of
https://gitee.com/johng/gf.git
synced 2024-12-02 04:07:47 +08:00
improve Struct convertion for package gdb; improve IsNil function for package internal/empty
This commit is contained in:
parent
8365ce9d29
commit
92b791eb08
@ -1,4 +1,4 @@
|
||||
// Copyright GoFrame Author(https://github.com/gogf/gf). All Rights Reserved.
|
||||
// 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,
|
||||
@ -48,9 +48,9 @@ type apiMapStrAny interface {
|
||||
}
|
||||
|
||||
const (
|
||||
ORM_TAG_FOR_STRUCT = "orm"
|
||||
ORM_TAG_FOR_UNIQUE = "unique"
|
||||
ORM_TAG_FOR_PRIMARY = "primary"
|
||||
OrmTagForStruct = "orm"
|
||||
OrmTagForUnique = "unique"
|
||||
OrmTagForPrimary = "primary"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -58,7 +58,7 @@ var (
|
||||
quoteWordReg = regexp.MustCompile(`^[a-zA-Z0-9\-_]+$`)
|
||||
|
||||
// Priority tags for struct converting for orm field mapping.
|
||||
structTagPriority = append([]string{ORM_TAG_FOR_STRUCT}, gconv.StructTagPriority...)
|
||||
structTagPriority = append([]string{OrmTagForStruct}, gconv.StructTagPriority...)
|
||||
)
|
||||
|
||||
// ListItemValues retrieves and returns the elements of all item struct/map with key <key>.
|
||||
@ -315,14 +315,14 @@ func doQuoteString(s, charLeft, charRight string) string {
|
||||
// GetWhereConditionOfStruct returns the where condition sql and arguments by given struct pointer.
|
||||
// This function automatically retrieves primary or unique field and its attribute value as condition.
|
||||
func GetWhereConditionOfStruct(pointer interface{}) (where string, args []interface{}, err error) {
|
||||
tagField, err := structs.TagFields(pointer, []string{ORM_TAG_FOR_STRUCT})
|
||||
tagField, err := structs.TagFields(pointer, []string{OrmTagForStruct})
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
array := ([]string)(nil)
|
||||
for _, field := range tagField {
|
||||
array = strings.Split(field.TagValue, ",")
|
||||
if len(array) > 1 && gstr.InArray([]string{ORM_TAG_FOR_UNIQUE, ORM_TAG_FOR_PRIMARY}, array[1]) {
|
||||
if len(array) > 1 && gstr.InArray([]string{OrmTagForUnique, OrmTagForPrimary}, array[1]) {
|
||||
return array[0], []interface{}{field.Value()}, nil
|
||||
}
|
||||
if len(where) > 0 {
|
||||
@ -336,14 +336,14 @@ func GetWhereConditionOfStruct(pointer interface{}) (where string, args []interf
|
||||
|
||||
// GetPrimaryKey retrieves and returns primary key field name from given struct.
|
||||
func GetPrimaryKey(pointer interface{}) (string, error) {
|
||||
tagField, err := structs.TagFields(pointer, []string{ORM_TAG_FOR_STRUCT})
|
||||
tagField, err := structs.TagFields(pointer, []string{OrmTagForStruct})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
array := ([]string)(nil)
|
||||
for _, field := range tagField {
|
||||
array = strings.Split(field.TagValue, ",")
|
||||
if len(array) > 1 && array[1] == ORM_TAG_FOR_PRIMARY {
|
||||
if len(array) > 1 && array[1] == OrmTagForPrimary {
|
||||
return array[0], nil
|
||||
}
|
||||
}
|
||||
@ -741,7 +741,7 @@ func FormatSqlWithArgs(sql string, args []interface{}) string {
|
||||
// convertMapToStruct maps the <data> to given struct.
|
||||
// Note that the given parameter <pointer> should be a pointer to s struct.
|
||||
func convertMapToStruct(data map[string]interface{}, pointer interface{}) error {
|
||||
tagNameMap, err := structs.TagMapName(pointer, []string{ORM_TAG_FOR_STRUCT})
|
||||
tagNameMap, err := structs.TagMapName(pointer, []string{OrmTagForStruct})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/gogf/gf/container/gmap"
|
||||
"github.com/gogf/gf/encoding/gparser"
|
||||
"github.com/gogf/gf/errors/gerror"
|
||||
"github.com/gogf/gf/internal/empty"
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
"reflect"
|
||||
)
|
||||
@ -47,7 +48,7 @@ func (r Record) GMap() *gmap.StrAnyMap {
|
||||
// Note that it returns sql.ErrNoRows if <r> is empty.
|
||||
func (r Record) Struct(pointer interface{}) error {
|
||||
// If the record is empty, it returns error.
|
||||
if r.IsEmpty() {
|
||||
if r.IsEmpty() && !empty.IsNil(pointer, true) {
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
// Special handling for parameter type: reflect.Value
|
||||
|
@ -981,6 +981,18 @@ func Test_Model_Struct(t *testing.T) {
|
||||
err := db.Table(table).Where("id=-1").Struct(user)
|
||||
t.Assert(err, sql.ErrNoRows)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
var user *User
|
||||
err := db.Table(table).Where("id=-1").Struct(&user)
|
||||
t.Assert(err, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Model_Struct_CustomType(t *testing.T) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright GoFrame Author(https://github.com/gogf/gf). All Rights Reserved.
|
||||
// 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,
|
||||
@ -262,7 +262,8 @@ func Test_Struct_Empty(t *testing.T) {
|
||||
one, err := db.Table(table).Where("id=100").One()
|
||||
t.Assert(err, nil)
|
||||
var user *User
|
||||
t.AssertNE(one.Struct(&user), nil)
|
||||
t.Assert(one.Struct(&user), nil)
|
||||
t.Assert(user, nil)
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
|
@ -52,9 +52,12 @@ func TryCatch(try func(), catch ...func(exception error)) {
|
||||
}
|
||||
|
||||
// IsNil checks whether given <value> is nil.
|
||||
// Parameter <traceSource> is used for tracing to the source variable if given <value> is type
|
||||
// of a pinter 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 bit.
|
||||
func IsNil(value interface{}) bool {
|
||||
return empty.IsNil(value)
|
||||
func IsNil(value interface{}, traceSource ...bool) bool {
|
||||
return empty.IsNil(value, traceSource...)
|
||||
}
|
||||
|
||||
// IsEmpty checks whether given <value> empty.
|
||||
|
@ -1,10 +1,10 @@
|
||||
// Copyright 2019 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
||||
// Copyright GoFrame gf 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 empty provides functions for checking empty variables.
|
||||
// Package empty provides functions for checking empty/nil variables.
|
||||
package empty
|
||||
|
||||
import (
|
||||
@ -152,8 +152,11 @@ func IsEmpty(value interface{}) bool {
|
||||
}
|
||||
|
||||
// IsNil checks whether given <value> is nil.
|
||||
// Parameter <traceSource> is used for tracing to the source variable if given <value> is type
|
||||
// of a pinter 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 bit.
|
||||
func IsNil(value interface{}) bool {
|
||||
func IsNil(value interface{}, traceSource ...bool) bool {
|
||||
if value == nil {
|
||||
return true
|
||||
}
|
||||
@ -168,10 +171,24 @@ func IsNil(value interface{}) bool {
|
||||
reflect.Map,
|
||||
reflect.Slice,
|
||||
reflect.Func,
|
||||
reflect.Ptr,
|
||||
reflect.Interface,
|
||||
reflect.UnsafePointer:
|
||||
return rv.IsNil()
|
||||
return !rv.IsValid() || rv.IsNil()
|
||||
|
||||
case reflect.Ptr:
|
||||
if len(traceSource) > 0 && traceSource[0] {
|
||||
for rv.Kind() == reflect.Ptr {
|
||||
rv = rv.Elem()
|
||||
}
|
||||
if !rv.IsValid() {
|
||||
return true
|
||||
}
|
||||
if rv.Kind() == reflect.Ptr {
|
||||
return rv.IsNil()
|
||||
}
|
||||
} else {
|
||||
return !rv.IsValid() || rv.IsNil()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
||||
// 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,
|
||||
@ -108,3 +108,22 @@ func TestIsEmpty(t *testing.T) {
|
||||
t.Assert(empty.IsEmpty(tmpF6), false)
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsNil(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
t.Assert(empty.IsNil(nil), true)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var i int
|
||||
t.Assert(empty.IsNil(i), false)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var i *int
|
||||
t.Assert(empty.IsNil(i), true)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var i *int
|
||||
t.Assert(empty.IsNil(&i), false)
|
||||
t.Assert(empty.IsNil(&i, true), true)
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user