Skip to content

Commit cb291da

Browse files
committed
feat(vectorset): improve VSetAttr API and add comprehensive test suite
- Simplify VSetAttr to accept interface{} with automatic JSON marshalling - Remove VectorAttributeMarshaller interface for simpler API - Add comprehensive unit tests for all vectorset commands
1 parent 0c8cafb commit cb291da

File tree

4 files changed

+893
-324
lines changed

4 files changed

+893
-324
lines changed

unit_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package redis
2+
3+
import (
4+
"context"
5+
)
6+
7+
// mockCmdable is a mock implementation of cmdable that records the last command.
8+
// This is used for unit testing command construction without requiring a Redis server.
9+
type mockCmdable struct {
10+
lastCmd Cmder
11+
returnErr error
12+
}
13+
14+
func (m *mockCmdable) call(ctx context.Context, cmd Cmder) error {
15+
m.lastCmd = cmd
16+
if m.returnErr != nil {
17+
cmd.SetErr(m.returnErr)
18+
}
19+
return m.returnErr
20+
}
21+
22+
func (m *mockCmdable) asCmdable() cmdable {
23+
return func(ctx context.Context, cmd Cmder) error {
24+
return m.call(ctx, cmd)
25+
}
26+
}

vectorset_commands.go

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package redis
22

33
import (
44
"context"
5+
"encoding/json"
56
"strconv"
67
)
78

@@ -19,7 +20,7 @@ type VectorSetCmdable interface {
1920
VRandMember(ctx context.Context, key string) *StringCmd
2021
VRandMemberCount(ctx context.Context, key string, count int) *StringSliceCmd
2122
VRem(ctx context.Context, key, element string) *BoolCmd
22-
VSetAttr(ctx context.Context, key, element string, attr VectorAttributeMarshaller) *BoolCmd
23+
VSetAttr(ctx context.Context, key, element string, attr interface{}) *BoolCmd
2324
VClearAttributes(ctx context.Context, key, element string) *BoolCmd
2425
VSim(ctx context.Context, key string, val Vector) *StringSliceCmd
2526
VSimWithScores(ctx context.Context, key string, val Vector) *VectorScoreSliceCmd
@@ -77,18 +78,6 @@ type VectorScore struct {
7778
Score float64
7879
}
7980

80-
type VectorAttributeMarshaller interface {
81-
Marshall() string
82-
}
83-
84-
type VectorAttributeRawString string
85-
86-
func (a *VectorAttributeRawString) Marshall() string {
87-
return string(*a)
88-
}
89-
90-
var _ VectorAttributeMarshaller = (*VectorAttributeRawString)(nil)
91-
9281
// `VADD key (FP32 | VALUES num) vector element`
9382
// note: the API is experimental and may be subject to change.
9483
func (c cmdable) VAdd(ctx context.Context, key, element string, val Vector) *BoolCmd {
@@ -242,9 +231,30 @@ func (c cmdable) VRem(ctx context.Context, key, element string) *BoolCmd {
242231
}
243232

244233
// `VSETATTR key element "{ JSON obj }"`
234+
// The `attr` must be something that can be marshaled to JSON (using encoding/JSON) unless
235+
// the argument is a string or []byte when we assume that it can be passed directly as JSON.
236+
//
245237
// note: the API is experimental and may be subject to change.
246-
func (c cmdable) VSetAttr(ctx context.Context, key, element string, attr VectorAttributeMarshaller) *BoolCmd {
247-
cmd := NewBoolCmd(ctx, "vsetattr", key, element, attr.Marshall())
238+
func (c cmdable) VSetAttr(ctx context.Context, key, element string, attr interface{}) *BoolCmd {
239+
var attrStr string
240+
var err error
241+
switch v := attr.(type) {
242+
case string:
243+
attrStr = v
244+
case []byte:
245+
attrStr = string(v)
246+
default:
247+
var bytes []byte
248+
bytes, err = json.Marshal(v)
249+
if err != nil {
250+
// If marshalling fails, create the command and set the error; this command won't be executed.
251+
cmd := NewBoolCmd(ctx, "vsetattr", key, element, "")
252+
cmd.SetErr(err)
253+
return cmd
254+
}
255+
attrStr = string(bytes)
256+
}
257+
cmd := NewBoolCmd(ctx, "vsetattr", key, element, attrStr)
248258
_ = c(ctx, cmd)
249259
return cmd
250260
}

0 commit comments

Comments
 (0)