Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,32 @@ module github.com/tarantool/go-storage
go 1.24.0

require (
github.com/stretchr/testify v1.11.1
github.com/tarantool/go-tarantool/v2 v2.4.0
go.etcd.io/etcd/client/v3 v3.6.4
go.etcd.io/etcd/client/v3 v3.6.5
)

require (
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.6.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/tarantool/go-iproto v1.1.0 // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
go.etcd.io/etcd/api/v3 v3.6.4 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect
go.etcd.io/etcd/api/v3 v3.6.5 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.6.5 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/net v0.44.0 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/text v0.29.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250922171735-9219d122eba9 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 // indirect
google.golang.org/grpc v1.75.1 // indirect
google.golang.org/protobuf v1.36.9 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
32 changes: 20 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnV
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tarantool/go-iproto v1.1.0 h1:HULVOIHsiehI+FnHfM7wMDntuzUddO09DKqu2WnFQ5A=
github.com/tarantool/go-iproto v1.1.0/go.mod h1:LNCtdyZxojUed8SbOiYHoc3v9NvaZTB7p96hUySMlIo=
github.com/tarantool/go-tarantool/v2 v2.4.0 h1:cfGngxdknpVVbd/vF2LvaoWsKjsLV9i3xC859XgsJlI=
Expand All @@ -34,12 +40,12 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/etcd/api/v3 v3.6.4 h1:7F6N7toCKcV72QmoUKa23yYLiiljMrT4xCeBL9BmXdo=
go.etcd.io/etcd/api/v3 v3.6.4/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk=
go.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0=
go.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI=
go.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A=
go.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo=
go.etcd.io/etcd/api/v3 v3.6.5 h1:pMMc42276sgR1j1raO/Qv3QI9Af/AuyQUW6CBAWuntA=
go.etcd.io/etcd/api/v3 v3.6.5/go.mod h1:ob0/oWA/UQQlT1BmaEkWQzI0sJ1M0Et0mMpaABxguOQ=
go.etcd.io/etcd/client/pkg/v3 v3.6.5 h1:Duz9fAzIZFhYWgRjp/FgNq2gO1jId9Yae/rLn3RrBP8=
go.etcd.io/etcd/client/pkg/v3 v3.6.5/go.mod h1:8Wx3eGRPiy0qOFMZT/hfvdos+DjEaPxdIDiCDUv/FQk=
go.etcd.io/etcd/client/v3 v3.6.5 h1:yRwZNFBx/35VKHTcLDeO7XVLbCBFbPi+XV4OC3QJf2U=
go.etcd.io/etcd/client/v3 v3.6.5/go.mod h1:ZqwG/7TAFZ0BJ0jXRPoJjKQJtbFo/9NIY8uoFFKcCyo=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
Expand Down Expand Up @@ -91,14 +97,16 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 h1:d8Nakh1G+ur7+P3GcMjpRDEkoLUcLW2iU92XVqR+XMQ=
google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090/go.mod h1:U8EXRNSd8sUYyDfs/It7KVWodQr+Hf9xtxyxWudSwEw=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 h1:/OQuEa4YWtDt7uQWHd3q3sUMb+QOLQUg1xa8CEsRv5w=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og=
google.golang.org/genproto/googleapis/api v0.0.0-20250922171735-9219d122eba9 h1:jm6v6kMRpTYKxBRrDkYAitNJegUeO1Mf3Kt80obv0gg=
google.golang.org/genproto/googleapis/api v0.0.0-20250922171735-9219d122eba9/go.mod h1:LmwNphe5Afor5V3R5BppOULHOnt2mCIf+NxMd4XiygE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9 h1:V1jCN2HBa8sySkR5vLcCSqJSTMv093Rw9EJefhQGP7M=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250922171735-9219d122eba9/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ=
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
34 changes: 34 additions & 0 deletions predicate/op_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package predicate_test

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/tarantool/go-storage/predicate"
)

func TestOpString(t *testing.T) {
t.Parallel()

tests := []struct {
name string
op predicate.Op
expected string
}{
{"OpEqual", predicate.OpEqual, "Equal"},
{"OpNotEqual", predicate.OpNotEqual, "NotEqual"},
{"OpGreater", predicate.OpGreater, "Greater"},
{"OpLess", predicate.OpLess, "Less"},
{"UnknownOp", predicate.Op(99), "Unknown"},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

result := tt.op.String()
assert.Equal(t, tt.expected, result)
})
}
}
89 changes: 89 additions & 0 deletions predicate/predicate.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,92 @@ type Predicate interface {
// Value returns the comparison value for the predicate.
Value() any
}

// predicate is the concrete implementation of the Predicate interface.
// It represents a condition used for conditional operations in transactions.
type predicate struct {
key []byte
op Op
target Target
value interface{}
}

