add UnmarshalJSON for gtime; add ineterface MapStrAny support for gjson.New

This commit is contained in:
John
2019-09-30 17:23:23 +08:00
parent 35ad4d869f
commit 987ce709e5
13 changed files with 103 additions and 22 deletions

View File

@ -2,26 +2,23 @@ package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/gtime"
)
func main() {
db := g.DB()
db.SetDebug(true)
//type User struct {
// Uid int
// Name *gvar.Var
//}
type User struct {
Id int
Name *gtime.Time
}
//user := new(User)
////user.Name = g.NewVar("john")
//g.Dump(gconv.Map(user))
_, e := db.Table("test").Data(g.Map{
"name": nil,
}).Update()
user := new(User)
e := db.Table("test").Where("id", 10000).Struct(user)
if e != nil {
panic(e)
}
g.Dump(user)
}

View File

@ -567,6 +567,10 @@ func TestSortedArray_Json(t *testing.T) {
err = json.Unmarshal(b, user)
gtest.Assert(err, nil)
gtest.Assert(user.Name, data["Name"])
gtest.Assert(user.Scores, data["Scores"])
gtest.AssertNE(user.Scores, nil)
gtest.Assert(user.Scores.Len(), 3)
gtest.AssertIN(user.Scores.PopLeft(), data["Scores"])
gtest.AssertIN(user.Scores.PopLeft(), data["Scores"])
gtest.AssertIN(user.Scores.PopLeft(), data["Scores"])
})
}

View File

