improve performance for gjson.Load* functions; add GetQueryVar/GetPostVar functions for ghttp.Request

This commit is contained in:
John
2019-07-16 16:23:03 +08:00
parent 0b62ccf941
commit 3fce835da0
3 changed files with 74 additions and 44 deletions

View File

@ -11,7 +11,10 @@ import (
"bytes"
"encoding/json"
"errors"
"fmt"
"reflect"
"github.com/gogf/gf/g/os/gfile"
"github.com/gogf/gf/g/encoding/gtoml"
"github.com/gogf/gf/g/encoding/gxml"
"github.com/gogf/gf/g/encoding/gyaml"
@ -19,7 +22,6 @@ import (
"github.com/gogf/gf/g/os/gfcache"
"github.com/gogf/gf/g/text/gregex"
"github.com/gogf/gf/g/util/gconv"
"reflect"
)
// New creates a Json object with any variable type of <data>,
@ -128,64 +130,82 @@ func DecodeToJson(data interface{}, unsafe ...bool) (*Json, error) {
// Load loads content from specified file <path>,
// and creates a Json object from its content.
func Load(path string, unsafe ...bool) (*Json, error) {
return LoadContent(gfcache.GetBinContents(path), unsafe...)
return doLoadContent(gfile.Ext(path), gfcache.GetBinContents(path), unsafe...)
}
// LoadContent creates a Json object from given content,
// it checks the data type of <content> automatically,
// supporting JSON, XML, YAML and TOML types of data.
func LoadContent(data interface{}, unsafe ...bool) (*Json, error) {
func LoadJson(data interface{}, unsafe ...bool) (*Json, error) {
return doLoadContent("json", gconv.Bytes(data), unsafe...)
}
func LoadXml(data interface{}, unsafe ...bool) (*Json, error) {
return doLoadContent("xml", gconv.Bytes(data), unsafe...)
}
func LoadYaml(data interface{}, unsafe ...bool) (*Json, error) {
return doLoadContent("yaml", gconv.Bytes(data), unsafe...)
}
func LoadToml(data interface{}, unsafe ...bool) (*Json, error) {
return doLoadContent("toml", gconv.Bytes(data), unsafe...)
}
func doLoadContent(dataType string, data []byte, unsafe ...bool) (*Json, error) {
var err error
var result interface{}
b := gconv.Bytes(data)
t := ""
if len(b) == 0 {
if len(data) == 0 {
return New(nil, unsafe...), nil
}
// auto check data type
if json.Valid(b) {
t = "json"
} 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"
} else if gregex.IsMatch(`^[\s\t]*\w+\s*=\s*.+`, b) || gregex.IsMatch(`\n[\s\t]*\w+\s*=\s*.+`, b) {
t = "toml"
} else {
return nil, errors.New("unsupported data type")
}
// convert to json type data
switch t {
switch dataType {
case "json", ".json":
// ok
decoder := json.NewDecoder(bytes.NewReader(data))
decoder.UseNumber()
if err = decoder.Decode(&result); err != nil {
return nil, err
}
case "xml", ".xml":
// TODO UseNumber
b, err = gxml.ToJson(b)
if result, err = gxml.Decode(data); err != nil {
return nil, err
}
case "yml", "yaml", ".yml", ".yaml":
// TODO UseNumber
b, err = gyaml.ToJson(b)
if result, err = gyaml.Decode(data); err != nil {
return nil, err
}
case "toml", ".toml":
// TODO UseNumber
b, err = gtoml.ToJson(b)
if result, err = gtoml.Decode(data); err != nil {
return nil, err
}
default:
err = errors.New("nonsupport type " + t)
err = errors.New("unsupported type for loading")
}
if err != nil {
return nil, err
}
if result == nil {
decoder := json.NewDecoder(bytes.NewReader(b))
decoder.UseNumber()
if err := decoder.Decode(&result); err != nil {
return nil, err
}
switch result.(type) {
case string, []byte:
return nil, fmt.Errorf(`json decoding failed for content: %s`, string(b))
}
}
return New(result, unsafe...), nil
}
func LoadContent(data interface{}, unsafe ...bool) (*Json, error) {
content := gconv.Bytes(data)
if len(content) == 0 {
return New(nil, unsafe...), nil
}
return doLoadContent(checkDataType(content), content, unsafe...)
}
func checkDataType(content []byte) string {
if json.Valid(content) {
return "json"
} else if gregex.IsMatch(`^<.+>[\S\s]+<.+>$`, content) {
return "xml"
} else if gregex.IsMatch(`^[\s\t]*\w+\s*:\s*.+`, content) || gregex.IsMatch(`\n[\s\t]*\w+\s*:\s*.+`, content) {
return "yml"
} else if gregex.IsMatch(`^[\s\t]*\w+\s*=\s*.+`, content) || gregex.IsMatch(`\n[\s\t]*\w+\s*=\s*.+`, content) {
return "toml"
} else {
return ""
}
}

View File

@ -7,6 +7,7 @@
package ghttp
import (
"github.com/gogf/gf/g/container/gvar"
"github.com/gogf/gf/g/internal/structs"
"github.com/gogf/gf/g/util/gconv"
)
@ -32,7 +33,6 @@ func (r *Request) AddPost(key string, value string) {
r.PostForm[key] = append(r.PostForm[key], value)
}
// 获得post参数
func (r *Request) GetPost(key string, def ...interface{}) []string {
r.initPost()
if v, ok := r.PostForm[key]; ok {
@ -44,6 +44,10 @@ func (r *Request) GetPost(key string, def ...interface{}) []string {
return nil
}
func (r *Request) GetPostVar(key string, def ...interface{}) *gvar.Var {
return gvar.New(r.GetPostString(key, def...), true)
}
func (r *Request) GetPostString(key string, def ...interface{}) string {
value := r.GetPost(key, def...)
if value != nil && value[0] != "" {

View File

@ -9,6 +9,8 @@ package ghttp
import (
"strings"
"github.com/gogf/gf/g/container/gvar"
"github.com/gogf/gf/g/internal/structs"
"github.com/gogf/gf/g/util/gconv"
)
@ -54,6 +56,10 @@ func (r *Request) GetQuery(key string, def ...interface{}) []string {
return nil
}
func (r *Request) GetQueryVar(key string, def ...interface{}) *gvar.Var {
return gvar.New(r.GetQueryString(key, def...), true)
}
func (r *Request) GetQueryString(key string, def ...interface{}) string {
value := r.GetQuery(key, def...)
if value != nil && value[0] != "" {