improve package gcfg/gjson for data loading

This commit is contained in:
John
2020-09-21 21:30:58 +08:00
parent 86433cef25
commit 28b0d59c61
4 changed files with 60 additions and 18 deletions

View File

@ -207,6 +207,21 @@ func LoadContentType(dataType string, data interface{}, safe ...bool) (*Json, er
return doLoadContent(dataType, content, safe...)
}
// IsValidDataType checks and returns whether given <dataType> an valid data type for loading.
func IsValidDataType(dataType string) bool {
if dataType == "" {
return false
}
if dataType[0] == '.' {
dataType = dataType[1:]
}
switch dataType {
case "json", "js", "xml", "yaml", "yml", "toml", "ini":
return true
}
return false
}
// checkDataType automatically checks and returns the data type for <content>.
// Note that it uses regular expression for loose checking, you can use LoadXXX/LoadContentType
// functions to load the content for certain content type.
@ -215,8 +230,9 @@ func checkDataType(content []byte) string {
return "json"
} else if gregex.IsMatch(`^<.+>[\S\s]+<.+>$`, content) {
return "xml"
} else if (gregex.IsMatch(`^[\n\r]*[\w\-\s\t]+\s*:\s*".+"`, content) || gregex.IsMatch(`^[\n\r]*[\w\-\s\t]+\s*:\s*\w+`, content)) ||
(gregex.IsMatch(`[\n\r]+[\w\-\s\t]+\s*:\s*".+"`, content) || gregex.IsMatch(`[\n\r]+[\w\-\s\t]+\s*:\s*\w+`, content)) {
} else if !gregex.IsMatch(`[\n\r]*[\s\t\w\-\."]+\s*=\s*"""[\s\S]+"""`, content) && !gregex.IsMatch(`[\n\r]*[\s\t\w\-\."]+\s*=\s*'''[\s\S]+'''`, content) &&
((gregex.IsMatch(`^[\n\r]*[\w\-\s\t]+\s*:\s*".+"`, content) || gregex.IsMatch(`^[\n\r]*[\w\-\s\t]+\s*:\s*\w+`, content)) ||
(gregex.IsMatch(`[\n\r]+[\w\-\s\t]+\s*:\s*".+"`, content) || gregex.IsMatch(`[\n\r]+[\w\-\s\t]+\s*:\s*\w+`, content))) {
return "yml"
} else if !gregex.IsMatch(`^[\s\t\n\r]*;.+`, content) &&
!gregex.IsMatch(`[\s\t\n\r]+;.+`, content) &&

View File

@ -112,4 +112,22 @@ app_conf = ./config/app.ini
`)
t.Assert(checkDataType(data), "ini")
})
gtest.C(t, func(t *gtest.T) {
data := []byte(`
# API Server
[server]
address = ":8199"
# Jenkins
[jenkins]
url = "https://jenkins-swimlane.com"
nodeJsStaticBuildCmdTpl = """
npm i --registry=https://registry.npm.taobao.org
wget http://consul.infra:8500/v1/kv/app_{{.SwimlaneName}}/{{.RepoName}}/.env.qa?raw=true -O ./env.qa
npm run build:qa
"""
`)
t.Assert(checkDataType(data), "toml")
})
}

View File

@ -334,7 +334,10 @@ func (c *Config) getJson(file ...string) *gjson.Json {
content = ""
filePath = ""
)
// The configured content can be any kind of data type different from its file type.
isFromConfigContent := true
if content = GetContent(name); content == "" {
isFromConfigContent = false
filePath = c.filePath(name)
if filePath == "" {
return nil
@ -346,7 +349,17 @@ func (c *Config) getJson(file ...string) *gjson.Json {
}
}
// Note that the underlying configuration json object operations are concurrent safe.
if j, err := gjson.LoadContent(content, true); err == nil {
var (
j *gjson.Json
err error
)
dataType := gfile.ExtName(name)
if gjson.IsValidDataType(dataType) && !isFromConfigContent {
j, err = gjson.LoadContentType(dataType, content, true)
} else {
j, err = gjson.LoadContent(content, true)
}
if err == nil {
j.SetViolenceCheck(c.vc)
// Add monitor for this configuration file,
// any changes of this file will refresh its cache in Config object.

View File

@ -231,21 +231,16 @@ func Test_SetFileName(t *testing.T) {
func Test_Instance(t *testing.T) {
config := `
{
"array": [
1,
2,
3
],
"redis": {
"cache": "127.0.0.1:6379,1",
"disk": "127.0.0.1:6379,0"
},
"v1": 1,
"v2": "true",
"v3": "off",
"v4": "1.234"
}
array = [1.0, 2.0, 3.0]
v1 = 1.0
v2 = "true"
v3 = "off"
v4 = "1.234"
[redis]
cache = "127.0.0.1:6379,1"
disk = "127.0.0.1:6379,0"
`
gtest.C(t, func(t *gtest.T) {
path := gcfg.DEFAULT_CONFIG_FILE