Skip to content

Commit

Permalink
not allow apppend
Browse files Browse the repository at this point in the history
  • Loading branch information
AsterDY committed Jan 17, 2024
1 parent 6640687 commit 71ade9f
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 91 deletions.
142 changes: 67 additions & 75 deletions ast/raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,8 @@ func (self *Value) SetAnyByPath(val interface{}, allowInsert bool, path ...inter
}

// SetByPath set value on given path and create nodes on the json if not exist
func (self *Value) SetByPath(val Value, allowInsert bool, path ...interface{}) (bool, error) {
// allowAppend controls if append val to V_ARRAY node if the path index is out of its range
func (self *Value) SetByPath(val Value, allowAppend bool, path ...interface{}) (bool, error) {
exist := false
if self.Check() != nil {
return exist, self
Expand All @@ -240,20 +241,6 @@ func (self *Value) SetByPath(val Value, allowInsert bool, path ...interface{}) (
var err types.ParsingError
var idx int

if !allowInsert {
//fast path
s, e := p.getByPath(path...)
if e != 0 {
return false, p.ExportError(e)
}
b := make([]byte, 0, len(self.js) + len(val.js) - (p.p - s))
b = append(b, self.js[:s]...)
b = append(b, val.js...)
b = append(b, self.js[p.p:]...)
self.js = rt.Mem2Str(b)
return exist, nil
}

for i, k := range path {
if id, ok := k.(int); ok && id >= 0 {
if _, err = p.searchIndex(id); err != 0 {
Expand All @@ -265,6 +252,9 @@ func (self *Value) SetByPath(val Value, allowInsert bool, path ...interface{}) (
}
} else if key, ok := k.(string); ok {
if _, err = p.searchKey(key); err != 0 {
if !allowAppend {
return false, p.ExportError(err)
}
if err != _ERR_NOT_FOUND {
return exist, p.ExportError(err)
}
Expand Down Expand Up @@ -583,20 +573,20 @@ func (ps points) Len() int {
// Set sets the node of given key under self, and insert new value if not exist.
// It reports if the key has existed.
func (self *Value) SetAny(key string, val interface{}, allowInsert bool) (bool, error) {
return self.SetMany([]string{key}, []Value{NewValue(val)}, allowInsert)
return self.SetMany([]string{key}, []Value{NewValue(val)})
}

// Set sets the node of given key under self, and insert new value if not exist.
// It reports if the key has existed.
func (self *Value) Set(key string, val Value, allowInsert bool) (bool, error) {
return self.SetMany([]string{key}, []Value{val}, allowInsert)
return self.SetMany([]string{key}, []Value{val})
}

// SetMany retries kvs in the V_OBJECT value,
// and replace (exist) or insert (not-exist) key with correpsonding value
//
// WARN: kvs shouldn't contains any repeated key, otherwise the repeated key will be regarded as new key and insert
func (self *Value) SetMany(keys []string, vals []Value, allowInsert bool) (bool, error) {
func (self *Value) SetMany(keys []string, vals []Value) (bool, error) {
if self.Check() != nil {
return false, self
}
Expand Down Expand Up @@ -654,54 +644,48 @@ func (self *Value) SetMany(keys []string, vals []Value, allowInsert bool) (bool,
b = append(b, self.js[r.e:s]...)
}

if allowInsert {
s = len(self.js) - 2
if !exist {
b = append(b, self.js[:s+1]...)
}
for ; s >= 0 && isSpace(self.js[s]); s-- {
s = len(self.js) - 2
if !exist {
b = append(b, self.js[:s+1]...)
}
for ; s >= 0 && isSpace(self.js[s]); s-- {
}
empty := self.js[s] == '{'

// write insert points
for _, r := range points {
if r.s != 0 {
continue
}
empty := self.js[s] == '{'

// write insert points
for _, r := range points {
if r.s != 0 {
continue
}
// write last ','
if !empty {
b = append(b, ","...)
}
empty = false
// write key
quote(&b, keys[r.i])
b = append(b, ":"...)
// write new val
b = append(b, vals[r.i].js...)
// write last ','
if !empty {
b = append(b, ","...)
}
empty = false
// write key
quote(&b, keys[r.i])
b = append(b, ":"...)
// write new val
b = append(b, vals[r.i].js...)
}

b = append(b, "}"...)
self.js = rt.Mem2Str(b)
return exist, nil
}

// SetByIndex sets the node of given index and insert new value if not exist.
// If the index is out range of self's children, it will be ADD to the last
// and reports if the key has existed.
// SetByIndex replaces the node of given index.
func (self *Value) SetAnyByIndex(id int, val interface{}) (bool, error) {
return self.SetByIndex(id, NewValue(val))
}

// SetByIndex sets the node of given index and insert new value if not exist.
// If the index is out range of self's children, it will be ADD to the last
// and reports if the key has existed.
// SetByIndex replaces the node of given index.
func (self *Value) SetByIndex(id int, val Value) (bool, error) {
return self.SetManyByIndex([]int{id}, []Value{val})
}

// SetManyByIndex retries ids in the V_ARRAY value,
// and replace (exist) or insert (not-exist) id of ids with correpsonding value of vals
// and replace existed ids with correpsonding value of vals
func (self *Value) SetManyByIndex(ids []int, vals []Value) (bool, error) {
if self.Check() != nil {
return false, self
Expand All @@ -728,6 +712,9 @@ func (self *Value) SetManyByIndex(ids []int, vals []Value) (bool, error) {
}); e != 0 {
return exist, NewParserObj(self.js).ExportError(e)
}
if !exist {
return false, ErrNotExist
}

// collect insert ponts
for i, r := range points {
Expand All @@ -738,12 +725,13 @@ func (self *Value) SetManyByIndex(ids []int, vals []Value) (bool, error) {
}

b := make([]byte, 0, size)

// write replace points
sort.Stable(points)
s := 0
notExist := false
for i, r := range points {
if r.s == 0 {
notExist = true
continue
}
// write left
Expand All @@ -753,39 +741,43 @@ func (self *Value) SetManyByIndex(ids []int, vals []Value) (bool, error) {
if i < len(points)-1 {
s = points[i+1].s
} else {
// not write '}'
s = len(self.js) - 1
s = len(self.js)
}
// write right
b = append(b, self.js[r.e:s]...)
}

s = len(self.js) - 2
if !exist {
b = append(b, self.js[:s+1]...)
}
for ; s >= 0 && isSpace(self.js[s]); s-- {
}
empty := self.js[s] == '['

// write insert points
for _, r := range points {
if r.s != 0 {
continue
}
// write last ','
if !empty {
b = append(b, ","...)
}
empty = false
// write new val
b = append(b, vals[r.i].js...)
}

b = append(b, "]"...)
// if allowAppend {
// s = len(self.js) - 2
// if !exist {
// b = append(b, self.js[:s+1]...)
// }
// for ; s >= 0 && isSpace(self.js[s]); s-- {
// }
// empty := self.js[s] == '['

// // write insert points
// for _, r := range points {
// if r.s != 0 {
// continue
// }
// // write last ','
// if !empty {
// b = append(b, ","...)
// }
// empty = false
// // write new val
// b = append(b, vals[r.i].js...)
// }
// }
// b = append(b, "]"...)

self.js = rt.Mem2Str(b)
return exist, nil
if notExist {
return exist, ErrNotExist
} else {
return exist, nil
}
}

// Add appends the given node under self.
Expand Down
28 changes: 12 additions & 16 deletions ast/raw_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,13 +294,13 @@ func TestSetMany(t *testing.T) {
{"replace 1, insert 1", `{ "a" : 1, "b" : 2} `, []keyVal{{"a", value(`11`)}, {"c", value(`33`)}}, `{ "a" : 11, "b" : 2,"c":33}`, ""},

{"replace 1", `[ 1, 2] `, []IndexVal{{0, value(`11`)}}, `[ 11, 2]`, ""},
{"replace 2", `[ 1, 2] `, []IndexVal{{0, value(`11`)}, {0, value(`22`)}}, `[ 11, 2,22]`, ""},
{"replace 2", `[ 1, 2] `, []IndexVal{{0, value(`11`)}, {0, value(`22`)}}, `[ 11, 2]`, "value not exists"},
{"replace repeated", `[ 1, 2] `, []IndexVal{{0, value(`11`)}, {1, value(`22`)}}, `[ 11, 22]`, ""},
{"insert empty", `[ ] `, []IndexVal{{2, value(`33`)}}, `[ 33]`, ""},
{"insert 1", `[ 1, 2] `, []IndexVal{{2, value(`33`)}}, `[ 1, 2,33]`, ""},
{"insert 2", `[ 1, 2] `, []IndexVal{{2, value(`33`)},{3, value(`44`)}}, `[ 1, 2,33,44]`, ""},
{"insert repeated", `[ 1, 2] `, []IndexVal{{2, value(`33`)},{2, value(`44`)}}, `[ 1, 2,33,44]`, ""},
{"replace 1, insert 1", `[ 1, 2] `, []IndexVal{{0, value(`11`)}, {2, value(`33`)}}, `[ 11, 2,33]`, ""},
{"insert empty", `[ ] `, []IndexVal{{2, value(`33`)}}, `[ ]`, "value not exists"},
{"insert 1", `[ 1, 2] `, []IndexVal{{2, value(`33`)}}, `[ 1, 2]`, "value not exists"},
{"insert 2", `[ 1, 2] `, []IndexVal{{2, value(`33`)},{3, value(`44`)}}, `[ 1, 2]`, "value not exists"},
{"insert repeated", `[ 1, 2] `, []IndexVal{{2, value(`33`)},{2, value(`44`)}}, `[ 1, 2]`, "value not exists"},
{"replace 1, insert 1", `[ 1, 2] `, []IndexVal{{0, value(`11`)}, {2, value(`33`)}}, `[ 11, 2]`, "value not exists"},
}

for i, c := range cases {
Expand All @@ -314,7 +314,7 @@ func TestSetMany(t *testing.T) {
keys = append(keys, kv.Key)
vals = append(vals, kv.Val)
}
_, err = node.SetMany(keys, vals, true)
_, err = node.SetMany(keys, vals)
require.Equal(t, c.exp, node.raw())
} else if ids, ok := c.kvs.([]IndexVal); ok {
keys := []int{}
Expand Down Expand Up @@ -465,9 +465,9 @@ func TestRawNode_Set(t *testing.T) {
{"not-exist object",`{"b":1}`,"a",NewValueJSON(`2`),false,"",`{"b":1,"a":2}`},
{"empty object",`{}`,"a",NewValueJSON(`2`),false,"",`{"a":2}`},
{"exist array",`[1]`,0,NewValueJSON(`2`),true,"",`[2]`},
{"not exist array",`[1]`,1,NewValueJSON(`2`),false,"",`[1,2]`},
{"not exist array over",`[1]`,99,NewValueJSON(`2`),false,"",`[1,2]`},
{"empty array",`[]`,1,NewValueJSON(`2`),false,"",`[2]`},
{"not exist array",`[1]`,1,NewValueJSON(`2`),false,"value not exists",`[1]`},
{"not exist array over",`[1]`,99,NewValueJSON(`2`),false,"value not exists",`[1]`},
{"empty array",`[]`,1,NewValueJSON(`2`),false,"value not exists",`[]`},
}
for _, c := range tests {
println(c.name)
Expand All @@ -483,13 +483,9 @@ func TestRawNode_Set(t *testing.T) {
t.Fatal()
}
if err != nil && err.Error() != c.err {
t.Fatal()
}
if out := root.raw(); err != nil {
t.Fatal()
} else {
require.Equal(t, c.out, out)
t.Fatal(err)
}
require.Equal(t, c.out, root.raw())
}
}

Expand Down

0 comments on commit 71ade9f

Please sign in to comment.