@ -75,6 +75,17 @@ func (m *IntAnyMap) Map() map[int]interface{} {
return data
}
// MapStrAny returns a copy of the data of the map as map[string]interface{}.
func (m *IntAnyMap) MapStrAny() map[string]interface{} {
m.mu.RLock()
data := make(map[string]interface{}, len(m.data))
for k, v := range m.data {
data[gconv.String(k)] = v
}
m.mu.RUnlock()
return data
}
// MapCopy returns a copy of the data of the hash map.
func (m *IntAnyMap) MapCopy() map[int]interface{} {
m.mu.RLock()

View File

@ -8,6 +8,7 @@ package gmap
import (
"encoding/json"
"github.com/gogf/gf/util/gconv"
"github.com/gogf/gf/internal/empty"
@ -72,6 +73,17 @@ func (m *IntIntMap) Map() map[int]int {
return data
}
// MapStrAny returns a copy of the data of the map as map[string]interface{}.
func (m *IntIntMap) MapStrAny() map[string]interface{} {
m.mu.RLock()
data := make(map[string]interface{}, len(m.data))
for k, v := range m.data {
data[gconv.String(k)] = v
}
m.mu.RUnlock()
return data
}
// MapCopy returns a copy of the data of the hash map.
func (m *IntIntMap) MapCopy() map[int]int {
m.mu.RLock()

View File

@ -73,6 +73,17 @@ func (m *IntStrMap) Map() map[int]string {
return data
}
// MapStrAny returns a copy of the data of the map as map[string]interface{}.
func (m *IntStrMap) MapStrAny() map[string]interface{} {
m.mu.RLock()
data := make(map[string]interface{}, len(m.data))
for k, v := range m.data {
data[gconv.String(k)] = v
}
m.mu.RUnlock()
return data
}
// MapCopy returns a copy of the data of the hash map.
func (m *IntStrMap) MapCopy() map[int]string {
m.mu.RLock()

View File

@ -75,6 +75,11 @@ func (m *StrAnyMap) Map() map[string]interface{} {
return data
}
// MapStrAny returns a copy of the data of the map as map[string]interface{}.
func (m *StrAnyMap) MapStrAny() map[string]interface{} {
return m.Map()
}
// MapCopy returns a copy of the data of the hash map.
func (m *StrAnyMap) MapCopy() map[string]interface{} {
m.mu.RLock()

View File

@ -73,6 +73,17 @@ func (m *StrIntMap) Map() map[string]int {
return data
}
// MapStrAny returns a copy of the data of the map as map[string]interface{}.
func (m *StrIntMap) MapStrAny() map[string]interface{} {
m.mu.RLock()
data := make(map[string]interface{}, len(m.data))
for k, v := range m.data {
data[k] = v
}
m.mu.RUnlock()
return data
}
// MapCopy returns a copy of the data of the hash map.
func (m *StrIntMap) MapCopy() map[string]int {
m.mu.RLock()

View File

@ -73,6 +73,17 @@ func (m *StrStrMap) Map() map[string]string {
return data
}
// MapStrAny returns a copy of the data of the map as map[string]interface{}.
func (m *StrStrMap) MapStrAny() map[string]interface{} {
m.mu.RLock()
data := make(map[string]interface{}, len(m.data))
for k, v := range m.data {
data[k] = v
}
m.mu.RUnlock()
return data
}
// MapCopy returns a copy of the data of the hash map.
func (m *StrStrMap) MapCopy() map[string]string {
m.mu.RLock()

View File

@ -51,9 +51,7 @@ func New(data interface{}, safe ...bool) *Json {
kind = rv.Kind()
}
switch kind {
case reflect.Slice:
fallthrough
case reflect.Array:
case reflect.Slice, reflect.Array:
i := interface{}(nil)
i = gconv.Interfaces(data)
j = &Json{
@ -61,9 +59,7 @@ func New(data interface{}, safe ...bool) *Json {
c: byte(gDEFAULT_SPLIT_CHAR),
vc: false,
}
case reflect.Map:
fallthrough
case reflect.Struct:
case reflect.Map, reflect.Struct:
i := interface{}(nil)
i = gconv.Map(data, "json")
j = &Json{

View File

@ -7,6 +7,7 @@
package gjson_test
import (
"github.com/gogf/gf/container/gmap"
"testing"
"github.com/gogf/gf/encoding/gjson"
@ -22,6 +23,17 @@ func Test_New(t *testing.T) {
gtest.Assert(j.Get("m"), g.Map{"k": "v"})
gtest.Assert(j.Get("a"), g.Slice{1, 2, 3})
})
gtest.Case(t, func() {
m := gmap.NewAnyAnyMapFrom(g.MapAnyAny{
"k1": "v1",
"k2": "v2",
})
j := gjson.New(m)
gtest.Assert(j.Get("k1"), "v1")
gtest.Assert(j.Get("k2"), "v2")
gtest.Assert(j.Get("k3"), nil)
})
}
func Test_Valid(t *testing.T) {

View File

@ -200,8 +200,8 @@ func AssertIN(value, expect interface{}) {
expectKind := reflect.ValueOf(expect).Kind()
switch expectKind {
case reflect.Slice, reflect.Array:
expectSlice := gconv.Interfaces(expect)
for _, v1 := range gconv.Interfaces(value) {
expectSlice := gconv.Strings(expect)
for _, v1 := range gconv.Strings(value) {
result := false
for _, v2 := range expectSlice {
if v1 == v2 {
@ -231,9 +231,9 @@ func AssertNI(value, expect interface{}) {
expectKind := reflect.ValueOf(expect).Kind()
switch expectKind {
case reflect.Slice, reflect.Array:
for _, v1 := range gconv.Interfaces(value) {
for _, v1 := range gconv.Strings(value) {
result := true
for _, v2 := range gconv.Interfaces(expect) {
for _, v2 := range gconv.Strings(expect) {
if v1 == v2 {
result = false
break

View File

@ -15,6 +15,11 @@ import (
"github.com/gogf/gf/internal/utilstr"
)
// Interface support for package gmap.
type apiMapStrAny interface {
MapStrAny() map[string]interface{}
}
// Map converts any variable <value> to map[string]interface{}.
//
// If the parameter <value> is not a map/struct/*struct type, then the conversion will fail and returns nil.
@ -103,6 +108,9 @@ func Map(value interface{}, tags ...string) map[string]interface{} {
m[String(k.Interface())] = rv.MapIndex(k).Interface()
}
case reflect.Struct:
if v, ok := value.(apiMapStrAny); ok {
return v.MapStrAny()
}
rt := rv.Type()
name := ""
tagArray := structTagPriority

View File

@ -38,6 +38,9 @@ func Duration(i interface{}) time.Duration {
// If no <format> given, it converts <i> using gtime.NewFromTimeStamp if <i> is numeric,
// or using gtime.StrToTime if <i> is string.
func GTime(i interface{}, format ...string) *gtime.Time {
if i == nil {
return nil
}
s := String(i)
if len(s) == 0 {
return gtime.New()