// Key returns the key that this predicate applies to.
func (p predicate) Key() []byte {
return p.key
}

// Operation returns the comparison operation (Equal, NotEqual, Greater, Less).
func (p predicate) Operation() Op {
return p.op
}

// Target returns what aspect of the record to compare (e.g. Version or Value).
func (p predicate) Target() Target {
return p.target
}

// Value returns the comparison value for the predicate.
func (p predicate) Value() interface{} {
return p.value
}

// ValueNotEqual creates a predicate that checks if a key's value is not equal to the specified value.
func ValueNotEqual(key []byte, value interface{}) Predicate {
return &predicate{
key: key,
op: OpNotEqual,
target: TargetValue,
value: value,
}
}

// ValueEqual creates a predicate that checks if a key's value equals the specified value.
func ValueEqual(key []byte, value interface{}) Predicate {
return &predicate{
key: key,
op: OpEqual,
target: TargetValue,
value: value,
}
}

// VersionEqual creates a predicate that checks if a key's version equals the specified version.
func VersionEqual(key []byte, version int64) Predicate {
return &predicate{
key: key,
op: OpEqual,
target: TargetVersion,
value: version,
}
}

// VersionNotEqual creates a predicate that checks if a key's version is not equal to the specified version.
func VersionNotEqual(key []byte, version int64) Predicate {
return &predicate{
key: key,
op: OpNotEqual,
target: TargetVersion,
value: version,
}
}

// VersionGreater creates a predicate that checks if a key's version is greater than the specified version.
func VersionGreater(key []byte, version int64) Predicate {
return &predicate{
key: key,
op: OpGreater,
target: TargetVersion,
value: version,
}
}

// VersionLess creates a predicate that checks if a key's version is less than the specified version.
func VersionLess(key []byte, version int64) Predicate {
return &predicate{
key: key,
op: OpLess,
target: TargetVersion,
value: version,
}
}
87 changes: 87 additions & 0 deletions predicate/predicate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package predicate_test

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/tarantool/go-storage/predicate"
)

func TestValueNotEqual(t *testing.T) {
t.Parallel()

key := []byte("test-key")
value := "test-value"
p := predicate.ValueNotEqual(key, value)

assert.Equal(t, key, p.Key())
assert.Equal(t, predicate.OpNotEqual, p.Operation())
assert.Equal(t, predicate.TargetValue, p.Target())
assert.Equal(t, value, p.Value())
}

func TestValueEqual(t *testing.T) {
t.Parallel()

key := []byte("test-key")
value := 42
p := predicate.ValueEqual(key, value)

assert.Equal(t, key, p.Key())
assert.Equal(t, predicate.OpEqual, p.Operation())
assert.Equal(t, predicate.TargetValue, p.Target())
assert.Equal(t, value, p.Value())
}

func TestVersionEqual(t *testing.T) {
t.Parallel()

key := []byte("test-key")
version := int64(123)
p := predicate.VersionEqual(key, version)

assert.Equal(t, key, p.Key())
assert.Equal(t, predicate.OpEqual, p.Operation())
assert.Equal(t, predicate.TargetVersion, p.Target())
assert.Equal(t, version, p.Value())
}

func TestVersionNotEqual(t *testing.T) {
t.Parallel()

key := []byte("test-key")
version := int64(456)
p := predicate.VersionNotEqual(key, version)

assert.Equal(t, key, p.Key())
assert.Equal(t, predicate.OpNotEqual, p.Operation())
assert.Equal(t, predicate.TargetVersion, p.Target())
assert.Equal(t, version, p.Value())
}

func TestVersionGreater(t *testing.T) {
t.Parallel()

key := []byte("test-key")
version := int64(789)
p := predicate.VersionGreater(key, version)

assert.Equal(t, key, p.Key())
assert.Equal(t, predicate.OpGreater, p.Operation())
assert.Equal(t, predicate.TargetVersion, p.Target())
assert.Equal(t, version, p.Value())
}

func TestVersionLess(t *testing.T) {
t.Parallel()

key := []byte("test-key")
version := int64(999)
p := predicate.VersionLess(key, version)

assert.Equal(t, key, p.Key())
assert.Equal(t, predicate.OpLess, p.Operation())
assert.Equal(t, predicate.TargetVersion, p.Target())
assert.Equal(t, version, p.Value())
}
32 changes: 32 additions & 0 deletions predicate/target_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package predicate_test

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/tarantool/go-storage/predicate"
)

func TestTargetString(t *testing.T) {
t.Parallel()

tests := []struct {
name string
target predicate.Target
expected string
}{
{"TargetVersion", predicate.TargetVersion, "Version"},
{"TargetValue", predicate.TargetValue, "Value"},
{"UnknownTarget", predicate.Target(99), "Unknown"},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

result := tt.target.String()
assert.Equal(t, tt.expected, result)
})
}
}
Loading