Skip to content

Commit

Permalink
fix issue gogf#1291
Browse files Browse the repository at this point in the history
  • Loading branch information
gqcn committed Jul 8, 2021
1 parent 82ad7e2 commit 5e92747
Show file tree
Hide file tree
Showing 9 changed files with 339 additions and 66 deletions.
81 changes: 17 additions & 64 deletions container/gvar/gvar_is.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,92 +7,45 @@
package gvar

import (
"github.com/gogf/gf/internal/empty"
"reflect"
"github.com/gogf/gf/internal/utils"
)

// IsNil checks whether <v> is nil.
// IsNil checks whether `v` is nil.
func (v *Var) IsNil() bool {
return v.Val() == nil
return utils.IsNil(v.Val())
}

// IsEmpty checks whether <v> is empty.
// IsEmpty checks whether `v` is empty.
func (v *Var) IsEmpty() bool {
return empty.IsEmpty(v.Val())
return utils.IsEmpty(v.Val())
}

// IsInt checks whether <v> is type of int.
// IsInt checks whether `v` is type of int.
func (v *Var) IsInt() bool {
switch v.Val().(type) {
case int, *int, int8, *int8, int16, *int16, int32, *int32, int64, *int64:
return true
}
return false
return utils.IsInt(v.Val())
}

// IsUint checks whether <v> is type of uint.
// IsUint checks whether `v` is type of uint.
func (v *Var) IsUint() bool {
switch v.Val().(type) {
case uint, *uint, uint8, *uint8, uint16, *uint16, uint32, *uint32, uint64, *uint64:
return true
}
return false
return utils.IsUint(v.Val())
}

// IsFloat checks whether <v> is type of float.
// IsFloat checks whether `v` is type of float.
func (v *Var) IsFloat() bool {
switch v.Val().(type) {
case float32, *float32, float64, *float64:
return true
}
return false
return utils.IsFloat(v.Val())
}

// IsSlice checks whether <v> is type of slice.
// IsSlice checks whether `v` is type of slice.
func (v *Var) IsSlice() bool {
var (
reflectValue = reflect.ValueOf(v.Val())
reflectKind = reflectValue.Kind()
)
for reflectKind == reflect.Ptr {
reflectValue = reflectValue.Elem()
}
switch reflectKind {
case reflect.Slice, reflect.Array:
return true
}
return false
return utils.IsSlice(v.Val())
}

// IsMap checks whether <v> is type of map.
// IsMap checks whether `v` is type of map.
func (v *Var) IsMap() bool {
var (
reflectValue = reflect.ValueOf(v.Val())
reflectKind = reflectValue.Kind()
)
for reflectKind == reflect.Ptr {
reflectValue = reflectValue.Elem()
}
switch reflectKind {
case reflect.Map:
return true
}
return false
return utils.IsMap(v.Val())
}

// IsStruct checks whether <v> is type of struct.
// IsStruct checks whether `v` is type of struct.
func (v *Var) IsStruct() bool {
var (
reflectValue = reflect.ValueOf(v.Val())
reflectKind = reflectValue.Kind()
)
for reflectKind == reflect.Ptr {
reflectValue = reflectValue.Elem()
reflectKind = reflectValue.Kind()
}
switch reflectKind {
case reflect.Struct:
return true
}
return false
return utils.IsStruct(v.Val())
}
12 changes: 10 additions & 2 deletions database/gdb/gdb_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ func (r *SqlResult) MustGetInsertId() int64 {
return id
}

