Skip to content

Commit 6cf3110

Browse files
committed
api: fix splice update operation
Splice update operation (`:`) accepts 5 and only 5 arguments. It was parsed and encoded incorrectly with only 3 argument (as every other update operations). Also fixed the same operation for the crud. Closes #348
1 parent 39ec344 commit 6cf3110

File tree

3 files changed

+84
-38
lines changed

3 files changed

+84
-38
lines changed

client_tools.go

+37-24
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,38 @@ type Op struct {
5959
Op string
6060
Field int
6161
Arg interface{}
62+
// Pos, Len, Replace fields used in the Splice operation
63+
Pos int
64+
Len int
65+
Replace string
6266
}
6367

6468
func (o Op) EncodeMsgpack(enc *msgpack.Encoder) error {
65-
enc.EncodeArrayLen(3)
66-
enc.EncodeString(o.Op)
67-
enc.EncodeInt(int64(o.Field))
69+
isSpliceOperation := o.Op == spliceOperator
70+
argsLen := 3
71+
if isSpliceOperation {
72+
argsLen = 5
73+
}
74+
if err := enc.EncodeArrayLen(argsLen); err != nil {
75+
return err
76+
}
77+
if err := enc.EncodeString(o.Op); err != nil {
78+
return err
79+
}
80+
if err := enc.EncodeInt(int64(o.Field)); err != nil {
81+
return err
82+
}
83+
84+
if isSpliceOperation {
85+
if err := enc.EncodeInt(int64(o.Pos)); err != nil {
86+
return err
87+
}
88+
if err := enc.EncodeInt(int64(o.Len)); err != nil {
89+
return err
90+
}
91+
return enc.EncodeString(o.Replace)
92+
}
93+
6894
return enc.Encode(o.Arg)
6995
}
7096

@@ -92,7 +118,12 @@ func NewOperations() *Operations {
92118
}
93119

94120
func (ops *Operations) append(op string, field int, arg interface{}) *Operations {
95-
ops.ops = append(ops.ops, Op{op, field, arg})
121+
ops.ops = append(ops.ops, Op{Op: op, Field: field, Arg: arg})
122+
return ops
123+
}
124+
125+
func (ops *Operations) appendSplice(op string, field, pos, len int, replace string) *Operations {
126+
ops.ops = append(ops.ops, Op{Op: op, Field: field, Pos: pos, Len: len, Replace: replace})
96127
return ops
97128
}
98129

@@ -122,8 +153,8 @@ func (ops *Operations) BitwiseXor(field int, arg interface{}) *Operations {
122153
}
123154

124155
// Splice adds a splice operation to the collection of update operations.
125-
func (ops *Operations) Splice(field int, arg interface{}) *Operations {
126-
return ops.append(spliceOperator, field, arg)
156+
func (ops *Operations) Splice(field, pos, len int, replace string) *Operations {
157+
return ops.appendSplice(spliceOperator, field, pos, len, replace)
127158
}
128159

129160
// Insert adds an insert operation to the collection of update operations.
@@ -140,21 +171,3 @@ func (ops *Operations) Delete(field int, arg interface{}) *Operations {
140171
func (ops *Operations) Assign(field int, arg interface{}) *Operations {
141172
return ops.append(assignOperator, field, arg)
142173
}
143-
144-
type OpSplice struct {
145-
Op string
146-
Field int
147-
Pos int
148-
Len int
149-
Replace string
150-
}
151-
152-
func (o OpSplice) EncodeMsgpack(enc *msgpack.Encoder) error {
153-
enc.EncodeArrayLen(5)
154-
enc.EncodeString(o.Op)
155-
enc.EncodeInt(int64(o.Field))
156-
enc.EncodeInt(int64(o.Pos))
157-
enc.EncodeInt(int64(o.Len))
158-
enc.EncodeString(o.Replace)
159-
return nil
160-
}

crud/operations.go

+36-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package crud
22

3+
import "github.com/vmihailenco/msgpack/v5"
4+
35
const (
46
// Add - operator for addition.
57
Add Operator = "+"
@@ -23,11 +25,42 @@ const (
2325

2426
// Operation describes CRUD operation as a table
2527
// {operator, field_identifier, value}.
28+
// Splice operation described as a table
29+
// {operator, field_identifier, position, length, replace_string}
2630
type Operation struct {
27-
// Instruct msgpack to pack this struct as array, so no custom packer
28-
// is needed.
29-
_msgpack struct{} `msgpack:",asArray"` //nolint: structcheck,unused
3031
Operator Operator
3132
Field interface{} // Number or string.
3233
Value interface{}
34+
Pos int
35+
Len int
36+
Replace string
37+
}
38+
39+
func (o Operation) EncodeMsgpack(enc *msgpack.Encoder) error {
40+
isSpliceOperation := o.Operator == Splice
41+
argsLen := 3
42+
if isSpliceOperation {
43+
argsLen = 5
44+
}
45+
if err := enc.EncodeArrayLen(argsLen); err != nil {
46+
return err
47+
}
48+
if err := enc.EncodeString(string(o.Operator)); err != nil {
49+
return err
50+
}
51+
if err := enc.Encode(o.Field); err != nil {
52+
return err
53+
}
54+
55+
if isSpliceOperation {
56+
if err := enc.EncodeInt(int64(o.Pos)); err != nil {
57+
return err
58+
}
59+
if err := enc.EncodeInt(int64(o.Len)); err != nil {
60+
return err
61+
}
62+
return enc.EncodeString(o.Replace)
63+
}
64+
65+
return enc.Encode(o.Value)
3366
}

request_test.go

+11-11
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,16 @@ func assertBodyEqual(t testing.TB, reference []byte, req Request) {
120120

121121
func getTestOps() ([]Op, *Operations) {
122122
ops := []Op{
123-
{"+", 1, 2},
124-
{"-", 3, 4},
125-
{"&", 5, 6},
126-
{"|", 7, 8},
127-
{"^", 9, 1},
128-
{"^", 9, 1}, // The duplication is for test purposes.
129-
{":", 2, 3},
130-
{"!", 4, 5},
131-
{"#", 6, 7},
132-
{"=", 8, 9},
123+
{Op: "+", Field: 1, Arg: 2},
124+
{Op: "-", Field: 3, Arg: 4},
125+
{Op: "&", Field: 5, Arg: 6},
126+
{Op: "|", Field: 7, Arg: 8},
127+
{Op: "^", Field: 9, Arg: 1},
128+
{Op: "^", Field: 9, Arg: 1}, // The duplication is for test purposes.
129+
{Op: ":", Field: 2, Pos: 3, Len: 1, Replace: "!!"},
130+
{Op: "!", Field: 4, Arg: 5},
131+
{Op: "#", Field: 6, Arg: 7},
132+
{Op: "=", Field: 8, Arg: 9},
133133
}
134134
operations := NewOperations().
135135
Add(1, 2).
@@ -138,7 +138,7 @@ func getTestOps() ([]Op, *Operations) {
138138
BitwiseOr(7, 8).
139139
BitwiseXor(9, 1).
140140
BitwiseXor(9, 1). // The duplication is for test purposes.
141-
Splice(2, 3).
141+
Splice(2, 3, 1, "!!").
142142
Insert(4, 5).
143143
Delete(6, 7).
144144
Assign(8, 9)

0 commit comments

Comments
 (0)