Skip to content

Commit 671a8f8

Browse files
committed
api: add CRUD module support
This patch provides crud [1] methods as request objects to support CRUD API. The following methods are supported: * `insert` * `insert_object` * `insert_many` * `insert_object_many` * `get` * `update` * `delete` * `replace` * `replace_object` * `replace_many` * `replace_object_many` * `upsert` * `upsert_object` * `upsert_many` * `upsert_object_many` * `select` * `min` * `max` * `truncate` * `len` * `storage_info` * `count` * `stats` * `unflatten_rows` 1. https://github.com/tarantool/crud Closes #108
1 parent a22527a commit 671a8f8

36 files changed

+2999
-64
lines changed

.github/workflows/testing.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@ jobs:
101101
make test
102102
make testrace
103103
104+
- name: Run CRUD tests with options v1
105+
run: |
106+
make bench-deps test-crud-bench
107+
108+
- name: Run CRUD tests with options v2
109+
run: |
110+
make bench-deps test-crud-bench TAGS="go_tarantool_crud_opts_v2"
111+
104112
- name: Run regression tests with call_17
105113
run: |
106114
make test TAGS="go_tarantool_call_17"

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
1212

1313
- Support pagination (#246)
1414
- A Makefile target to test with race detector (#218)
15+
- Support CRUD API (#108)
1516

1617
### Changed
1718

Makefile

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ endif
2121

2222
.PHONY: clean
2323
clean:
24-
( cd ./queue; rm -rf .rocks )
24+
( rm -rf queue/.rocks crud/.rocks )
2525
rm -f $(COVERAGE_FILE)
2626

2727
.PHONY: deps
2828
deps: clean
2929
( cd ./queue/testdata; $(TTCTL) rocks install queue 1.2.1 )
30+
( cd ./crud; $(TTCTL) rocks install crud 0.14.1 )
3031

3132
.PHONY: datetime-timezones
3233
datetime-timezones:
@@ -99,6 +100,19 @@ test-settings:
99100
go clean -testcache
100101
go test -tags "$(TAGS)" ./settings/ -v -p 1
101102

103+
.PHONY: test-crud
104+
test-crud:
105+
@echo "Running tests in crud package"
106+
cd ./crud/ && tarantool -e "require('crud')"
107+
go clean -testcache
108+
go test -tags "$(TAGS)" ./crud/ -v -p 1
109+
110+
.PHONY: test-crud-bench
111+
test-crud-bench:
112+
@echo "Running bench tests in crud package"
113+
cd ./crud/ && tarantool -e "require('crud')"
114+
cd ./crud/ && go test -v -tags "$(TAGS)" -bench=. -run=asdasdasd . -benchmem -memprofile=mem.out
115+
102116
.PHONY: test-main
103117
test-main:
104118
@echo "Running tests in main package"

crud/common.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package crud
2+
3+
import (
4+
"context"
5+
6+
"github.com/tarantool/go-tarantool"
7+
)
8+
9+
type Tuple = []interface{}
10+
type Object = map[string]interface{}
11+
12+
type baseRequest struct {
13+
impl *tarantool.CallRequest
14+
}
15+
16+
func (req *baseRequest) initImpl(methodName string) {
17+
req.impl = tarantool.NewCall17Request(methodName)
18+
}
19+
20+
// Code returns IPROTO code for CRUD request.
21+
func (req *baseRequest) Code() int32 {
22+
return req.impl.Code()
23+
}
24+
25+
// Ctx returns a context of CRUD request.
26+
func (req *baseRequest) Ctx() context.Context {
27+
return req.impl.Ctx()
28+
}
29+
30+
// Async returns is CRUD request expects a response.
31+
func (req *baseRequest) Async() bool {
32+
return req.impl.Async()
33+
}
34+
35+
type spaceRequest struct {
36+
baseRequest
37+
space string
38+
}
39+
40+
func (req *spaceRequest) setSpace(space string) {
41+
req.space = space
42+
}

crud/conditions.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package crud
2+
3+
type Operator string
4+
5+
const (
6+
EQ Operator = "="
7+
LT Operator = "<"
8+
LE Operator = "<="
9+
GT Operator = ">"
10+
GE Operator = ">="
11+
)
12+
13+
type Condition struct {
14+
// Instruct msgpack to pack this struct as array, so no custom packer
15+
// is needed.
16+
_msgpack struct{} `msgpack:",asArray"` //nolint: structcheck,unused
17+
Operator Operator
18+
KeyName string
19+
KeyValue interface{}
20+
}

crud/count.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package crud
2+
3+
import (
4+
"context"
5+
6+
"github.com/tarantool/go-tarantool"
7+
)
8+
9+
type CountOpts struct {
10+
Timeout OptUint
11+
VshardRouter OptString
12+
Mode OptString
13+
PreferReplica OptBool
14+
Balance OptBool
15+
YieldEvery OptUint
16+
BucketId OptUint
17+
ForceMapCall OptBool
18+
Fullscan OptBool
19+
}
20+
21+
func (opts CountOpts) EncodeMsgpack(enc *encoder) error {
22+
const optsCnt = 9
23+
24+
options := []option{opts.Timeout, opts.VshardRouter,
25+
opts.Mode, opts.PreferReplica, opts.Balance,
26+
opts.YieldEvery, opts.BucketId, opts.ForceMapCall,
27+
opts.Fullscan}
28+
names := []string{timeoutOptName, vshardRouterOptName,
29+
modeOptName, preferReplicaOptName, balanceOptName,
30+
yieldEveryOptName, bucketIdOptName, forceMapCallOptName,
31+
fullscanOptName}
32+
values := make([]interface{}, optsCnt)
33+
34+
return encodeOptions(enc, options, names, values)
35+
}
36+
37+
// CountRequest helps you to create request object to call `crud.count`
38+
// for execution by a Connection.
39+
type CountRequest struct {
40+
spaceRequest
41+
conditions []Condition
42+
opts CountOpts
43+
}
44+
45+
// NewCountRequest returns a new empty CountRequest.
46+
func NewCountRequest(space string) *CountRequest {
47+
req := new(CountRequest)
48+
req.initImpl("crud.count")
49+
req.setSpace(space)
50+
req.conditions = []Condition{}
51+
req.opts = CountOpts{}
52+
return req
53+
}
54+
55+
// Conditions sets the conditions for the CountRequest request.
56+
// Note: default value is nil.
57+
func (req *CountRequest) Conditions(conditions []Condition) *CountRequest {
58+
req.conditions = conditions
59+
return req
60+
}
61+
62+
// Opts sets the options for the CountRequest request.
63+
// Note: default value is nil.
64+
func (req *CountRequest) Opts(opts CountOpts) *CountRequest {
65+
req.opts = opts
66+
return req
67+
}
68+
69+
// Body fills an encoder with the call request body.
70+
func (req *CountRequest) Body(res tarantool.SchemaResolver, enc *encoder) error {
71+
req.impl.Args([]interface{}{req.space, req.conditions, req.opts})
72+
return req.impl.Body(res, enc)
73+
}
74+
75+
// Context sets a passed context to CRUD request.
76+
func (req *CountRequest) Context(ctx context.Context) *CountRequest {
77+
req.impl = req.impl.Context(ctx)
78+
79+
return req
80+
}

crud/delete.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package crud
2+
3+
import (
4+
"context"
5+
6+
"github.com/tarantool/go-tarantool"
7+
)
8+
9+
type DeleteOpts = SimpleOperationOpts
10+
11+
// DeleteRequest helps you to create request object to call `crud.delete`
12+
// for execution by a Connection.
13+
type DeleteRequest struct {
14+
spaceRequest
15+
key Tuple
16+
opts DeleteOpts
17+
}
18+
19+
// NewDeleteRequest returns a new empty DeleteRequest.
20+
func NewDeleteRequest(space string) *DeleteRequest {
21+
req := new(DeleteRequest)
22+
req.initImpl("crud.delete")
23+
req.setSpace(space)
24+
req.key = Tuple{}
25+
req.opts = DeleteOpts{}
26+
return req
27+
}
28+
29+
// Key sets the key for the DeleteRequest request.
30+
// Note: default value is nil.
31+
func (req *DeleteRequest) Key(key Tuple) *DeleteRequest {
32+
req.key = key
33+
return req
34+
}
35+
36+
// Opts sets the options for the DeleteRequest request.
37+
// Note: default value is nil.
38+
func (req *DeleteRequest) Opts(opts DeleteOpts) *DeleteRequest {
39+
req.opts = opts
40+
return req
41+
}
42+
43+
// Body fills an encoder with the call request body.
44+
func (req *DeleteRequest) Body(res tarantool.SchemaResolver, enc *encoder) error {
45+
req.impl.Args([]interface{}{req.space, req.key, req.opts})
46+
return req.impl.Body(res, enc)
47+
}
48+
49+
// Context sets a passed context to CRUD request.
50+
func (req *DeleteRequest) Context(ctx context.Context) *DeleteRequest {
51+
req.impl = req.impl.Context(ctx)
52+
53+
return req
54+
}

crud/get.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package crud
2+
3+
import (
4+
"context"
5+
6+
"github.com/tarantool/go-tarantool"
7+
)
8+
9+
type GetOpts struct {
10+
Timeout OptUint
11+
VshardRouter OptString
12+
Fields OptTuple
13+
BucketId OptUint
14+
Mode OptString
15+
PreferReplica OptBool
16+
Balance OptBool
17+
}
18+
19+
func (opts GetOpts) EncodeMsgpack(enc *encoder) error {
20+
const optsCnt = 7
21+
22+
options := []option{opts.Timeout, opts.VshardRouter,
23+
opts.Fields, opts.BucketId, opts.Mode,
24+
opts.PreferReplica, opts.Balance}
25+
names := []string{timeoutOptName, vshardRouterOptName,
26+
fieldsOptName, bucketIdOptName, modeOptName,
27+
preferReplicaOptName, balanceOptName}
28+
values := make([]interface{}, optsCnt)
29+
30+
return encodeOptions(enc, options, names, values)
31+
}
32+
33+
// GetRequest helps you to create request object to call `crud.get`
34+
// for execution by a Connection.
35+
type GetRequest struct {
36+
spaceRequest
37+
key Tuple
38+
opts GetOpts
39+
}
40+
41+
// NewGetRequest returns a new empty GetRequest.
42+
func NewGetRequest(space string) *GetRequest {
43+
req := new(GetRequest)
44+
req.initImpl("crud.get")
45+
req.setSpace(space)
46+
req.key = Tuple{}
47+
req.opts = GetOpts{}
48+
return req
49+
}
50+
51+
// Key sets the key for the GetRequest request.
52+
// Note: default value is nil.
53+
func (req *GetRequest) Key(key Tuple) *GetRequest {
54+
req.key = key
55+
return req
56+
}
57+
58+
// Opts sets the options for the GetRequest request.
59+
// Note: default value is nil.
60+
func (req *GetRequest) Opts(opts GetOpts) *GetRequest {
61+
req.opts = opts
62+
return req
63+
}
64+
65+
// Body fills an encoder with the call request body.
66+
func (req *GetRequest) Body(res tarantool.SchemaResolver, enc *encoder) error {
67+
req.impl.Args([]interface{}{req.space, req.key, req.opts})
68+
return req.impl.Body(res, enc)
69+
}
70+
71+
// Context sets a passed context to CRUD request.
72+
func (req *GetRequest) Context(ctx context.Context) *GetRequest {
73+
req.impl = req.impl.Context(ctx)
74+
75+
return req
76+
}

0 commit comments

Comments
 (0)