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 committed Nov 16, 2023
1 parent c43db4d commit 5c6ff3a
Show file tree
Hide file tree
Showing 15 changed files with 149 additions and 99 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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ is supported.

#### Client tools changes

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

Expand Down
17 changes: 11 additions & 6 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,7 +108,12 @@ 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.
Expand All @@ -118,12 +123,12 @@ func NewOperations() *Operations {
}

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
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
8 changes: 4 additions & 4 deletions pool/connection_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1964,7 +1964,7 @@ func TestUpsert(t *testing.T) {
// Mode is `RW` by default, we have only one RW instance (servers[2])
resp, err := connPool.Upsert(spaceName,
[]interface{}{"upsert_key", "upsert_value"},
[]interface{}{[]interface{}{"=", 1, "new_value"}})
tarantool.NewOperations().Assign(1, "new_value"))
require.Nilf(t, err, "failed to Upsert")
require.NotNilf(t, resp, "response is nil after Upsert")

Expand Down Expand Up @@ -1993,7 +1993,7 @@ func TestUpsert(t *testing.T) {
// PreferRW
resp, err = connPool.Upsert(
spaceName, []interface{}{"upsert_key", "upsert_value"},
[]interface{}{[]interface{}{"=", 1, "new_value"}}, pool.PreferRW)
tarantool.NewOperations().Assign(1, "new_value"), pool.PreferRW)

require.Nilf(t, err, "failed to Upsert")
require.NotNilf(t, resp, "response is nil after Upsert")
Expand Down Expand Up @@ -2056,7 +2056,7 @@ func TestUpdate(t *testing.T) {

// Mode is `RW` by default, we have only one RW instance (servers[2])
resp, err = connPool.Update(spaceName, indexNo,
[]interface{}{"update_key"}, []interface{}{[]interface{}{"=", 1, "new_value"}})
[]interface{}{"update_key"}, tarantool.NewOperations().Assign(1, "new_value"))
require.Nilf(t, err, "failed to Update")
require.NotNilf(t, resp, "response is nil after Update")

Expand Down Expand Up @@ -2085,7 +2085,7 @@ func TestUpdate(t *testing.T) {
// PreferRW
resp, err = connPool.Update(
spaceName, indexNo, []interface{}{"update_key"},
[]interface{}{[]interface{}{"=", 1, "another_value"}}, pool.PreferRW)
tarantool.NewOperations().Assign(1, "another_value"), pool.PreferRW)

require.Nilf(t, err, "failed to Update")
require.NotNilf(t, resp, "response is nil after Update")
Expand Down
14 changes: 7 additions & 7 deletions pool/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,16 @@ func (c *ConnectorAdapter) Delete(space, index interface{},
// Deprecated: the method will be removed in the next major version,
// use a UpdateRequest object + Do() instead.
func (c *ConnectorAdapter) Update(space, index interface{},
key, ops interface{}) (*tarantool.Response, error) {
key interface{}, ops *tarantool.Operations) (*tarantool.Response, error) {
return c.pool.Update(space, index, key, ops, c.mode)
}

// Upsert performs "update or insert" action of a tuple by key.
//
// Deprecated: the method will be removed in the next major version,
// use a UpsertRequest object + Do() instead.
func (c *ConnectorAdapter) Upsert(space interface{},
tuple, ops interface{}) (*tarantool.Response, error) {
func (c *ConnectorAdapter) Upsert(space, tuple interface{},
ops *tarantool.Operations) (*tarantool.Response, error) {
return c.pool.Upsert(space, tuple, ops, c.mode)
}

Expand Down Expand Up @@ -220,7 +220,7 @@ func (c *ConnectorAdapter) DeleteTyped(space, index interface{},
// Deprecated: the method will be removed in the next major version,
// use a UpdateRequest object + Do() instead.
func (c *ConnectorAdapter) UpdateTyped(space, index interface{},
key, ops interface{}, result interface{}) error {
key interface{}, ops *tarantool.Operations, result interface{}) error {
return c.pool.UpdateTyped(space, index, key, ops, result, c.mode)
}

Expand Down Expand Up @@ -314,16 +314,16 @@ func (c *ConnectorAdapter) DeleteAsync(space, index interface{},
// Deprecated: the method will be removed in the next major version,
// use a UpdateRequest object + Do() instead.
func (c *ConnectorAdapter) UpdateAsync(space, index interface{},
key, ops interface{}) *tarantool.Future {
key interface{}, ops *tarantool.Operations) *tarantool.Future {
return c.pool.UpdateAsync(space, index, key, ops, c.mode)
}

// UpsertAsync sends "update or insert" action to Tarantool and returns Future.
//
// Deprecated: the method will be removed in the next major version,
// use a UpsertRequest object + Do() instead.
func (c *ConnectorAdapter) UpsertAsync(space interface{}, tuple interface{},
ops interface{}) *tarantool.Future {
func (c *ConnectorAdapter) UpsertAsync(space, tuple interface{},
ops *tarantool.Operations) *tarantool.Future {
return c.pool.UpsertAsync(space, tuple, ops, c.mode)
}

Expand Down
20 changes: 10 additions & 10 deletions pool/connector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ var reqIndex interface{} = []interface{}{2}
var reqArgs interface{} = []interface{}{3}
var reqTuple interface{} = []interface{}{4}
var reqKey interface{} = []interface{}{5}
var reqOps interface{} = []interface{}{6}
var reqOps = tarantool.NewOperations()

var reqResult interface{} = []interface{}{7}
var reqSqlInfo = tarantool.SQLInfo{AffectedCount: 3}
Expand Down Expand Up @@ -547,8 +547,8 @@ type updateMock struct {
baseRequestMock
}

func (m *updateMock) Update(space, index, key, ops interface{},
mode ...Mode) (*tarantool.Response, error) {
func (m *updateMock) Update(space, index, key interface{},
ops *tarantool.Operations, mode ...Mode) (*tarantool.Response, error) {
m.called++
m.space = space
m.index = index
Expand Down Expand Up @@ -578,8 +578,8 @@ type updateTypedMock struct {
baseRequestMock
}

func (m *updateTypedMock) UpdateTyped(space, index, key, ops interface{},
result interface{}, mode ...Mode) error {
func (m *updateTypedMock) UpdateTyped(space, index, key interface{},
ops *tarantool.Operations, result interface{}, mode ...Mode) error {
m.called++
m.space = space
m.index = index
Expand Down Expand Up @@ -610,8 +610,8 @@ type updateAsyncMock struct {
baseRequestMock
}

func (m *updateAsyncMock) UpdateAsync(space, index, key, ops interface{},
mode ...Mode) *tarantool.Future {
func (m *updateAsyncMock) UpdateAsync(space, index, key interface{},
ops *tarantool.Operations, mode ...Mode) *tarantool.Future {
m.called++
m.space = space
m.index = index
Expand Down Expand Up @@ -640,7 +640,7 @@ type upsertMock struct {
baseRequestMock
}

func (m *upsertMock) Upsert(space, tuple, ops interface{},
func (m *upsertMock) Upsert(space, tuple interface{}, ops *tarantool.Operations,
mode ...Mode) (*tarantool.Response, error) {
m.called++
m.space = space
Expand Down Expand Up @@ -669,8 +669,8 @@ type upsertAsyncMock struct {
baseRequestMock
}

func (m *upsertAsyncMock) UpsertAsync(space, tuple, ops interface{},
mode ...Mode) *tarantool.Future {
func (m *upsertAsyncMock) UpsertAsync(space, tuple interface{},
ops *tarantool.Operations, mode ...Mode) *tarantool.Future {
m.called++
m.space = space
m.tuple = tuple
Expand Down
Loading

0 comments on commit 5c6ff3a

Please sign in to comment.