From 5c6ff3a63fddb21cb1833af238037956dae5e89d Mon Sep 17 00:00:00 2001 From: DerekBum Date: Wed, 15 Nov 2023 18:15:31 +0300 Subject: [PATCH] api: update all `Update` and `Upsert` requests `Op` struct made private. Change all `Upsert` and `Update` requests to accept `*tarantool.Operations` as `ops` parameters instead of `interface{}`. Closes #348 --- CHANGELOG.md | 2 ++ README.md | 1 + client_tools.go | 17 +++++++----- client_tools_test.go | 51 ++++++++++++++++++++++++++++++++++++ connector.go | 11 ++++---- crud/operations.go | 1 + export_test.go | 4 +-- pool/connection_pool.go | 20 +++++++------- pool/connection_pool_test.go | 8 +++--- pool/connector.go | 14 +++++----- pool/connector_test.go | 20 +++++++------- pool/pooler.go | 14 +++++----- request.go | 39 +++++++++++++-------------- request_test.go | 34 ++++++++---------------- tarantool_test.go | 12 ++++----- 15 files changed, 149 insertions(+), 99 deletions(-) create mode 100644 client_tools_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 709490e2c..609e71380 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/README.md b/README.md index c4b1edeeb..677d2d290 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/client_tools.go b/client_tools.go index 396645205..50ab7bae3 100644 --- a/client_tools.go +++ b/client_tools.go @@ -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{} @@ -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 { @@ -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. @@ -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 } diff --git a/client_tools_test.go b/client_tools_test.go new file mode 100644 index 000000000..fdd109152 --- /dev/null +++ b/client_tools_test.go @@ -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()) + } +} diff --git a/connector.go b/connector.go index 5d4b5be39..9536116d7 100644 --- a/connector.go +++ b/connector.go @@ -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) @@ -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 @@ -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 diff --git a/crud/operations.go b/crud/operations.go index 633afe7c6..84953d590 100644 --- a/crud/operations.go +++ b/crud/operations.go @@ -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 diff --git a/export_test.go b/export_test.go index a52ef5b26..2c28472b9 100644 --- a/export_test.go +++ b/export_test.go @@ -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 @@ -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 diff --git a/pool/connection_pool.go b/pool/connection_pool.go index aa84d8c24..6186683b3 100644 --- a/pool/connection_pool.go +++ b/pool/connection_pool.go @@ -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 @@ -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 @@ -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 @@ -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) @@ -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) diff --git a/pool/connection_pool_test.go b/pool/connection_pool_test.go index 27310be23..8b19e671b 100644 --- a/pool/connection_pool_test.go +++ b/pool/connection_pool_test.go @@ -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") @@ -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") @@ -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") @@ -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") diff --git a/pool/connector.go b/pool/connector.go index acb9a9187..604e3921f 100644 --- a/pool/connector.go +++ b/pool/connector.go @@ -106,7 +106,7 @@ 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) } @@ -114,8 +114,8 @@ func (c *ConnectorAdapter) Update(space, index interface{}, // // 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) } @@ -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) } @@ -314,7 +314,7 @@ 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) } @@ -322,8 +322,8 @@ func (c *ConnectorAdapter) UpdateAsync(space, index interface{}, // // 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) } diff --git a/pool/connector_test.go b/pool/connector_test.go index b667b0d34..fa107cc58 100644 --- a/pool/connector_test.go +++ b/pool/connector_test.go @@ -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} @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/pool/pooler.go b/pool/pooler.go index a588d67f4..0ff945bbb 100644 --- a/pool/pooler.go +++ b/pool/pooler.go @@ -38,11 +38,11 @@ type Pooler interface { mode ...Mode) (*tarantool.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{}, + Update(space, index interface{}, key interface{}, ops *tarantool.Operations, mode ...Mode) (*tarantool.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{}, + Upsert(space interface{}, tuple interface{}, ops *tarantool.Operations, mode ...Mode) (*tarantool.Response, error) // Deprecated: the method will be removed in the next major version, // use a CallRequest object + Do() instead. @@ -87,8 +87,8 @@ type Pooler interface { mode ...Mode) 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{}, mode ...Mode) error + UpdateTyped(space, index interface{}, key interface{}, + ops *tarantool.Operations, result interface{}, mode ...Mode) 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{}, @@ -128,11 +128,11 @@ type Pooler interface { mode ...Mode) *tarantool.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{}, - mode ...Mode) *tarantool.Future + UpdateAsync(space, index interface{}, key interface{}, + ops *tarantool.Operations, mode ...Mode) *tarantool.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{}, + UpsertAsync(space interface{}, tuple interface{}, ops *tarantool.Operations, mode ...Mode) *tarantool.Future // Deprecated: the method will be removed in the next major version, // use a CallRequest object + Do() instead. diff --git a/request.go b/request.go index c2e7cf96d..ac0f7e858 100644 --- a/request.go +++ b/request.go @@ -182,16 +182,20 @@ func fillSelect(enc *msgpack.Encoder, spaceEnc spaceEncoder, indexEnc indexEncod } func fillUpdate(enc *msgpack.Encoder, spaceEnc spaceEncoder, indexEnc indexEncoder, - key, ops interface{}) error { + key interface{}, ops *Operations) error { enc.EncodeMapLen(4) if err := fillSearch(enc, spaceEnc, indexEnc, key); err != nil { return err } enc.EncodeUint(uint64(iproto.IPROTO_TUPLE)) + if ops == nil { + return enc.Encode([]interface{}{}) + } return enc.Encode(ops) } -func fillUpsert(enc *msgpack.Encoder, spaceEnc spaceEncoder, tuple, ops interface{}) error { +func fillUpsert(enc *msgpack.Encoder, spaceEnc spaceEncoder, tuple interface{}, + ops *Operations) error { enc.EncodeMapLen(3) if err := spaceEnc.Encode(enc); err != nil { return err @@ -202,6 +206,9 @@ func fillUpsert(enc *msgpack.Encoder, spaceEnc spaceEncoder, tuple, ops interfac return err } enc.EncodeUint(uint64(iproto.IPROTO_OPS)) + if ops == nil { + return enc.Encode([]interface{}{}) + } return enc.Encode(ops) } @@ -308,7 +315,7 @@ func (conn *Connection) Delete(space, index interface{}, key interface{}) (*Resp // // Deprecated: the method will be removed in the next major version, // use a UpdateRequest object + Do() instead. -func (conn *Connection) Update(space, index interface{}, key, ops interface{}) (*Response, error) { +func (conn *Connection) Update(space, index, key interface{}, ops *Operations) (*Response, error) { return conn.UpdateAsync(space, index, key, ops).Get() } @@ -319,7 +326,7 @@ func (conn *Connection) 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 (conn *Connection) Upsert(space interface{}, tuple, ops interface{}) (*Response, error) { +func (conn *Connection) Upsert(space, tuple interface{}, ops *Operations) (*Response, error) { return conn.UpsertAsync(space, tuple, ops).Get() } @@ -464,8 +471,8 @@ func (conn *Connection) DeleteTyped(space, index interface{}, key interface{}, // // Deprecated: the method will be removed in the next major version, // use a UpdateRequest object + Do() instead. -func (conn *Connection) UpdateTyped(space, index interface{}, key, ops interface{}, - result interface{}) error { +func (conn *Connection) UpdateTyped(space, index interface{}, key interface{}, + ops *Operations, result interface{}) error { return conn.UpdateAsync(space, index, key, ops).GetTyped(result) } @@ -580,7 +587,8 @@ func (conn *Connection) DeleteAsync(space, index interface{}, key interface{}) * // // Deprecated: the method will be removed in the next major version, // use a UpdateRequest object + Do() instead. -func (conn *Connection) UpdateAsync(space, index interface{}, key, ops interface{}) *Future { +func (conn *Connection) UpdateAsync(space, index interface{}, key interface{}, + ops *Operations) *Future { req := NewUpdateRequest(space).Index(index).Key(key) req.ops = ops return conn.Do(req) @@ -591,8 +599,7 @@ func (conn *Connection) UpdateAsync(space, index interface{}, key, ops interface // // Deprecated: the method will be removed in the next major version, // use a UpsertRequest object + Do() instead. -func (conn *Connection) UpsertAsync(space interface{}, tuple interface{}, - ops interface{}) *Future { +func (conn *Connection) UpsertAsync(space, tuple interface{}, ops *Operations) *Future { req := NewUpsertRequest(space).Tuple(tuple) req.ops = ops return conn.Do(req) @@ -1193,7 +1200,7 @@ func (req *DeleteRequest) Context(ctx context.Context) *DeleteRequest { type UpdateRequest struct { spaceIndexRequest key interface{} - ops interface{} + ops *Operations } // NewUpdateRequest returns a new empty UpdateRequest. @@ -1202,7 +1209,6 @@ func NewUpdateRequest(space interface{}) *UpdateRequest { req.rtype = iproto.IPROTO_UPDATE req.setSpace(space) req.key = []interface{}{} - req.ops = []interface{}{} return req } @@ -1223,9 +1229,7 @@ func (req *UpdateRequest) Key(key interface{}) *UpdateRequest { // Operations sets operations to be performed on update. // Note: default value is empty. func (req *UpdateRequest) Operations(ops *Operations) *UpdateRequest { - if ops != nil { - req.ops = ops.ops - } + req.ops = ops return req } @@ -1259,7 +1263,7 @@ func (req *UpdateRequest) Context(ctx context.Context) *UpdateRequest { type UpsertRequest struct { spaceRequest tuple interface{} - ops interface{} + ops *Operations } // NewUpsertRequest returns a new empty UpsertRequest. @@ -1268,7 +1272,6 @@ func NewUpsertRequest(space interface{}) *UpsertRequest { req.rtype = iproto.IPROTO_UPSERT req.setSpace(space) req.tuple = []interface{}{} - req.ops = []interface{}{} return req } @@ -1282,9 +1285,7 @@ func (req *UpsertRequest) Tuple(tuple interface{}) *UpsertRequest { // Operations sets operations to be performed on update case by the upsert request. // Note: default value is empty. func (req *UpsertRequest) Operations(ops *Operations) *UpsertRequest { - if ops != nil { - req.ops = ops.ops - } + req.ops = ops return req } diff --git a/request_test.go b/request_test.go index af06e3c61..580259702 100644 --- a/request_test.go +++ b/request_test.go @@ -118,19 +118,7 @@ func assertBodyEqual(t testing.TB, reference []byte, req Request) { } } -func getTestOps() ([]Op, *Operations) { - ops := []Op{ - {Op: "+", Field: 1, Arg: 2}, - {Op: "-", Field: 3, Arg: 4}, - {Op: "&", Field: 5, Arg: 6}, - {Op: "|", Field: 7, Arg: 8}, - {Op: "^", Field: 9, Arg: 1}, - {Op: "^", Field: 9, Arg: 1}, // The duplication is for test purposes. - {Op: ":", Field: 2, Pos: 3, Len: 1, Replace: "!!"}, - {Op: "!", Field: 4, Arg: 5}, - {Op: "#", Field: 6, Arg: 7}, - {Op: "=", Field: 8, Arg: 9}, - } +func getTestOps() *Operations { operations := NewOperations(). Add(1, 2). Subtract(3, 4). @@ -142,7 +130,7 @@ func getTestOps() ([]Op, *Operations) { Insert(4, 5). Delete(6, 7). Assign(8, 9) - return ops, operations + return operations } func TestRequestsValidSpaceAndIndex(t *testing.T) { @@ -670,7 +658,7 @@ func TestUpdateRequestDefaultValues(t *testing.T) { refEnc := msgpack.NewEncoder(&refBuf) err := RefImplUpdateBody(refEnc, &resolver, validSpace, defaultIndex, - []interface{}{}, []Op{}) + []interface{}{}, nil) if err != nil { t.Fatalf("An unexpected RefImplUpdateBody() error: %q", err.Error()) } @@ -686,7 +674,7 @@ func TestUpdateRequestSpaceByName(t *testing.T) { refEnc := msgpack.NewEncoder(&refBuf) err := RefImplUpdateBody(refEnc, &resolver, "valid", defaultIndex, - []interface{}{}, []Op{}) + []interface{}{}, nil) if err != nil { t.Fatalf("An unexpected RefImplUpdateBody() error: %q", err.Error()) } @@ -702,7 +690,7 @@ func TestUpdateRequestIndexByName(t *testing.T) { refEnc := msgpack.NewEncoder(&refBuf) err := RefImplUpdateBody(refEnc, &resolver, defaultSpace, "valid", - []interface{}{}, []Op{}) + []interface{}{}, nil) if err != nil { t.Fatalf("An unexpected RefImplUpdateBody() error: %q", err.Error()) } @@ -714,11 +702,11 @@ func TestUpdateRequestIndexByName(t *testing.T) { func TestUpdateRequestSetters(t *testing.T) { key := []interface{}{uint(44)} - refOps, reqOps := getTestOps() + reqOps := getTestOps() var refBuf bytes.Buffer refEnc := msgpack.NewEncoder(&refBuf) - err := RefImplUpdateBody(refEnc, &resolver, validSpace, validIndex, key, refOps) + err := RefImplUpdateBody(refEnc, &resolver, validSpace, validIndex, key, reqOps) if err != nil { t.Fatalf("An unexpected RefImplUpdateBody() error: %q", err.Error()) } @@ -734,7 +722,7 @@ func TestUpsertRequestDefaultValues(t *testing.T) { var refBuf bytes.Buffer refEnc := msgpack.NewEncoder(&refBuf) - err := RefImplUpsertBody(refEnc, &resolver, validSpace, []interface{}{}, []Op{}) + err := RefImplUpsertBody(refEnc, &resolver, validSpace, []interface{}{}, nil) if err != nil { t.Fatalf("An unexpected RefImplUpsertBody() error: %q", err.Error()) } @@ -749,7 +737,7 @@ func TestUpsertRequestSpaceByName(t *testing.T) { resolver.nameUseSupported = true refEnc := msgpack.NewEncoder(&refBuf) - err := RefImplUpsertBody(refEnc, &resolver, "valid", []interface{}{}, []Op{}) + err := RefImplUpsertBody(refEnc, &resolver, "valid", []interface{}{}, nil) if err != nil { t.Fatalf("An unexpected RefImplUpsertBody() error: %q", err.Error()) } @@ -760,11 +748,11 @@ func TestUpsertRequestSpaceByName(t *testing.T) { func TestUpsertRequestSetters(t *testing.T) { tuple := []interface{}{uint(64)} - refOps, reqOps := getTestOps() + reqOps := getTestOps() var refBuf bytes.Buffer refEnc := msgpack.NewEncoder(&refBuf) - err := RefImplUpsertBody(refEnc, &resolver, validSpace, tuple, refOps) + err := RefImplUpsertBody(refEnc, &resolver, validSpace, tuple, reqOps) if err != nil { t.Fatalf("An unexpected RefImplUpsertBody() error: %q", err.Error()) } diff --git a/tarantool_test.go b/tarantool_test.go index 8be963474..f8da2bdb5 100644 --- a/tarantool_test.go +++ b/tarantool_test.go @@ -992,7 +992,7 @@ func TestClient(t *testing.T) { // Update resp, err = conn.Update(spaceNo, indexNo, []interface{}{uint(2)}, - []interface{}{[]interface{}{"=", 1, "bye"}, []interface{}{"#", 2, 1}}) + NewOperations().Assign(1, "bye").Delete(2, 1)) if err != nil { t.Fatalf("Failed to Update: %s", err.Error()) } @@ -1021,7 +1021,7 @@ func TestClient(t *testing.T) { // Upsert resp, err = conn.Upsert(spaceNo, []interface{}{uint(3), 1}, - []interface{}{[]interface{}{"+", 1, 1}}) + NewOperations().Add(1, 1)) if err != nil { t.Fatalf("Failed to Upsert (insert): %s", err.Error()) } @@ -1032,7 +1032,7 @@ func TestClient(t *testing.T) { t.Errorf("Response should not have a position") } resp, err = conn.Upsert(spaceNo, []interface{}{uint(3), 1}, - []interface{}{[]interface{}{"+", 1, 1}}) + NewOperations().Add(1, 1)) if err != nil { t.Fatalf("Failed to Upsert (update): %s", err.Error()) } @@ -2095,7 +2095,7 @@ func TestClientNamed(t *testing.T) { resp, err = conn.Update(spaceName, indexName, []interface{}{ uint(1002)}, - []interface{}{[]interface{}{"=", 1, "bye"}, []interface{}{"#", 2, 1}}) + NewOperations().Assign(1, "buy").Delete(2, 1)) if err != nil { t.Fatalf("Failed to Update: %s", err.Error()) } @@ -2105,7 +2105,7 @@ func TestClientNamed(t *testing.T) { // Upsert resp, err = conn.Upsert(spaceName, - []interface{}{uint(1003), 1}, []interface{}{[]interface{}{"+", 1, 1}}) + []interface{}{uint(1003), 1}, NewOperations().Add(1, 1)) if err != nil { t.Fatalf("Failed to Upsert (insert): %s", err.Error()) } @@ -2113,7 +2113,7 @@ func TestClientNamed(t *testing.T) { t.Errorf("Response is nil after Upsert (insert)") } resp, err = conn.Upsert(spaceName, - []interface{}{uint(1003), 1}, []interface{}{[]interface{}{"+", 1, 1}}) + []interface{}{uint(1003), 1}, NewOperations().Add(1, 1)) if err != nil { t.Fatalf("Failed to Upsert (update): %s", err.Error()) }