forked from TrueCloudLab/frostfs-sdk-go
Compare commits
10 commits
3e455777fd
...
3063b525d5
Author | SHA1 | Date | |
---|---|---|---|
3063b525d5 | |||
99d5bf913b | |||
e50838a33d | |||
97cf56ba41 | |||
07625e3bd1 | |||
da2f0e7532 | |||
114b4c14b5 | |||
e580ee991d | |||
6821fe6fb2 | |||
6009d089fc |
26 changed files with 187 additions and 70 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -23,7 +23,7 @@ coverage.txt
|
||||||
coverage.html
|
coverage.html
|
||||||
|
|
||||||
# antlr tool jar
|
# antlr tool jar
|
||||||
antlr-*.jar
|
antlr*.jar
|
||||||
|
|
||||||
# tempfiles
|
# tempfiles
|
||||||
.cache
|
.cache
|
||||||
|
|
5
Makefile
5
Makefile
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/make -f
|
#!/usr/bin/make -f
|
||||||
|
|
||||||
ANTLR_VERSION="4.13.0"
|
ANTLR_VERSION=4.13.1
|
||||||
TMP_DIR := .cache
|
TMP_DIR := .cache
|
||||||
LINT_VERSION ?= 1.60.1
|
LINT_VERSION ?= 1.60.1
|
||||||
TRUECLOUDLAB_LINT_VERSION ?= 0.0.6
|
TRUECLOUDLAB_LINT_VERSION ?= 0.0.6
|
||||||
|
@ -53,7 +53,8 @@ format:
|
||||||
|
|
||||||
policy:
|
policy:
|
||||||
@wget -q https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar -O antlr4-tool.jar
|
@wget -q https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar -O antlr4-tool.jar
|
||||||
@java -Xmx500M -cp "`pwd`/antlr4-tool.jar" "org.antlr.v4.Tool" -o `pwd`/netmap/parser/ -Dlanguage=Go -no-listener -visitor `pwd`/netmap/parser/Query.g4 `pwd`/netmap/parser/QueryLexer.g4
|
@java -Xmx500M -cp antlr4-tool.jar org.antlr.v4.Tool -Dlanguage=Go \
|
||||||
|
-no-listener -visitor netmap/parser/Query.g4 netmap/parser/QueryLexer.g4
|
||||||
|
|
||||||
# Run `make %` in truecloudlab/frostfs-sdk-go container(Golang+Java)
|
# Run `make %` in truecloudlab/frostfs-sdk-go container(Golang+Java)
|
||||||
docker/%:
|
docker/%:
|
||||||
|
|
|
@ -65,7 +65,7 @@ func (c *Client) APEManagerListChains(ctx context.Context, prm PrmAPEManagerList
|
||||||
var res ResAPEManagerListChains
|
var res ResAPEManagerListChains
|
||||||
res.st, err = c.processResponse(resp)
|
res.st, err = c.processResponse(resp)
|
||||||
if err != nil || !apistatus.IsSuccessful(res.st) {
|
if err != nil || !apistatus.IsSuccessful(res.st) {
|
||||||
return nil, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ch := range resp.GetBody().GetChains() {
|
for _, ch := range resp.GetBody().GetChains() {
|
||||||
|
|
|
@ -11,6 +11,8 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client represents virtual connection to the FrostFS network to communicate
|
// Client represents virtual connection to the FrostFS network to communicate
|
||||||
|
@ -98,13 +100,21 @@ func (c *Client) Dial(ctx context.Context, prm PrmDial) error {
|
||||||
|
|
||||||
c.setFrostFSAPIServer((*coreServer)(&c.c))
|
c.setFrostFSAPIServer((*coreServer)(&c.c))
|
||||||
|
|
||||||
// TODO: (neofs-api-go#382) perform generic dial stage of the client.Client
|
|
||||||
_, err := rpc.Balance(&c.c, new(v2accounting.BalanceRequest),
|
_, err := rpc.Balance(&c.c, new(v2accounting.BalanceRequest),
|
||||||
client.WithContext(ctx),
|
client.WithContext(ctx),
|
||||||
)
|
)
|
||||||
// return context errors since they signal about dial problem
|
if err != nil {
|
||||||
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
|
// return context errors since they signal about dial problem
|
||||||
return err
|
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
st, ok := status.FromError(err)
|
||||||
|
if ok && st.Code() == codes.Canceled {
|
||||||
|
return context.Canceled
|
||||||
|
}
|
||||||
|
if ok && st.Code() == codes.DeadlineExceeded {
|
||||||
|
return context.DeadlineExceeded
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -240,7 +240,7 @@ func (c *Client) NetMapSnapshot(ctx context.Context, _ PrmNetMapSnapshot) (*ResN
|
||||||
var res ResNetMapSnapshot
|
var res ResNetMapSnapshot
|
||||||
res.st, err = c.processResponse(resp)
|
res.st, err = c.processResponse(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !apistatus.IsSuccessful(res.st) {
|
if !apistatus.IsSuccessful(res.st) {
|
||||||
|
|
|
@ -149,7 +149,7 @@ func (c *Client) ObjectDelete(ctx context.Context, prm PrmObjectDelete) (*ResObj
|
||||||
var res ResObjectDelete
|
var res ResObjectDelete
|
||||||
res.st, err = c.processResponse(resp)
|
res.st, err = c.processResponse(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !apistatus.IsSuccessful(res.st) {
|
if !apistatus.IsSuccessful(res.st) {
|
||||||
|
|
|
@ -493,7 +493,7 @@ func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectH
|
||||||
var res ResObjectHead
|
var res ResObjectHead
|
||||||
res.st, err = c.processResponse(resp)
|
res.st, err = c.processResponse(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !apistatus.IsSuccessful(res.st) {
|
if !apistatus.IsSuccessful(res.st) {
|
||||||
|
|
|
@ -190,7 +190,7 @@ func (c *Client) ObjectHash(ctx context.Context, prm PrmObjectHash) (*ResObjectH
|
||||||
var res ResObjectHash
|
var res ResObjectHash
|
||||||
res.st, err = c.processResponse(resp)
|
res.st, err = c.processResponse(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return &res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !apistatus.IsSuccessful(res.st) {
|
if !apistatus.IsSuccessful(res.st) {
|
||||||
|
|
|
@ -247,7 +247,7 @@ func (x *objectPatcher) Close(_ context.Context) (*ResObjectPatch, error) {
|
||||||
|
|
||||||
x.res.st, x.err = x.client.processResponse(&x.respV2)
|
x.res.st, x.err = x.client.processResponse(&x.respV2)
|
||||||
if x.err != nil {
|
if x.err != nil {
|
||||||
return nil, x.err
|
return &x.res, x.err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !apistatus.IsSuccessful(x.res.st) {
|
if !apistatus.IsSuccessful(x.res.st) {
|
||||||
|
|
|
@ -157,7 +157,7 @@ func (x *objectWriterRaw) Close(_ context.Context) (*ResObjectPut, error) {
|
||||||
|
|
||||||
x.res.st, x.err = x.client.processResponse(&x.respV2)
|
x.res.st, x.err = x.client.processResponse(&x.respV2)
|
||||||
if x.err != nil {
|
if x.err != nil {
|
||||||
return nil, x.err
|
return &x.res, x.err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !apistatus.IsSuccessful(x.res.st) {
|
if !apistatus.IsSuccessful(x.res.st) {
|
||||||
|
|
|
@ -167,7 +167,7 @@ func (c *Client) ObjectPutSingle(ctx context.Context, prm PrmObjectPutSingle) (*
|
||||||
var res ResObjectPutSingle
|
var res ResObjectPutSingle
|
||||||
res.st, err = c.processResponse(resp)
|
res.st, err = c.processResponse(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return &res, err
|
||||||
}
|
}
|
||||||
res.epoch = resp.GetMetaHeader().GetEpoch()
|
res.epoch = resp.GetMetaHeader().GetEpoch()
|
||||||
|
|
||||||
|
|
|
@ -356,8 +356,7 @@ func (x Container) IterateUserAttributes(f func(key, val string)) {
|
||||||
attrs := x.v2.GetAttributes()
|
attrs := x.v2.GetAttributes()
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
key := attr.GetKey()
|
key := attr.GetKey()
|
||||||
if !strings.HasPrefix(key, container.SysAttributePrefix) &&
|
if !strings.HasPrefix(key, container.SysAttributePrefix) {
|
||||||
!strings.HasPrefix(key, container.SysAttributePrefixNeoFS) {
|
|
||||||
f(key, attr.GetValue())
|
f(key, attr.GetValue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -417,8 +416,7 @@ func DisableHomomorphicHashing(cnr *Container) {
|
||||||
//
|
//
|
||||||
// Zero Container has enabled hashing.
|
// Zero Container has enabled hashing.
|
||||||
func IsHomomorphicHashingDisabled(cnr Container) bool {
|
func IsHomomorphicHashingDisabled(cnr Container) bool {
|
||||||
return cnr.Attribute(container.SysAttributeHomomorphicHashing) == attributeHomoHashEnabled ||
|
return cnr.Attribute(container.SysAttributeHomomorphicHashing) == attributeHomoHashEnabled
|
||||||
cnr.Attribute(container.SysAttributeHomomorphicHashingNeoFS) == attributeHomoHashEnabled
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Domain represents information about container domain registered in the NNS
|
// Domain represents information about container domain registered in the NNS
|
||||||
|
@ -467,9 +465,6 @@ func ReadDomain(cnr Container) (res Domain) {
|
||||||
if name := cnr.Attribute(container.SysAttributeName); name != "" {
|
if name := cnr.Attribute(container.SysAttributeName); name != "" {
|
||||||
res.SetName(name)
|
res.SetName(name)
|
||||||
res.SetZone(cnr.Attribute(container.SysAttributeZone))
|
res.SetZone(cnr.Attribute(container.SysAttributeZone))
|
||||||
} else if name = cnr.Attribute(container.SysAttributeNameNeoFS); name != "" {
|
|
||||||
res.SetName(name)
|
|
||||||
res.SetZone(cnr.Attribute(container.SysAttributeZoneNeoFS))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -150,7 +150,7 @@ func assertContainsAttribute(t *testing.T, m v2container.Container, key, val str
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContainer_Attribute(t *testing.T) {
|
func TestContainer_Attribute(t *testing.T) {
|
||||||
const attrKey1, attrKey2 = v2container.SysAttributePrefix + "key1", v2container.SysAttributePrefixNeoFS + "key2"
|
const attrKey1, attrKey2 = v2container.SysAttributePrefix + "key1", v2container.SysAttributePrefix + "key2"
|
||||||
const attrVal1, attrVal2 = "val1", "val2"
|
const attrVal1, attrVal2 = "val1", "val2"
|
||||||
|
|
||||||
val := containertest.Container()
|
val := containertest.Container()
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -7,7 +7,7 @@ require (
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240621131249-49e5270f673e
|
git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240621131249-49e5270f673e
|
||||||
git.frostfs.info/TrueCloudLab/hrw v1.2.1
|
git.frostfs.info/TrueCloudLab/hrw v1.2.1
|
||||||
git.frostfs.info/TrueCloudLab/tzhash v1.8.0
|
git.frostfs.info/TrueCloudLab/tzhash v1.8.0
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.0
|
github.com/antlr4-go/antlr/v4 v4.13.1
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||||
github.com/klauspost/reedsolomon v1.12.1
|
github.com/klauspost/reedsolomon v1.12.1
|
||||||
|
@ -40,7 +40,7 @@ require (
|
||||||
go.etcd.io/bbolt v1.3.9 // indirect
|
go.etcd.io/bbolt v1.3.9 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/crypto v0.24.0 // indirect
|
golang.org/x/crypto v0.24.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
|
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
|
||||||
golang.org/x/net v0.26.0 // indirect
|
golang.org/x/net v0.26.0 // indirect
|
||||||
golang.org/x/sync v0.7.0 // indirect
|
golang.org/x/sync v0.7.0 // indirect
|
||||||
golang.org/x/sys v0.21.0 // indirect
|
golang.org/x/sys v0.21.0 // indirect
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -12,8 +12,8 @@ git.frostfs.info/TrueCloudLab/tzhash v1.8.0 h1:UFMnUIk0Zh17m8rjGHJMqku2hCgaXDqjq
|
||||||
git.frostfs.info/TrueCloudLab/tzhash v1.8.0/go.mod h1:dhY+oy274hV8wGvGL4MwwMpdL3GYvaX1a8GQZQHvlF8=
|
git.frostfs.info/TrueCloudLab/tzhash v1.8.0/go.mod h1:dhY+oy274hV8wGvGL4MwwMpdL3GYvaX1a8GQZQHvlF8=
|
||||||
github.com/VictoriaMetrics/easyproto v0.1.4 h1:r8cNvo8o6sR4QShBXQd1bKw/VVLSQma/V2KhTBPf+Sc=
|
github.com/VictoriaMetrics/easyproto v0.1.4 h1:r8cNvo8o6sR4QShBXQd1bKw/VVLSQma/V2KhTBPf+Sc=
|
||||||
github.com/VictoriaMetrics/easyproto v0.1.4/go.mod h1:QlGlzaJnDfFd8Lk6Ci/fuLxfTo3/GThPs2KH23mv710=
|
github.com/VictoriaMetrics/easyproto v0.1.4/go.mod h1:QlGlzaJnDfFd8Lk6Ci/fuLxfTo3/GThPs2KH23mv710=
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
|
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
|
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c=
|
github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c=
|
||||||
|
@ -124,8 +124,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
|
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
|
||||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
|
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
|
|
@ -19,10 +19,10 @@ repStmt:
|
||||||
cbfStmt: CBF BackupFactor = NUMBER1; // container backup factor
|
cbfStmt: CBF BackupFactor = NUMBER1; // container backup factor
|
||||||
|
|
||||||
selectStmt:
|
selectStmt:
|
||||||
SELECT Count = NUMBER1 // number of nodes to select without container backup factor *)
|
SELECT Count = NUMBER1 // number of nodes to select without container backup factor *)
|
||||||
(IN clause? Bucket = ident)? // bucket name
|
(IN clause? Bucket = filterKey)? // bucket name
|
||||||
FROM Filter = identWC // filter reference or whole netmap
|
FROM Filter = identWC // filter reference or whole netmap
|
||||||
(AS Name = ident)? // optional selector name
|
(AS Name = ident)? // optional selector name
|
||||||
;
|
;
|
||||||
|
|
||||||
clause: CLAUSE_SAME | CLAUSE_DISTINCT; // nodes from distinct buckets
|
clause: CLAUSE_SAME | CLAUSE_DISTINCT; // nodes from distinct buckets
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,5 @@
|
||||||
package parser
|
package parser
|
||||||
|
|
||||||
// ANTLR can be downloaded from https://www.antlr.org/download/antlr-4.13.0-complete.jar
|
// You can download ANTLR from https://www.antlr.org/download/antlr-4.13.1-complete.jar,
|
||||||
//go:generate java -Xmx500M -cp "./antlr-4.13.0-complete.jar:$CLASSPATH" org.antlr.v4.Tool -Dlanguage=Go -no-listener -visitor QueryLexer.g4 Query.g4
|
// then run generate or simply run the dedicated Makefile target like this `make policy`.
|
||||||
|
//go:generate java -Xmx500M -cp "./antlr-4.13.1-complete.jar:$CLASSPATH" org.antlr.v4.Tool -Dlanguage=Go -no-listener -visitor QueryLexer.g4 Query.g4
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Code generated from /repo/frostfs/sdk-go/netmap/parser/Query.g4 by ANTLR 4.13.0. DO NOT EDIT.
|
// Code generated from netmap/parser/Query.g4 by ANTLR 4.13.1. DO NOT EDIT.
|
||||||
|
|
||||||
package parser // Query
|
package parser // Query
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Code generated from /repo/frostfs/sdk-go/netmap/parser/QueryLexer.g4 by ANTLR 4.13.0. DO NOT EDIT.
|
// Code generated from netmap/parser/QueryLexer.g4 by ANTLR 4.13.1. DO NOT EDIT.
|
||||||
|
|
||||||
package parser
|
package parser
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Code generated from /repo/frostfs/sdk-go/netmap/parser/Query.g4 by ANTLR 4.13.0. DO NOT EDIT.
|
// Code generated from netmap/parser/Query.g4 by ANTLR 4.13.1. DO NOT EDIT.
|
||||||
|
|
||||||
package parser // Query
|
package parser // Query
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ func queryParserInit() {
|
||||||
85, 1, 0, 0, 0, 85, 7, 1, 0, 0, 0, 86, 87, 5, 10, 0, 0, 87, 88, 5, 22,
|
85, 1, 0, 0, 0, 85, 7, 1, 0, 0, 0, 86, 87, 5, 10, 0, 0, 87, 88, 5, 22,
|
||||||
0, 0, 88, 9, 1, 0, 0, 0, 89, 90, 5, 11, 0, 0, 90, 96, 5, 22, 0, 0, 91,
|
0, 0, 88, 9, 1, 0, 0, 0, 89, 90, 5, 11, 0, 0, 90, 96, 5, 22, 0, 0, 91,
|
||||||
93, 5, 8, 0, 0, 92, 94, 3, 12, 6, 0, 93, 92, 1, 0, 0, 0, 93, 94, 1, 0,
|
93, 5, 8, 0, 0, 92, 94, 3, 12, 6, 0, 93, 92, 1, 0, 0, 0, 93, 94, 1, 0,
|
||||||
0, 0, 94, 95, 1, 0, 0, 0, 95, 97, 3, 28, 14, 0, 96, 91, 1, 0, 0, 0, 96,
|
0, 0, 94, 95, 1, 0, 0, 0, 95, 97, 3, 20, 10, 0, 96, 91, 1, 0, 0, 0, 96,
|
||||||
97, 1, 0, 0, 0, 97, 98, 1, 0, 0, 0, 98, 99, 5, 12, 0, 0, 99, 102, 3, 30,
|
97, 1, 0, 0, 0, 97, 98, 1, 0, 0, 0, 98, 99, 5, 12, 0, 0, 99, 102, 3, 30,
|
||||||
15, 0, 100, 101, 5, 9, 0, 0, 101, 103, 3, 28, 14, 0, 102, 100, 1, 0, 0,
|
15, 0, 100, 101, 5, 9, 0, 0, 101, 103, 3, 28, 14, 0, 102, 100, 1, 0, 0,
|
||||||
0, 102, 103, 1, 0, 0, 0, 103, 11, 1, 0, 0, 0, 104, 105, 7, 0, 0, 0, 105,
|
0, 102, 103, 1, 0, 0, 0, 103, 11, 1, 0, 0, 0, 104, 105, 7, 0, 0, 0, 105,
|
||||||
|
@ -1364,7 +1364,7 @@ type ISelectStmtContext interface {
|
||||||
SetCount(antlr.Token)
|
SetCount(antlr.Token)
|
||||||
|
|
||||||
// GetBucket returns the Bucket rule contexts.
|
// GetBucket returns the Bucket rule contexts.
|
||||||
GetBucket() IIdentContext
|
GetBucket() IFilterKeyContext
|
||||||
|
|
||||||
// GetFilter returns the Filter rule contexts.
|
// GetFilter returns the Filter rule contexts.
|
||||||
GetFilter() IIdentWCContext
|
GetFilter() IIdentWCContext
|
||||||
|
@ -1373,7 +1373,7 @@ type ISelectStmtContext interface {
|
||||||
GetName() IIdentContext
|
GetName() IIdentContext
|
||||||
|
|
||||||
// SetBucket sets the Bucket rule contexts.
|
// SetBucket sets the Bucket rule contexts.
|
||||||
SetBucket(IIdentContext)
|
SetBucket(IFilterKeyContext)
|
||||||
|
|
||||||
// SetFilter sets the Filter rule contexts.
|
// SetFilter sets the Filter rule contexts.
|
||||||
SetFilter(IIdentWCContext)
|
SetFilter(IIdentWCContext)
|
||||||
|
@ -1388,8 +1388,8 @@ type ISelectStmtContext interface {
|
||||||
IdentWC() IIdentWCContext
|
IdentWC() IIdentWCContext
|
||||||
IN() antlr.TerminalNode
|
IN() antlr.TerminalNode
|
||||||
AS() antlr.TerminalNode
|
AS() antlr.TerminalNode
|
||||||
AllIdent() []IIdentContext
|
FilterKey() IFilterKeyContext
|
||||||
Ident(i int) IIdentContext
|
Ident() IIdentContext
|
||||||
Clause() IClauseContext
|
Clause() IClauseContext
|
||||||
|
|
||||||
// IsSelectStmtContext differentiates from other interfaces.
|
// IsSelectStmtContext differentiates from other interfaces.
|
||||||
|
@ -1400,7 +1400,7 @@ type SelectStmtContext struct {
|
||||||
antlr.BaseParserRuleContext
|
antlr.BaseParserRuleContext
|
||||||
parser antlr.Parser
|
parser antlr.Parser
|
||||||
Count antlr.Token
|
Count antlr.Token
|
||||||
Bucket IIdentContext
|
Bucket IFilterKeyContext
|
||||||
Filter IIdentWCContext
|
Filter IIdentWCContext
|
||||||
Name IIdentContext
|
Name IIdentContext
|
||||||
}
|
}
|
||||||
|
@ -1436,13 +1436,13 @@ func (s *SelectStmtContext) GetCount() antlr.Token { return s.Count }
|
||||||
|
|
||||||
func (s *SelectStmtContext) SetCount(v antlr.Token) { s.Count = v }
|
func (s *SelectStmtContext) SetCount(v antlr.Token) { s.Count = v }
|
||||||
|
|
||||||
func (s *SelectStmtContext) GetBucket() IIdentContext { return s.Bucket }
|
func (s *SelectStmtContext) GetBucket() IFilterKeyContext { return s.Bucket }
|
||||||
|
|
||||||
func (s *SelectStmtContext) GetFilter() IIdentWCContext { return s.Filter }
|
func (s *SelectStmtContext) GetFilter() IIdentWCContext { return s.Filter }
|
||||||
|
|
||||||
func (s *SelectStmtContext) GetName() IIdentContext { return s.Name }
|
func (s *SelectStmtContext) GetName() IIdentContext { return s.Name }
|
||||||
|
|
||||||
func (s *SelectStmtContext) SetBucket(v IIdentContext) { s.Bucket = v }
|
func (s *SelectStmtContext) SetBucket(v IFilterKeyContext) { s.Bucket = v }
|
||||||
|
|
||||||
func (s *SelectStmtContext) SetFilter(v IIdentWCContext) { s.Filter = v }
|
func (s *SelectStmtContext) SetFilter(v IIdentWCContext) { s.Filter = v }
|
||||||
|
|
||||||
|
@ -1484,37 +1484,28 @@ func (s *SelectStmtContext) AS() antlr.TerminalNode {
|
||||||
return s.GetToken(QueryAS, 0)
|
return s.GetToken(QueryAS, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SelectStmtContext) AllIdent() []IIdentContext {
|
func (s *SelectStmtContext) FilterKey() IFilterKeyContext {
|
||||||
children := s.GetChildren()
|
var t antlr.RuleContext
|
||||||
len := 0
|
for _, ctx := range s.GetChildren() {
|
||||||
for _, ctx := range children {
|
if _, ok := ctx.(IFilterKeyContext); ok {
|
||||||
if _, ok := ctx.(IIdentContext); ok {
|
t = ctx.(antlr.RuleContext)
|
||||||
len++
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tst := make([]IIdentContext, len)
|
if t == nil {
|
||||||
i := 0
|
return nil
|
||||||
for _, ctx := range children {
|
|
||||||
if t, ok := ctx.(IIdentContext); ok {
|
|
||||||
tst[i] = t.(IIdentContext)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tst
|
return t.(IFilterKeyContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SelectStmtContext) Ident(i int) IIdentContext {
|
func (s *SelectStmtContext) Ident() IIdentContext {
|
||||||
var t antlr.RuleContext
|
var t antlr.RuleContext
|
||||||
j := 0
|
|
||||||
for _, ctx := range s.GetChildren() {
|
for _, ctx := range s.GetChildren() {
|
||||||
if _, ok := ctx.(IIdentContext); ok {
|
if _, ok := ctx.(IIdentContext); ok {
|
||||||
if j == i {
|
t = ctx.(antlr.RuleContext)
|
||||||
t = ctx.(antlr.RuleContext)
|
break
|
||||||
break
|
|
||||||
}
|
|
||||||
j++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1617,7 +1608,7 @@ func (p *Query) SelectStmt() (localctx ISelectStmtContext) {
|
||||||
{
|
{
|
||||||
p.SetState(95)
|
p.SetState(95)
|
||||||
|
|
||||||
var _x = p.Ident()
|
var _x = p.FilterKey()
|
||||||
|
|
||||||
localctx.(*SelectStmtContext).Bucket = _x
|
localctx.(*SelectStmtContext).Bucket = _x
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Code generated from /repo/frostfs/sdk-go/netmap/parser/Query.g4 by ANTLR 4.13.0. DO NOT EDIT.
|
// Code generated from netmap/parser/Query.g4 by ANTLR 4.13.1. DO NOT EDIT.
|
||||||
|
|
||||||
package parser // Query
|
package parser // Query
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,13 @@ CBF 1
|
||||||
SELECT 1 FROM Color
|
SELECT 1 FROM Color
|
||||||
FILTER (Color EQ Red OR Color EQ Blue OR Color EQ Yellow) AND Color NE Green AS Color`,
|
FILTER (Color EQ Red OR Color EQ Blue OR Color EQ Yellow) AND Color NE Green AS Color`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "non-ascii attributes in SELECT IN",
|
||||||
|
input: `REP 1
|
||||||
|
CBF 1
|
||||||
|
SELECT 1 IN SAME 'Цвет' FROM Colorful
|
||||||
|
FILTER 'Цвет' EQ 'Красный' OR 'Цвет' EQ 'Синий' AS Colorful`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
@ -127,6 +134,11 @@ func TestDecodeSelectFilterExpr(t *testing.T) {
|
||||||
SELECT 1 FROM R
|
SELECT 1 FROM R
|
||||||
FILTER Color LIKE 'R' AS R
|
FILTER Color LIKE 'R' AS R
|
||||||
`,
|
`,
|
||||||
|
`
|
||||||
|
CBF 1
|
||||||
|
SELECT 1 IN SAME 'Цвет' FROM Colorful
|
||||||
|
FILTER 'Цвет' EQ 'Красный' OR 'Цвет' EQ 'Синий' AS Colorful
|
||||||
|
`,
|
||||||
} {
|
} {
|
||||||
_, err := DecodeSelectFilterString(s)
|
_, err := DecodeSelectFilterString(s)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
mrand "math/rand"
|
mrand "math/rand"
|
||||||
|
"reflect"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -13,6 +14,7 @@ import (
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||||
"git.frostfs.info/TrueCloudLab/hrw"
|
"git.frostfs.info/TrueCloudLab/hrw"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -542,6 +544,66 @@ func TestPlacementPolicy_ProcessSelectorsExceptForNodes(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPlacementPolicy_NonAsciiAttributes(t *testing.T) {
|
||||||
|
p := newPlacementPolicy(
|
||||||
|
1,
|
||||||
|
[]ReplicaDescriptor{
|
||||||
|
newReplica(2, "Nodes"),
|
||||||
|
newReplica(2, "Nodes"),
|
||||||
|
},
|
||||||
|
[]Selector{
|
||||||
|
newSelector("Nodes", "Цвет", 2, "Colorful", (*Selector).SelectSame),
|
||||||
|
},
|
||||||
|
[]Filter{
|
||||||
|
newFilter("Colorful", "", "", netmap.OR,
|
||||||
|
newFilter("", "Цвет", "Красный", netmap.EQ),
|
||||||
|
newFilter("", "Цвет", "Синий", netmap.EQ),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
p.SetUnique(true)
|
||||||
|
|
||||||
|
nodes := []NodeInfo{
|
||||||
|
nodeInfoFromAttributes("Цвет", "Красный", "Форма", "Треугольник"),
|
||||||
|
nodeInfoFromAttributes("Цвет", "Красный", "Форма", "Круг"),
|
||||||
|
nodeInfoFromAttributes("Цвет", "Синий", "Форма", "Треугольник"),
|
||||||
|
nodeInfoFromAttributes("Цвет", "Синий", "Форма", "Круг"),
|
||||||
|
nodeInfoFromAttributes("Свойство", "Мягкий", "Форма", "Треугольник"),
|
||||||
|
nodeInfoFromAttributes("Свойство", "Теплый", "Форма", "Круг"),
|
||||||
|
}
|
||||||
|
for i := range nodes {
|
||||||
|
nodes[i].SetPublicKey([]byte{byte(i)})
|
||||||
|
}
|
||||||
|
|
||||||
|
redNodes := nodes[:2]
|
||||||
|
blueNodes := nodes[2:4]
|
||||||
|
|
||||||
|
var nm NetMap
|
||||||
|
nm.SetNodes(nodes)
|
||||||
|
|
||||||
|
pivot := make([]byte, 42)
|
||||||
|
_, _ = rand.Read(pivot)
|
||||||
|
|
||||||
|
nodesPerReplica, err := nm.ContainerNodes(p, pivot)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, nodesPerReplica, 2)
|
||||||
|
|
||||||
|
for i := range nodesPerReplica {
|
||||||
|
slices.SortFunc(nodesPerReplica[i], func(n1, n2 NodeInfo) int {
|
||||||
|
pk1, pk2 := string(n1.PublicKey()), string(n2.PublicKey())
|
||||||
|
return cmp.Compare(pk1, pk2)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
redMatchFirst := reflect.DeepEqual(redNodes, nodesPerReplica[0])
|
||||||
|
blueMatchFirst := reflect.DeepEqual(blueNodes, nodesPerReplica[0])
|
||||||
|
|
||||||
|
redMatchSecond := reflect.DeepEqual(redNodes, nodesPerReplica[1])
|
||||||
|
blueMatchSecond := reflect.DeepEqual(blueNodes, nodesPerReplica[1])
|
||||||
|
|
||||||
|
assert.True(t, redMatchFirst && blueMatchSecond || blueMatchFirst && redMatchSecond)
|
||||||
|
}
|
||||||
|
|
||||||
func TestSelector_SetName(t *testing.T) {
|
func TestSelector_SetName(t *testing.T) {
|
||||||
const name = "some name"
|
const name = "some name"
|
||||||
var s Selector
|
var s Selector
|
||||||
|
|
|
@ -3,7 +3,10 @@ package object
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||||
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
|
||||||
|
@ -312,6 +315,23 @@ func (o *Object) Attributes() []Attribute {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UserAttributes returns object user attributes.
|
||||||
|
func (o *Object) UserAttributes() []Attribute {
|
||||||
|
attrs := (*object.Object)(o).
|
||||||
|
GetHeader().
|
||||||
|
GetAttributes()
|
||||||
|
|
||||||
|
res := make([]Attribute, 0, len(attrs))
|
||||||
|
|
||||||
|
for _, attr := range attrs {
|
||||||
|
if !strings.HasPrefix(attr.GetKey(), container.SysAttributePrefix) {
|
||||||
|
res = append(res, *NewAttributeFromV2(&attr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return slices.Clip(res)
|
||||||
|
}
|
||||||
|
|
||||||
// SetAttributes sets object attributes.
|
// SetAttributes sets object attributes.
|
||||||
func (o *Object) SetAttributes(v ...Attribute) {
|
func (o *Object) SetAttributes(v ...Attribute) {
|
||||||
attrs := make([]object.Attribute, len(v))
|
attrs := make([]object.Attribute, len(v))
|
||||||
|
|
|
@ -3,8 +3,10 @@ package object_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
v2container "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
||||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
|
objecttest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/test"
|
||||||
usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test"
|
usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -24,3 +26,26 @@ func TestInitCreation(t *testing.T) {
|
||||||
require.Equal(t, cnr, cID)
|
require.Equal(t, cnr, cID)
|
||||||
require.Equal(t, own, o.OwnerID())
|
require.Equal(t, own, o.OwnerID())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_Attributes(t *testing.T) {
|
||||||
|
obj := objecttest.Object()
|
||||||
|
|
||||||
|
t.Run("get user attributes", func(t *testing.T) {
|
||||||
|
// See how we create a test object. It's created with two attributes.
|
||||||
|
require.Len(t, obj.UserAttributes(), 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
userAttrs := obj.UserAttributes()
|
||||||
|
|
||||||
|
sysAttr := *object.NewAttribute()
|
||||||
|
sysAttr.SetKey(v2container.SysAttributePrefix + "key")
|
||||||
|
sysAttr.SetValue("value")
|
||||||
|
|
||||||
|
attr := append(userAttrs, sysAttr)
|
||||||
|
obj.SetAttributes(attr...)
|
||||||
|
|
||||||
|
t.Run("get attributes", func(t *testing.T) {
|
||||||
|
require.ElementsMatch(t, obj.UserAttributes(), userAttrs)
|
||||||
|
require.ElementsMatch(t, obj.Attributes(), attr)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue