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 := ` + + + 0 + 1 + 2 + GF框架 + + + ` + 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 := ` + + + 0 + 1 + 2 + GF框架 + + + ` + 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 := ` + + + 0 + 1 + 2 + 3 + + + ` + p, err := gparser.LoadContent([]byte(xml)) + if err != nil { + panic(err) + } + p.Dump() +}