mirror of
https://gitee.com/johng/gf
synced 2026-06-25 01:05:41 +08:00
去掉gfile/glog中的文件指针池使用,修复gjson的Set方法在自己元素为[]interface{}类型下的实效问题
This commit is contained in:
@ -40,36 +40,22 @@ type Json struct {
|
||||
// 将变量转换为Json对象进行处理,该变量至少应当是一个map或者array,否者转换没有意义
|
||||
func New(value interface{}, safe...bool) *Json {
|
||||
j := (*Json)(nil)
|
||||
if value != nil {
|
||||
switch value.(type) {
|
||||
case map[string]interface{}:
|
||||
j = &Json{
|
||||
p : &value,
|
||||
c : byte(gDEFAULT_SPLIT_CHAR),
|
||||
vc : false ,
|
||||
}
|
||||
case []interface{}:
|
||||
j = &Json{
|
||||
p : &value,
|
||||
c : byte(gDEFAULT_SPLIT_CHAR),
|
||||
vc : false ,
|
||||
}
|
||||
default:
|
||||
// 这里效率会比较低
|
||||
b, _ := Encode(value)
|
||||
v, _ := Decode(b)
|
||||
j = &Json{
|
||||
p : &v,
|
||||
c : byte(gDEFAULT_SPLIT_CHAR),
|
||||
vc : false,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
j = &Json{
|
||||
p : nil,
|
||||
c : byte(gDEFAULT_SPLIT_CHAR),
|
||||
vc : false,
|
||||
}
|
||||
switch value.(type) {
|
||||
case map[string]interface{}, []interface{}, nil:
|
||||
j = &Json{
|
||||
p : &value,
|
||||
c : byte(gDEFAULT_SPLIT_CHAR),
|
||||
vc : false ,
|
||||
}
|
||||
default:
|
||||
// 这里效率会比较低
|
||||
b, _ := Encode(value)
|
||||
v, _ := Decode(b)
|
||||
j = &Json{
|
||||
p : &v,
|
||||
c : byte(gDEFAULT_SPLIT_CHAR),
|
||||
vc : false,
|
||||
}
|
||||
}
|
||||
j.mu = rwmutex.New(safe...)
|
||||
return j
|
||||
@ -389,7 +375,16 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
|
||||
if removed && value == nil {
|
||||
goto done
|
||||
}
|
||||
j.setPointerWithValue(pointer, array[i], value)
|
||||
if pparent == nil {
|
||||
// 表示根节点
|
||||
j.setPointerWithValue(pointer, array[i], value)
|
||||
} else {
|
||||
// 非根节点
|
||||
s := make([]interface{}, valn + 1)
|
||||
copy(s, (*pointer).([]interface{}))
|
||||
s[valn] = value
|
||||
j.setPointerWithValue(pparent, array[i - 1], s)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if gstr.IsNumeric(array[i + 1]) {
|
||||
@ -518,16 +513,29 @@ func (j *Json) Get(pattern...string) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 计算指定pattern的元素长度(pattern对应数据类型为map[string]interface{}/[]interface{}时有效)
|
||||
func (j *Json) Len(pattern string) int {
|
||||
p := j.getPointerByPattern(pattern)
|
||||
if p != nil {
|
||||
switch (*p).(type) {
|
||||
case map[string]interface{}:
|
||||
return len((*p).(map[string]interface{}))
|
||||
case []interface{}:
|
||||
return len((*p).([]interface{}))
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// 指定pattern追加元素
|
||||
func (j *Json) Append(pattern string, value interface{}) error {
|
||||
p := j.getPointerByPattern(pattern)
|
||||
switch t := (*p).(type) {
|
||||
case []interface{}:
|
||||
*p = append((*p).([]interface{}), value)
|
||||
return nil
|
||||
default:
|
||||
return errors.New(fmt.Sprintf("invalid type '%s' to append", t))
|
||||
length := j.Len(pattern)
|
||||
if length != -1 {
|
||||
return j.Set(fmt.Sprintf("%s.%d", pattern, length), value)
|
||||
}
|
||||
return errors.New(fmt.Sprintf("cannot find item for pattern: %s", pattern))
|
||||
}
|
||||
|
||||
// 根据pattern层级查找**变量指针**
|
||||
|
||||
@ -152,9 +152,14 @@ func (p *Parser) Set(pattern string, value interface{}) error {
|
||||
return p.json.Set(pattern, value)
|
||||
}
|
||||
|
||||
// 计算指定pattern的元素长度(pattern对应数据类型为map[string]interface{}/[]interface{}时有效)
|
||||
func (p *Parser) Len(pattern string) int {
|
||||
return p.json.Len(pattern)
|
||||
}
|
||||
|
||||
// 指定pattern追加元素
|
||||
func (j *Parser) Append(pattern string, value interface{}) error {
|
||||
return j.json.Append(pattern, value)
|
||||
func (p *Parser) Append(pattern string, value interface{}) error {
|
||||
return p.json.Append(pattern, value)
|
||||
}
|
||||
|
||||
// 动态删除变量节点
|
||||
@ -205,6 +210,11 @@ func (p *Parser) ToToml() ([]byte, error) {
|
||||
return p.json.ToToml()
|
||||
}
|
||||
|
||||
// 打印Json对象
|
||||
func (p *Parser) Dump() error {
|
||||
return p.json.Dump()
|
||||
}
|
||||
|
||||
// 将变量解析为对应的struct对象,注意传递的参数为struct对象指针
|
||||
func (p *Parser) ToStruct(o interface{}) error {
|
||||
return p.json.ToStruct(o)
|
||||
@ -237,4 +247,5 @@ func VarToToml(value interface{}) ([]byte, error) {
|
||||
// 将变量解析为对应的struct对象,注意传递的参数为struct对象指针
|
||||
func VarToStruct(value interface{}, obj interface{}) error {
|
||||
return New(value).ToStruct(obj)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -187,6 +187,36 @@ func Test_Set11(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Set12(t *testing.T) {
|
||||
e := []byte(`[0,1]`)
|
||||
p := gparser.New(nil)
|
||||
p.Set("0", 0)
|
||||
p.Set("1", 1)
|
||||
if c, err := p.ToJson(); err == nil {
|
||||
fmt.Println(string(c))
|
||||
if bytes.Compare(c, e) != 0 {
|
||||
t.Error("expect:", string(e))
|
||||
}
|
||||
} else {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Set13(t *testing.T) {
|
||||
e := []byte(`{"array":[0,1]}`)
|
||||
p := gparser.New(nil)
|
||||
p.Set("array.0", 0)
|
||||
p.Set("array.1", 1)
|
||||
if c, err := p.ToJson(); err == nil {
|
||||
fmt.Println(string(c))
|
||||
if bytes.Compare(c, e) != 0 {
|
||||
t.Error("expect:", string(e))
|
||||
}
|
||||
} else {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -22,7 +22,6 @@ import (
|
||||
"path/filepath"
|
||||
"gitee.com/johng/gf/g/util/gregex"
|
||||
"gitee.com/johng/gf/g/container/gtype"
|
||||
"gitee.com/johng/gf/g/os/gfilepool"
|
||||
"sort"
|
||||
)
|
||||
|
||||
@ -383,7 +382,7 @@ func putContents(path string, data []byte, flag int, perm os.FileMode) error {
|
||||
}
|
||||
}
|
||||
// 创建/打开文件,使用文件指针池,默认为60秒
|
||||
f, err := gfilepool.OpenWithPool(path, flag, perm, 60000)
|
||||
f, err := os.OpenFile(path, flag, perm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@ import (
|
||||
"strconv"
|
||||
"gitee.com/johng/gf/g/os/gfile"
|
||||
"gitee.com/johng/gf/g/util/gregex"
|
||||
"gitee.com/johng/gf/g/os/gfilepool"
|
||||
"gitee.com/johng/gf/g/container/gtype"
|
||||
"gitee.com/johng/gf/g/os/gmlock"
|
||||
)
|
||||
@ -102,10 +101,10 @@ func (l *Logger) GetIO() io.Writer {
|
||||
}
|
||||
|
||||
// 获取默认的文件IO
|
||||
func (l *Logger) getFileByPool() *gfilepool.File {
|
||||
func (l *Logger) getFilePointer() *os.File {
|
||||
if path := l.path.Val(); path != "" {
|
||||
fpath := path + gfile.Separator + time.Now().Format("2006-01-02.log")
|
||||
if fp, err := gfilepool.OpenWithPool(fpath, gDEFAULT_FILE_POOL_FLAGS, 0666, 86400000); err == nil {
|
||||
if fp, err := os.OpenFile(fpath, gDEFAULT_FILE_POOL_FLAGS, 0666); err == nil {
|
||||
return fp
|
||||
} else {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
@ -145,7 +144,7 @@ func (l *Logger) print(std io.Writer, s string) {
|
||||
if writer == nil {
|
||||
// 如果设置的IO为空,那么其次判断是否有文件输出设置
|
||||
// 内部使用了内存锁,保证在glog中对同一个日志文件的并发写入不会串日志
|
||||
if f := l.getFileByPool(); f != nil {
|
||||
if f := l.getFilePointer(); f != nil {
|
||||
defer f.Close()
|
||||
key := l.path.Val()
|
||||
gmlock.Lock(key)
|
||||
|
||||
@ -5,9 +5,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
j := gjson.NewUnsafe([]int{1,2,3})
|
||||
j.Append("", 4)
|
||||
j.Append("", "abc")
|
||||
j := gjson.New(nil)
|
||||
j.Set("array", []int{1,2,3})
|
||||
j.Append("array", 4)
|
||||
j.Dump()
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user