Skip to content

Commit

Permalink
api: update all Update and Upsert requests
Browse files Browse the repository at this point in the history
`Op` struct made private.
Change all `Upsert` and `Update` requests to accept
`*tarantool.Operations` as `ops` parameters instead of
`interface{}`.

Closes #348
  • Loading branch information
DerekBum authored and oleg-jukovec committed Nov 17, 2023
1 parent a5de8f3 commit 6225ec4
Show file tree
Hide file tree
Showing 16 changed files with 281 additions and 107 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
constants for `protocol` (#337)
- Change `crud` operations `Timeout` option type to `crud.OptFloat64`
instead of `crud.OptUint` (#342)
- Change all `Upsert` and `Update` requests to accept `*tarantool.Operations`
as `ops` parameters instead of `interface{}` (#348)

### Deprecated

Expand Down
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,17 @@ of the requests is an array instead of array of arrays.

IPROTO constants have been moved to a separate package [go-iproto](https://github.com/tarantool/go-iproto).

#### Request interface
#### Request changes

* The method `Code() uint32` replaced by the `Type() iproto.Type`.
* `Op` struct for update operations made private.
* Removed `OpSplice` struct.
* `Operations.Splice` method now accepts 5 arguments instead of 3.
* Requests `Update`, `UpdateAsync`, `UpdateTyped`, `Upsert`, `UpsertAsync` no
longer accept `ops` argument (operations) as an `interface{}`. `*Operations`
needs to be passed instead.
* `UpdateRequest` and `UpsertRequest` structs no longer accept `interface{}`
for an `ops` field. `*Operations` needs to be used instead.

#### Connect function

Expand All @@ -253,11 +261,6 @@ interface to get information if the usage of space and index names in requests
is supported.
* `Schema` structure no longer implements `SchemaResolver` interface.

#### Client tools changes

* Remove `OpSplice` struct.
* `Operations.Splice` method now accepts 5 arguments instead of 3.

## Contributing

See [the contributing guide](CONTRIBUTING.md) for detailed instructions on how
Expand Down
20 changes: 12 additions & 8 deletions client_tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func (k IntIntKey) EncodeMsgpack(enc *msgpack.Encoder) error {
return nil
}

// Op - is update operation.
type Op struct {
// operation - is update operation.
type operation struct {
Op string
Field int
Arg interface{}
Expand All @@ -65,7 +65,7 @@ type Op struct {
Replace string
}

func (o Op) EncodeMsgpack(enc *msgpack.Encoder) error {
func (o operation) EncodeMsgpack(enc *msgpack.Encoder) error {
isSpliceOperation := o.Op == spliceOperator
argsLen := 3
if isSpliceOperation {
Expand Down Expand Up @@ -108,22 +108,26 @@ const (

// Operations is a collection of update operations.
type Operations struct {
ops []Op
ops []operation
}

// EncodeMsgpack encodes Operations as an array of operations.
func (ops *Operations) EncodeMsgpack(enc *msgpack.Encoder) error {
return enc.Encode(ops.ops)
}

// NewOperations returns a new empty collection of update operations.
func NewOperations() *Operations {
ops := new(Operations)
return ops
return &Operations{[]operation{}}
}

func (ops *Operations) append(op string, field int, arg interface{}) *Operations {
ops.ops = append(ops.ops, Op{Op: op, Field: field, Arg: arg})
ops.ops = append(ops.ops, operation{Op: op, Field: field, Arg: arg})
return ops
}

func (ops *Operations) appendSplice(op string, field, pos, len int, replace string) *Operations {
ops.ops = append(ops.ops, Op{Op: op, Field: field, Pos: pos, Len: len, Replace: replace})
ops.ops = append(ops.ops, operation{Op: op, Field: field, Pos: pos, Len: len, Replace: replace})
return ops
}

Expand Down
51 changes: 51 additions & 0 deletions client_tools_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package tarantool_test

import (
"bytes"
"testing"

"github.com/vmihailenco/msgpack/v5"

"github.com/tarantool/go-tarantool/v2"
)

func TestOperations_EncodeMsgpack(t *testing.T) {
ops := tarantool.NewOperations().
Add(1, 2).
Subtract(1, 2).
BitwiseAnd(1, 2).
BitwiseOr(1, 2).
BitwiseXor(1, 2).
Splice(1, 2, 3, "a").
Insert(1, 2).
Delete(1, 2).
Assign(1, 2)
refOps := []interface{}{
[]interface{}{"+", 1, 2},
[]interface{}{"-", 1, 2},
[]interface{}{"&", 1, 2},
[]interface{}{"|", 1, 2},
[]interface{}{"^", 1, 2},
[]interface{}{":", 1, 2, 3, "a"},
[]interface{}{"!", 1, 2},
[]interface{}{"#", 1, 2},
[]interface{}{"=", 1, 2},
}

var refBuf bytes.Buffer
encRef := msgpack.NewEncoder(&refBuf)
if err := encRef.Encode(refOps); err != nil {
t.Errorf("error while encoding: %v", err.Error())
}

var buf bytes.Buffer
enc := msgpack.NewEncoder(&buf)

if err := enc.Encode(ops); err != nil {
t.Errorf("error while encoding: %v", err.Error())
}
if !bytes.Equal(refBuf.Bytes(), buf.Bytes()) {
t.Errorf("encode response is wrong:\n expected %v\n got: %v",
refBuf, buf.Bytes())
}
}
11 changes: 6 additions & 5 deletions connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ type Connector interface {
Delete(space, index interface{}, key interface{}) (*Response, error)
// Deprecated: the method will be removed in the next major version,
// use a UpdateRequest object + Do() instead.
Update(space, index interface{}, key, ops interface{}) (*Response, error)
Update(space, index interface{}, key interface{}, ops *Operations) (*Response, error)
// Deprecated: the method will be removed in the next major version,
// use a UpsertRequest object + Do() instead.
Upsert(space interface{}, tuple, ops interface{}) (*Response, error)
Upsert(space interface{}, tuple interface{}, ops *Operations) (*Response, error)
// Deprecated: the method will be removed in the next major version,
// use a CallRequest object + Do() instead.
Call(functionName string, args interface{}) (*Response, error)
Expand Down Expand Up @@ -67,7 +67,8 @@ type Connector interface {
DeleteTyped(space, index interface{}, key interface{}, result interface{}) error
// Deprecated: the method will be removed in the next major version,
// use a UpdateRequest object + Do() instead.
UpdateTyped(space, index interface{}, key, ops interface{}, result interface{}) error
UpdateTyped(space, index interface{}, key interface{}, ops *Operations,
result interface{}) error
// Deprecated: the method will be removed in the next major version,
// use a CallRequest object + Do() instead.
CallTyped(functionName string, args interface{}, result interface{}) error
Expand Down Expand Up @@ -100,10 +101,10 @@ type Connector interface {
DeleteAsync(space, index interface{}, key interface{}) *Future
// Deprecated: the method will be removed in the next major version,
// use a UpdateRequest object + Do() instead.
UpdateAsync(space, index interface{}, key, ops interface{}) *Future
UpdateAsync(space, index interface{}, key interface{}, ops *Operations) *Future
// Deprecated: the method will be removed in the next major version,
// use a UpsertRequest object + Do() instead.
UpsertAsync(space interface{}, tuple interface{}, ops interface{}) *Future
UpsertAsync(space interface{}, tuple interface{}, ops *Operations) *Future
// Deprecated: the method will be removed in the next major version,
// use a CallRequest object + Do() instead.
CallAsync(functionName string, args interface{}) *Future
Expand Down
1 change: 1 addition & 0 deletions crud/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type Operation struct {
Replace string
}

// EncodeMsgpack encodes Operation.
func (o Operation) EncodeMsgpack(enc *msgpack.Encoder) error {
isSpliceOperation := o.Operator == Splice
argsLen := 3
Expand Down
123 changes: 123 additions & 0 deletions crud/operations_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package crud_test

import (
"bytes"
"testing"

"github.com/vmihailenco/msgpack/v5"

"github.com/tarantool/go-tarantool/v2/crud"
)

func TestOperation_EncodeMsgpack(t *testing.T) {
testCases := []struct {
name string
op crud.Operation
ref []interface{}
}{
{
"Add",
crud.Operation{
Operator: crud.Add,
Field: 1,
Value: 2,
},
[]interface{}{"+", 1, 2},
},
{
"Sub",
crud.Operation{
Operator: crud.Sub,
Field: 1,
Value: 2,
},
[]interface{}{"-", 1, 2},
},
{
"And",
crud.Operation{
Operator: crud.And,
Field: 1,
Value: 2,
},
[]interface{}{"&", 1, 2},
},
{
"Or",
crud.Operation{
Operator: crud.Or,
Field: 1,
Value: 2,
},
[]interface{}{"|", 1, 2},
},
{
"Xor",
crud.Operation{
Operator: crud.Xor,
Field: 1,
Value: 2,
},
[]interface{}{"^", 1, 2},
},
{
"Splice",
crud.Operation{
Operator: crud.Splice,
Field: 1,
Pos: 2,
Len: 3,
Replace: "a",
},
[]interface{}{":", 1, 2, 3, "a"},
},
{
"Insert",
crud.Operation{
Operator: crud.Insert,
Field: 1,
Value: 2,
},
[]interface{}{"!", 1, 2},
},
{
"Delete",
crud.Operation{
Operator: crud.Delete,
Field: 1,
Value: 2,
},
[]interface{}{"#", 1, 2},
},
{
"Assign",
crud.Operation{
Operator: crud.Assign,
Field: 1,
Value: 2,
},
[]interface{}{"=", 1, 2},
},
}

for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
var refBuf bytes.Buffer
encRef := msgpack.NewEncoder(&refBuf)
if err := encRef.Encode(test.ref); err != nil {
t.Errorf("error while encoding: %v", err.Error())
}

var buf bytes.Buffer
enc := msgpack.NewEncoder(&buf)

if err := enc.Encode(test.op); err != nil {
t.Errorf("error while encoding: %v", err.Error())
}
if !bytes.Equal(refBuf.Bytes(), buf.Bytes()) {
t.Errorf("encode response is wrong:\n expected %v\n got: %v",
refBuf, buf.Bytes())
}
})
}
}
4 changes: 2 additions & 2 deletions export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func RefImplDeleteBody(enc *msgpack.Encoder, res SchemaResolver, space, index,
// RefImplUpdateBody is reference implementation for filling of an update
// request's body.
func RefImplUpdateBody(enc *msgpack.Encoder, res SchemaResolver, space, index,
key, ops interface{}) error {
key interface{}, ops *Operations) error {
spaceEnc, err := newSpaceEncoder(res, space)
if err != nil {
return err
Expand All @@ -93,7 +93,7 @@ func RefImplUpdateBody(enc *msgpack.Encoder, res SchemaResolver, space, index,
// RefImplUpsertBody is reference implementation for filling of an upsert
// request's body.
func RefImplUpsertBody(enc *msgpack.Encoder, res SchemaResolver, space,
tuple, ops interface{}) error {
tuple interface{}, ops *Operations) error {
spaceEnc, err := newSpaceEncoder(res, space)
if err != nil {
return err
Expand Down
20 changes: 10 additions & 10 deletions pool/connection_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,8 @@ func (p *ConnectionPool) Delete(space, index interface{}, key interface{},
//
// Deprecated: the method will be removed in the next major version,
// use a UpdateRequest object + Do() instead.
func (p *ConnectionPool) Update(space, index interface{}, key, ops interface{},
userMode ...Mode) (*tarantool.Response, error) {
func (p *ConnectionPool) Update(space, index interface{}, key interface{},
ops *tarantool.Operations, userMode ...Mode) (*tarantool.Response, error) {
conn, err := p.getConnByMode(RW, userMode)
if err != nil {
return nil, err
Expand All @@ -477,8 +477,8 @@ func (p *ConnectionPool) Update(space, index interface{}, key, ops interface{},
//
// Deprecated: the method will be removed in the next major version,
// use a UpsertRequest object + Do() instead.
func (p *ConnectionPool) Upsert(space interface{}, tuple, ops interface{},
userMode ...Mode) (*tarantool.Response, error) {
func (p *ConnectionPool) Upsert(space interface{}, tuple interface{},
ops *tarantool.Operations, userMode ...Mode) (*tarantool.Response, error) {
conn, err := p.getConnByMode(RW, userMode)
if err != nil {
return nil, err
Expand Down Expand Up @@ -639,8 +639,8 @@ func (p *ConnectionPool) DeleteTyped(space, index interface{}, key interface{},
//
// Deprecated: the method will be removed in the next major version,
// use a UpdateRequest object + Do() instead.
func (p *ConnectionPool) UpdateTyped(space, index interface{}, key, ops interface{},
result interface{}, userMode ...Mode) error {
func (p *ConnectionPool) UpdateTyped(space, index interface{}, key interface{},
ops *tarantool.Operations, result interface{}, userMode ...Mode) error {
conn, err := p.getConnByMode(RW, userMode)
if err != nil {
return err
Expand Down Expand Up @@ -788,8 +788,8 @@ func (p *ConnectionPool) DeleteAsync(space, index interface{}, key interface{},
//
// Deprecated: the method will be removed in the next major version,
// use a UpdateRequest object + Do() instead.
func (p *ConnectionPool) UpdateAsync(space, index interface{}, key, ops interface{},
userMode ...Mode) *tarantool.Future {
func (p *ConnectionPool) UpdateAsync(space, index interface{}, key interface{},
ops *tarantool.Operations, userMode ...Mode) *tarantool.Future {
conn, err := p.getConnByMode(RW, userMode)
if err != nil {
return newErrorFuture(err)
Expand All @@ -803,8 +803,8 @@ func (p *ConnectionPool) UpdateAsync(space, index interface{}, key, ops interfac
//
// Deprecated: the method will be removed in the next major version,
// use a UpsertRequest object + Do() instead.
func (p *ConnectionPool) UpsertAsync(space interface{}, tuple interface{}, ops interface{},
userMode ...Mode) *tarantool.Future {
func (p *ConnectionPool) UpsertAsync(space interface{}, tuple interface{},
ops *tarantool.Operations, userMode ...Mode) *tarantool.Future {
conn, err := p.getConnByMode(RW, userMode)
if err != nil {
return newErrorFuture(err)
Expand Down
Loading

0 comments on commit 6225ec4

Please sign in to comment.