// see sql.Result.RowsAffected
// RowsAffected returns the number of rows affected by an
// update, insert, or delete. Not every database or database
// driver may support this.
// Also See sql.Result.
func (r *SqlResult) RowsAffected() (int64, error) {
if r.affected > 0 {
return r.affected, nil
Expand All @@ -44,7 +47,12 @@ func (r *SqlResult) RowsAffected() (int64, error) {
return r.result.RowsAffected()
}

// see sql.Result.LastInsertId
// LastInsertId returns the integer generated by the database
// in response to a command. Typically this will be from an
// "auto increment" column when inserting a new row. Not all
// databases support this feature, and the syntax of such
// statements varies.
// Also See sql.Result.
func (r *SqlResult) LastInsertId() (int64, error) {
if r.result == nil {
return 0, nil
Expand Down
5 changes: 5 additions & 0 deletions database/gdb/gdb_type_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ import (
"github.com/gogf/gf/util/gconv"
)

// Interface converts and returns `r` as type of interface{}.
func (r Record) Interface() interface{} {
return r
}

// Json converts `r` to JSON format content.
func (r Record) Json() string {
content, _ := gparser.VarToJson(r.Map())
Expand Down
5 changes: 5 additions & 0 deletions database/gdb/gdb_type_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import (
"math"
)

// Interface converts and returns `r` as type of interface{}.
func (r Result) Interface() interface{} {
return r
}

// IsEmpty checks and returns whether `r` is empty.
func (r Result) IsEmpty() bool {
return r.Len() == 0
Expand Down
13 changes: 13 additions & 0 deletions encoding/gjson/gjson.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package gjson

import (
"github.com/gogf/gf/internal/utils"
"reflect"
"strconv"
"strings"
Expand Down Expand Up @@ -37,11 +38,23 @@ type Options struct {
StrNumber bool // StrNumber causes the Decoder to unmarshal a number into an interface{} as a string instead of as a float64.
}

// apiInterface is used for type assert api for Interface().
type apiInterface interface {
Interface() interface{}
}

// setValue sets <value> to <j> by <pattern>.
// Note:
// 1. If value is nil and removed is true, means deleting this value;
// 2. It's quite complicated in hierarchical data search, node creating and data assignment;
func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
if value != nil {
if utils.IsStruct(value) {
if v, ok := value.(apiInterface); ok {
value = v.Interface()
}
}
}
array := strings.Split(pattern, string(j.c))
length := len(array)
value = j.convertValue(value)
Expand Down
6 changes: 6 additions & 0 deletions encoding/gjson/gjson_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ import (
)

// Value returns the json value.
// Deprecated, use Interface instead.
func (j *Json) Value() interface{} {
return j.Interface()
}

// Interface returns the json value.
func (j *Json) Interface() interface{} {
j.mu.RLock()
defer j.mu.RUnlock()
return *(j.p)
Expand Down
14 changes: 14 additions & 0 deletions encoding/gjson/gjson_z_unit_basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,3 +485,17 @@ func TestJson_IsNil(t *testing.T) {
t.Assert(j.IsNil(), true)
})
}

func TestJson_Set_With_Struct(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
v := gjson.New(g.Map{
"user1": g.Map{"name": "user1"},
"user2": g.Map{"name": "user2"},
"user3": g.Map{"name": "user3"},
})
user1 := v.GetJson("user1")
user1.Set("id", 111)
v.Set("user1", user1)
t.Assert(v.Get("user1.id"), 111)
})
}
98 changes: 98 additions & 0 deletions internal/utils/utils_is.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// 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 utils

import (
"github.com/gogf/gf/internal/empty"
"reflect"
)

// IsNil checks whether `value` is nil.
func IsNil(value interface{}) bool {
return value == nil
}

// IsEmpty checks whether `value` is empty.
func IsEmpty(value interface{}) bool {
return empty.IsEmpty(value)
}

// IsInt checks whether `value` is type of int.
func IsInt(value interface{}) bool {
switch value.(type) {
case int, *int, int8, *int8, int16, *int16, int32, *int32, int64, *int64:
return true
}
return false
}

// IsUint checks whether `value` is type of uint.
func IsUint(value interface{}) bool {
switch value.(type) {
case uint, *uint, uint8, *uint8, uint16, *uint16, uint32, *uint32, uint64, *uint64:
return true
}
return false
}

// IsFloat checks whether `value` is type of float.
func IsFloat(value interface{}) bool {
switch value.(type) {
case float32, *float32, float64, *float64:
return true
}
return false
}

// IsSlice checks whether `value` is type of slice.
func IsSlice(value interface{}) bool {
var (
reflectValue = reflect.ValueOf(value)
reflectKind = reflectValue.Kind()
)
for reflectKind == reflect.Ptr {
reflectValue = reflectValue.Elem()
}
switch reflectKind {
case reflect.Slice, reflect.Array:
return true
}
return false
}

// IsMap checks whether `value` is type of map.
func IsMap(value interface{}) bool {
var (
reflectValue = reflect.ValueOf(value)
reflectKind = reflectValue.Kind()
)
for reflectKind == reflect.Ptr {
reflectValue = reflectValue.Elem()
}
switch reflectKind {
case reflect.Map:
return true
}
return false
}

// IsStruct checks whether `value` is type of struct.
func IsStruct(value interface{}) bool {
var (
reflectValue = reflect.ValueOf(value)
reflectKind = reflectValue.Kind()
)
for reflectKind == reflect.Ptr {
reflectValue = reflectValue.Elem()
reflectKind = reflectValue.Kind()
}
switch reflectKind {
case reflect.Struct:
return true
}
return false
}
Loading

0 comments on commit 5e92747

Please sign in to comment.