diff --git a/g/database/gdb/gdb_func.go b/g/database/gdb/gdb_func.go
index 374def4ee..f010d23b4 100644
--- a/g/database/gdb/gdb_func.go
+++ b/g/database/gdb/gdb_func.go
@@ -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()
diff --git a/g/database/gdb/gdb_unit_method_test.go b/g/database/gdb/gdb_unit_method_test.go
index 8bc04ca87..a620bd8c9 100644
--- a/g/database/gdb/gdb_unit_method_test.go
+++ b/g/database/gdb/gdb_unit_method_test.go
@@ -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)
+ }
+}
+
+
+
diff --git a/g/database/gdb/gdb_unit_model_test.go b/g/database/gdb/gdb_unit_model_test.go
index 504fd8c89..41e5d3294 100644
--- a/g/database/gdb/gdb_unit_model_test.go
+++ b/g/database/gdb/gdb_unit_model_test.go
@@ -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",
diff --git a/g/encoding/gjson/gjson_api_new_load.go b/g/encoding/gjson/gjson_api_new_load.go
index 72a0df0ec..e1d32340d 100644
--- a/g/encoding/gjson/gjson_api_new_load.go
+++ b/g/encoding/gjson/gjson_api_new_load.go
@@ -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"
diff --git a/g/encoding/gjson/gjson_z_unit_load_test.go b/g/encoding/gjson/gjson_z_unit_load_test.go
index 7c096428e..6717ea124 100644
--- a/g/encoding/gjson/gjson_z_unit_load_test.go
+++ b/g/encoding/gjson/gjson_z_unit_load_test.go
@@ -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 := `
+
+ `
+ 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) {
diff --git a/g/encoding/gparser/gparser_api_new_load.go b/g/encoding/gparser/gparser_api_new_load.go
index 434d05bd1..0cf99c054 100644
--- a/g/encoding/gparser/gparser_api_new_load.go
+++ b/g/encoding/gparser/gparser_api_new_load.go
@@ -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 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 {
diff --git a/g/encoding/gparser/gparser_unit_load_test.go b/g/encoding/gparser/gparser_unit_load_test.go
index 930693a72..2702ca05f 100644
--- a/g/encoding/gparser/gparser_unit_load_test.go
+++ b/g/encoding/gparser/gparser_unit_load_test.go
@@ -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 := `
+
+ `
+ 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) {
diff --git a/g/encoding/gxml/gxml.go b/g/encoding/gxml/gxml.go
index 828d7f8ca..6d4b1ea97 100644
--- a/g/encoding/gxml/gxml.go
+++ b/g/encoding/gxml/gxml.go
@@ -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
}
diff --git a/g/util/gconv/gconv_z_unit_struct_test.go b/g/util/gconv/gconv_z_unit_struct_test.go
index c2426083a..35d4274f8 100644
--- a/g/util/gconv/gconv_z_unit_struct_test.go
+++ b/g/util/gconv/gconv_z_unit_struct_test.go
@@ -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")
})
-}
\ No newline at end of file
+}
+
+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())
+ })
+}
+
diff --git a/g/util/gconv/gconv_z_unit_time_test.go b/g/util/gconv/gconv_z_unit_time_test.go
index 7195f89f6..994b7856e 100644
--- a/g/util/gconv/gconv_z_unit_time_test.go
+++ b/g/util/gconv/gconv_z_unit_time_test.go
@@ -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)
+ })
}
diff --git a/geg/encoding/gparser.go b/geg/encoding/gparser/gparser.go
similarity index 100%
rename from geg/encoding/gparser.go
rename to geg/encoding/gparser/gparser.go
diff --git a/geg/encoding/gparser/gparser_xml.go b/geg/encoding/gparser/gparser_xml.go
new file mode 100644
index 000000000..375600951
--- /dev/null
+++ b/geg/encoding/gparser/gparser_xml.go
@@ -0,0 +1,21 @@
+package main
+
+import "github.com/gogf/gf/g/encoding/gparser"
+
+func main() {
+ xml := `
+
+ `
+ p, err := gparser.LoadContent([]byte(xml))
+ if err != nil {
+ panic(err)
+ }
+ p.Dump()
+}