diff --git a/CHANGELOG.md b/CHANGELOG.md index b4cdf0012..01d08c408 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release. - Support `operation_data` in `crud.Error` (#330) - Support `fetch_latest_metadata` option for crud requests with metadata (#335) - Support `noreturn` option for data change crud requests (#335) -- Support `crud.schema` request (#336) +- Support `crud.schema` request (#336, #351) - Support `IPROTO_WATCH_ONCE` request type for Tarantool version >= 3.0.0-alpha1 (#337) - Support `yield_every` option for crud select requests (#350) diff --git a/crud/options.go b/crud/options.go index eec3fc0db..311df522c 100644 --- a/crud/options.go +++ b/crud/options.go @@ -23,6 +23,7 @@ const ( batchSizeOptName = "batch_size" fetchLatestMetadataOptName = "fetch_latest_metadata" noreturnOptName = "noreturn" + cachedOptName = "cached" ) // OptUint is an optional uint. diff --git a/crud/request_test.go b/crud/request_test.go index 8a64ab427..719c64a66 100644 --- a/crud/request_test.go +++ b/crud/request_test.go @@ -194,6 +194,7 @@ func TestRequestsCodes(t *testing.T) { {req: crud.MakeCountRequest(validSpace), rtype: CrudRequestType}, {req: crud.MakeStorageInfoRequest(), rtype: CrudRequestType}, {req: crud.MakeStatsRequest(), rtype: CrudRequestType}, + {req: crud.MakeSchemaRequest(), rtype: CrudRequestType}, } for _, test := range tests { @@ -231,6 +232,7 @@ func TestRequestsAsync(t *testing.T) { {req: crud.MakeCountRequest(validSpace), async: false}, {req: crud.MakeStorageInfoRequest(), async: false}, {req: crud.MakeStatsRequest(), async: false}, + {req: crud.MakeSchemaRequest(), async: false}, } for _, test := range tests { @@ -268,6 +270,7 @@ func TestRequestsCtx_default(t *testing.T) { {req: crud.MakeCountRequest(validSpace), expected: nil}, {req: crud.MakeStorageInfoRequest(), expected: nil}, {req: crud.MakeStatsRequest(), expected: nil}, + {req: crud.MakeSchemaRequest(), expected: nil}, } for _, test := range tests { @@ -306,6 +309,7 @@ func TestRequestsCtx_setter(t *testing.T) { {req: crud.MakeCountRequest(validSpace).Context(ctx), expected: ctx}, {req: crud.MakeStorageInfoRequest().Context(ctx), expected: ctx}, {req: crud.MakeStatsRequest().Context(ctx), expected: ctx}, + {req: crud.MakeSchemaRequest().Context(ctx), expected: ctx}, } for _, test := range tests { @@ -462,6 +466,12 @@ func TestRequestsDefaultValues(t *testing.T) { []interface{}{}), target: crud.MakeStatsRequest(), }, + { + name: "SchemaRequest", + ref: tarantool.NewCall17Request("crud.schema").Args( + []interface{}{nil, map[string]interface{}{}}), + target: crud.MakeSchemaRequest(), + }, } for _, tc := range testCases { @@ -624,6 +634,20 @@ func TestRequestsSetters(t *testing.T) { []interface{}{spaceName}), target: crud.MakeStatsRequest().Space(spaceName), }, + { + name: "SchemaRequest", + ref: tarantool.NewCall17Request("crud.schema").Args( + []interface{}{nil, schemaOpts}, + ), + target: crud.MakeSchemaRequest().Opts(schemaOpts), + }, + { + name: "SchemaRequestWithSpace", + ref: tarantool.NewCall17Request("crud.schema").Args( + []interface{}{spaceName, schemaOpts}, + ), + target: crud.MakeSchemaRequest().Space(spaceName).Opts(schemaOpts), + }, } for _, tc := range testCases { diff --git a/crud/schema.go b/crud/schema.go index 7f055e90a..6f3b94a97 100644 --- a/crud/schema.go +++ b/crud/schema.go @@ -14,11 +14,39 @@ func msgpackIsMap(code byte) bool { return code == msgpcode.Map16 || code == msgpcode.Map32 || msgpcode.IsFixedMap(code) } +// SchemaOpts describes options for `crud.schema` method. +type SchemaOpts struct { + // Timeout is a `vshard.call` timeout and vshard + // master discovery timeout (in seconds). + Timeout OptFloat64 + // VshardRouter is cartridge vshard group name or + // vshard router instance. + VshardRouter OptString + // Cached defines whether router should reload storage schema on call. + Cached OptBool +} + +// EncodeMsgpack provides custom msgpack encoder. +func (opts SchemaOpts) EncodeMsgpack(enc *msgpack.Encoder) error { + const optsCnt = 3 + + names := [optsCnt]string{timeoutOptName, vshardRouterOptName, + cachedOptName} + values := [optsCnt]interface{}{} + exists := [optsCnt]bool{} + values[0], exists[0] = opts.Timeout.Get() + values[1], exists[1] = opts.VshardRouter.Get() + values[2], exists[2] = opts.Cached.Get() + + return encodeOptions(enc, names[:], values[:], exists[:]) +} + // SchemaRequest helps you to create request object to call `crud.schema` // for execution by a Connection. type SchemaRequest struct { baseRequest space OptString + opts SchemaOpts } // MakeSchemaRequest returns a new empty SchemaRequest. @@ -35,12 +63,19 @@ func (req SchemaRequest) Space(space string) SchemaRequest { return req } +// Opts sets the options for the SchemaRequest request. +// Note: default value is nil. +func (req SchemaRequest) Opts(opts SchemaOpts) SchemaRequest { + req.opts = opts + return req +} + // Body fills an encoder with the call request body. func (req SchemaRequest) Body(res tarantool.SchemaResolver, enc *msgpack.Encoder) error { if value, ok := req.space.Get(); ok { - req.impl = req.impl.Args([]interface{}{value}) + req.impl = req.impl.Args([]interface{}{value, req.opts}) } else { - req.impl = req.impl.Args([]interface{}{}) + req.impl = req.impl.Args([]interface{}{nil, req.opts}) } return req.impl.Body(res, enc) diff --git a/crud/tarantool_test.go b/crud/tarantool_test.go index 399b0d48f..529f0201a 100644 --- a/crud/tarantool_test.go +++ b/crud/tarantool_test.go @@ -87,6 +87,11 @@ var opObjManyOpts = crud.OperationObjectManyOpts{ Timeout: crud.MakeOptFloat64(timeout), } +var schemaOpts = crud.SchemaOpts{ + Timeout: crud.MakeOptFloat64(timeout), + Cached: crud.MakeOptBool(false), +} + var conditions = []crud.Condition{ { Operator: crud.Lt, @@ -216,6 +221,11 @@ var testProcessDataCases = []struct { 1, crud.MakeStorageInfoRequest().Opts(baseOpts), }, + { + "Schema", + 1, + crud.MakeSchemaRequest().Opts(schemaOpts), + }, } var testResultWithErrCases = []struct {