mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
fix issue in gjson/gparser in loading xml content; add *time.Time support for gdb
This commit is contained in:
@ -142,10 +142,19 @@ func convertParam(value interface{}) interface{} {
|
||||
}
|
||||
switch kind {
|
||||
case reflect.Struct:
|
||||
// 底层数据库引擎支持 time.Time 类型
|
||||
if _, ok := value.(time.Time); ok {
|
||||
// 底层数据库引擎支持 time.Time/*time.Time 类型
|
||||
if v, ok := value.(time.Time); ok {
|
||||
if v.IsZero() {
|
||||
return "null"
|
||||
}
|
||||
return value
|
||||
}
|
||||
if v, ok := value.(*time.Time); ok {
|
||||
if v.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return value
|
||||
}
|
||||
return gconv.String(value)
|
||||
}
|
||||
return value
|
||||
@ -206,10 +215,13 @@ func structToMap(obj interface{}) map[string]interface{} {
|
||||
}
|
||||
switch kind {
|
||||
case reflect.Struct:
|
||||
// 底层数据库引擎支持 time.Time 类型
|
||||
// 底层数据库引擎支持 time.Time/*time.Time 类型
|
||||
if _, ok := value.(time.Time); ok {
|
||||
continue
|
||||
}
|
||||
if _, ok := value.(*time.Time); ok {
|
||||
continue
|
||||
}
|
||||
// 如果执行String方法,那么执行字符串转换
|
||||
if s, ok := value.(apiString); ok {
|
||||
data[key] = s.String()
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
"github.com/gogf/gf/g/os/gtime"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestDbBase_Ping(t *testing.T) {
|
||||
@ -488,3 +489,51 @@ func TestDbBase_Delete(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDbBase_Time(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
result, err := db.Insert("user", g.Map{
|
||||
"id" : 200,
|
||||
"passport" : "t200",
|
||||
"password" : "123456",
|
||||
"nickname" : "T200",
|
||||
"create_time" : time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 1)
|
||||
value, err := db.GetValue("select `passport` from `user` where id=?", 200)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(value.String(), "t200")
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
t := time.Now()
|
||||
result, err := db.Insert("user", g.Map{
|
||||
"id" : 300,
|
||||
"passport" : "t300",
|
||||
"password" : "123456",
|
||||
"nickname" : "T300",
|
||||
"create_time" : &t,
|
||||
})
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 1)
|
||||
value, err := db.GetValue("select `passport` from `user` where id=?", 300)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(value.String(), "t300")
|
||||
})
|
||||
|
||||
if result, err := db.Delete("user", nil); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
n, _ := result.RowsAffected()
|
||||
gtest.Assert(n, 2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -10,7 +10,8 @@ import (
|
||||
"github.com/gogf/gf/g"
|
||||
"github.com/gogf/gf/g/os/gtime"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
"testing"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// 基本测试
|
||||
@ -28,7 +29,7 @@ func TestModel_Insert(t *testing.T) {
|
||||
}
|
||||
n, _ := result.LastInsertId()
|
||||
gtest.Assert(n, 1)
|
||||
|
||||
os.Exit(1)
|
||||
result, err = db.Table("user").Filter().Data(map[interface{}]interface{} {
|
||||
"id" : "2",
|
||||
"uid" : "2",
|
||||
|
||||
@ -136,7 +136,7 @@ func LoadContent(data interface{}, unsafe...bool) (*Json, error) {
|
||||
// auto check data type
|
||||
if json.Valid(b) {
|
||||
t = "json"
|
||||
} else if gregex.IsMatch(`^<.+>.*</.+>$`, b) {
|
||||
} else if gregex.IsMatch(`^<.+>[\S\s]+<.+>$`, b) {
|
||||
t = "xml"
|
||||
} else if gregex.IsMatch(`^[\s\t]*\w+\s*:\s*.+`, b) || gregex.IsMatch(`\n[\s\t]*\w+\s*:\s*.+`, b) {
|
||||
t = "yml"
|
||||
|
||||
@ -67,6 +67,24 @@ func Test_Load_XML(t *testing.T) {
|
||||
gtest.Assert(j.Get("doc.a"), g.Slice{1, 2, 3})
|
||||
gtest.Assert(j.Get("doc.a.1"), 2)
|
||||
})
|
||||
|
||||
// XML
|
||||
gtest.Case(t, func() {
|
||||
xml := `<?xml version="1.0"?>
|
||||
|
||||
<Output type="o">
|
||||
<itotalSize>0</itotalSize>
|
||||
<ipageSize>1</ipageSize>
|
||||
<ipageIndex>2</ipageIndex>
|
||||
<itotalRecords>GF框架</itotalRecords>
|
||||
<nworkOrderDtos/>
|
||||
<nworkOrderFrontXML/>
|
||||
</Output>`
|
||||
j, err := gjson.LoadContent(xml)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(j.Get("Output.ipageIndex"), "2")
|
||||
gtest.Assert(j.Get("Output.itotalRecords"), "GF框架")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Load_YAML1(t *testing.T) {
|
||||
|
||||
@ -40,7 +40,7 @@ func Load(path string, unsafe...bool) (*Parser, error) {
|
||||
// LoadContent creates a Parser object from given content,
|
||||
// it checks the data type of <content> automatically,
|
||||
// supporting JSON, XML, YAML and TOML types of data.
|
||||
func LoadContent(data []byte, unsafe...bool) (*Parser, error) {
|
||||
func LoadContent(data interface{}, unsafe...bool) (*Parser, error) {
|
||||
if j, e := gjson.LoadContent(data, unsafe...); e == nil {
|
||||
return &Parser{j}, nil
|
||||
} else {
|
||||
|
||||
@ -7,11 +7,11 @@
|
||||
package gparser_test
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/g"
|
||||
"github.com/gogf/gf/g/encoding/gparser"
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
"testing"
|
||||
"github.com/gogf/gf/g"
|
||||
"github.com/gogf/gf/g/encoding/gparser"
|
||||
"github.com/gogf/gf/g/os/gfile"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
||||
@ -67,6 +67,24 @@ func Test_Load_XML(t *testing.T) {
|
||||
gtest.Assert(j.Get("doc.a"), g.Slice{1, 2, 3})
|
||||
gtest.Assert(j.Get("doc.a.1"), 2)
|
||||
})
|
||||
|
||||
// XML
|
||||
gtest.Case(t, func() {
|
||||
xml := `<?xml version="1.0"?>
|
||||
|
||||
<Output type="o">
|
||||
<itotalSize>0</itotalSize>
|
||||
<ipageSize>1</ipageSize>
|
||||
<ipageIndex>2</ipageIndex>
|
||||
<itotalRecords>GF框架</itotalRecords>
|
||||
<nworkOrderDtos/>
|
||||
<nworkOrderFrontXML/>
|
||||
</Output>`
|
||||
j, err := gparser.LoadContent(xml)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(j.Get("Output.ipageIndex"), "2")
|
||||
gtest.Assert(j.Get("Output.itotalRecords"), "GF框架")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Load_YAML1(t *testing.T) {
|
||||
|
||||
@ -5,8 +5,6 @@
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
// Package gxml provides accessing and converting for XML content.
|
||||
//
|
||||
// XML数据格式解析。
|
||||
package gxml
|
||||
|
||||
import (
|
||||
@ -52,33 +50,26 @@ func ToJson(content []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
// XML字符集预处理
|
||||
// @author wenzi1
|
||||
// @date 20180604 修复并发安全问题,改为如果非UTF8字符集则先做字符集转换
|
||||
func convert(xmlbyte []byte) (res []byte, err error) {
|
||||
func convert(xml []byte) (res []byte, err error) {
|
||||
patten := `<\?xml.*encoding\s*=\s*['|"](.*?)['|"].*\?>`
|
||||
matchStr, err := gregex.MatchString(patten, string(xmlbyte))
|
||||
matchStr, err := gregex.MatchString(patten, string(xml))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
xmlEncode := "UTF-8"
|
||||
if len(matchStr) == 2 {
|
||||
xmlEncode = matchStr[1]
|
||||
}
|
||||
|
||||
s := mahonia.GetCharset(xmlEncode)
|
||||
if s == nil {
|
||||
return nil, fmt.Errorf("not support charset:%s\n", xmlEncode)
|
||||
}
|
||||
|
||||
res, err = gregex.Replace(patten, []byte(""), []byte(xmlbyte))
|
||||
res, err = gregex.Replace(patten, []byte(""), xml)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !strings.EqualFold(s.Name, "UTF-8") {
|
||||
res = []byte(s.NewDecoder().ConvertString(string(res)))
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@ -8,9 +8,11 @@ package gconv_test
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/g"
|
||||
"github.com/gogf/gf/g/os/gtime"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
"github.com/gogf/gf/g/util/gconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Test_Struct_Basic1(t *testing.T) {
|
||||
@ -347,4 +349,67 @@ func Test_Struct_Deep(t *testing.T) {
|
||||
gtest.Assert(user.Nickname, "T1")
|
||||
gtest.Assert(user.CreateTime, "2019")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Struct_Time(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
CreateTime time.Time
|
||||
}
|
||||
now := time.Now()
|
||||
user := new(User)
|
||||
gconv.Struct(g.Map{
|
||||
"create_time" : now,
|
||||
}, user)
|
||||
gtest.Assert(user.CreateTime.UTC().String(), now.UTC().String())
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
CreateTime *time.Time
|
||||
}
|
||||
now := time.Now()
|
||||
user := new(User)
|
||||
gconv.Struct(g.Map{
|
||||
"create_time" : &now,
|
||||
}, user)
|
||||
gtest.Assert(user.CreateTime.UTC().String(), now.UTC().String())
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
now := time.Now()
|
||||
user := new(User)
|
||||
gconv.Struct(g.Map{
|
||||
"create_time" : &now,
|
||||
}, user)
|
||||
gtest.Assert(user.CreateTime.Time.UTC().String(), now.UTC().String())
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
now := time.Now()
|
||||
user := new(User)
|
||||
gconv.Struct(g.Map{
|
||||
"create_time" : &now,
|
||||
}, user)
|
||||
gtest.Assert(user.CreateTime.Time.UTC().String(), now.UTC().String())
|
||||
})
|
||||
|
||||
gtest.Case(t, func() {
|
||||
type User struct {
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
now := time.Now()
|
||||
user := new(User)
|
||||
gconv.Struct(g.Map{
|
||||
"create_time" : now,
|
||||
}, user)
|
||||
gtest.Assert(user.CreateTime.Time.UTC().String(), now.UTC().String())
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -17,9 +17,9 @@ import (
|
||||
|
||||
func Test_Time(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
t1 := "2011-10-10 01:02:03.456"
|
||||
gtest.AssertEQ(gconv.GTime(t1), gtime.NewFromStr(t1))
|
||||
gtest.AssertEQ(gconv.Time(t1), gtime.NewFromStr(t1).Time)
|
||||
gtest.AssertEQ(gconv.Duration(100), 100*time.Nanosecond)
|
||||
})
|
||||
t1 := "2011-10-10 01:02:03.456"
|
||||
gtest.AssertEQ(gconv.GTime(t1), gtime.NewFromStr(t1))
|
||||
gtest.AssertEQ(gconv.Time(t1), gtime.NewFromStr(t1).Time)
|
||||
gtest.AssertEQ(gconv.Duration(100), 100*time.Nanosecond)
|
||||
})
|
||||
}
|
||||
|
||||
21
geg/encoding/gparser/gparser_xml.go
Normal file
21
geg/encoding/gparser/gparser_xml.go
Normal file
@ -0,0 +1,21 @@
|
||||
package main
|
||||
|
||||
import "github.com/gogf/gf/g/encoding/gparser"
|
||||
|
||||
func main() {
|
||||
xml := `<?xml version="1.0" encoding="GBK"?>
|
||||
|
||||
<Output type="o">
|
||||
<itotalSize>0</itotalSize>
|
||||
<ipageSize>1</ipageSize>
|
||||
<ipageIndex>2</ipageIndex>
|
||||
<itotalRecords>3</itotalRecords>
|
||||
<nworkOrderDtos/>
|
||||
<nworkOrderFrontXML/>
|
||||
</Output>`
|
||||
p, err := gparser.LoadContent([]byte(xml))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
p.Dump()
|
||||
}
|
||||
Reference in New Issue
Block a user