去掉gfile/glog中的文件指针池使用,修复gjson的Set方法在自己元素为[]interface{}类型下的实效问题

This commit is contained in:
john
2018-09-14 17:02:07 +08:00
parent 2a0a294ce9
commit e0baf618c5
6 changed files with 97 additions and 51 deletions

View File

@ -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层级查找**变量指针**

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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)

View File

@ -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()
}