Merge branch 'master' into test-redis-8

This commit is contained in:
ofekshenawa 2024-10-29 22:48:47 +02:00 committed by GitHub
commit 9ea2431935
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 1874 additions and 643 deletions

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ go 1.18
replace github.com/redis/go-redis/v9 => ../..
require (
github.com/redis/go-redis/v9 v9.6.1
github.com/redis/go-redis/v9 v9.6.2
go.uber.org/zap v1.24.0
)

View File

@ -4,7 +4,7 @@ go 1.18
replace github.com/redis/go-redis/v9 => ../..
require github.com/redis/go-redis/v9 v9.6.1
require github.com/redis/go-redis/v9 v9.6.2
require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect

View File

@ -4,7 +4,7 @@ go 1.18
replace github.com/redis/go-redis/v9 => ../..
require github.com/redis/go-redis/v9 v9.6.1
require github.com/redis/go-redis/v9 v9.6.2
require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect

View File

@ -9,8 +9,8 @@ replace github.com/redis/go-redis/extra/redisotel/v9 => ../../extra/redisotel
replace github.com/redis/go-redis/extra/rediscmd/v9 => ../../extra/rediscmd
require (
github.com/redis/go-redis/extra/redisotel/v9 v9.6.1
github.com/redis/go-redis/v9 v9.6.1
github.com/redis/go-redis/extra/redisotel/v9 v9.6.2
github.com/redis/go-redis/v9 v9.6.2
github.com/uptrace/uptrace-go v1.21.0
go.opentelemetry.io/otel v1.22.0
)
@ -23,7 +23,7 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
github.com/redis/go-redis/extra/rediscmd/v9 v9.6.1 // indirect
github.com/redis/go-redis/extra/rediscmd/v9 v9.6.2 // indirect
go.opentelemetry.io/contrib/instrumentation/runtime v0.46.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect

View File

@ -4,7 +4,7 @@ go 1.18
replace github.com/redis/go-redis/v9 => ../..
require github.com/redis/go-redis/v9 v9.6.1
require github.com/redis/go-redis/v9 v9.6.2
require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect

View File

@ -6,7 +6,7 @@ replace github.com/redis/go-redis/v9 => ../..
require (
github.com/davecgh/go-spew v1.1.1
github.com/redis/go-redis/v9 v9.6.1
github.com/redis/go-redis/v9 v9.6.2
)
require (

View File

@ -7,8 +7,8 @@ replace github.com/redis/go-redis/v9 => ../..
replace github.com/redis/go-redis/extra/rediscmd/v9 => ../rediscmd
require (
github.com/redis/go-redis/extra/rediscmd/v9 v9.6.1
github.com/redis/go-redis/v9 v9.6.1
github.com/redis/go-redis/extra/rediscmd/v9 v9.6.2
github.com/redis/go-redis/v9 v9.6.2
go.opencensus.io v0.24.0
)

View File

@ -7,7 +7,7 @@ replace github.com/redis/go-redis/v9 => ../..
require (
github.com/bsm/ginkgo/v2 v2.12.0
github.com/bsm/gomega v1.27.10
github.com/redis/go-redis/v9 v9.6.1
github.com/redis/go-redis/v9 v9.6.2
)
require (

View File

@ -7,8 +7,8 @@ replace github.com/redis/go-redis/v9 => ../..
replace github.com/redis/go-redis/extra/rediscmd/v9 => ../rediscmd
require (
github.com/redis/go-redis/extra/rediscmd/v9 v9.6.1
github.com/redis/go-redis/v9 v9.6.1
github.com/redis/go-redis/extra/rediscmd/v9 v9.6.2
github.com/redis/go-redis/v9 v9.6.2
go.opentelemetry.io/otel v1.22.0
go.opentelemetry.io/otel/metric v1.22.0
go.opentelemetry.io/otel/sdk v1.22.0

View File

@ -6,7 +6,7 @@ replace github.com/redis/go-redis/v9 => ../..
require (
github.com/prometheus/client_golang v1.14.0
github.com/redis/go-redis/v9 v9.6.1
github.com/redis/go-redis/v9 v9.6.2
)
require (

View File

@ -60,7 +60,7 @@ type JSONArrTrimArgs struct {
type JSONCmd struct {
baseCmd
val string
expanded []interface{}
expanded interface{}
}
var _ Cmder = (*JSONCmd)(nil)
@ -100,11 +100,11 @@ func (cmd *JSONCmd) Result() (string, error) {
return cmd.Val(), cmd.Err()
}
func (cmd JSONCmd) Expanded() (interface{}, error) {
func (cmd *JSONCmd) Expanded() (interface{}, error) {
if len(cmd.val) != 0 && cmd.expanded == nil {
err := json.Unmarshal([]byte(cmd.val), &cmd.expanded)
if err != nil {
return "", err
return nil, err
}
}
@ -494,7 +494,7 @@ func (c cmdable) JSONMSet(ctx context.Context, params ...interface{}) *StatusCmd
}
// JSONNumIncrBy increments the number value stored at the specified path by the provided number.
// For more information, see https://redis.io/commands/json.numincreby
// For more information, see https://redis.io/docs/latest/commands/json.numincrby/
func (c cmdable) JSONNumIncrBy(ctx context.Context, key, path string, value float64) *JSONCmd {
args := []interface{}{"JSON.NUMINCRBY", key, path, value}
cmd := newJSONCmd(ctx, args...)

View File

@ -2,6 +2,8 @@ package redis_test
import (
"context"
"encoding/json"
"time"
. "github.com/bsm/ginkgo/v2"
. "github.com/bsm/gomega"
@ -17,13 +19,27 @@ var _ = Describe("JSON Commands", Label("json"), func() {
ctx := context.TODO()
var client *redis.Client
BeforeEach(func() {
client = redis.NewClient(&redis.Options{Addr: ":6379"})
Expect(client.FlushAll(ctx).Err()).NotTo(HaveOccurred())
setupRedisClient := func(protocolVersion int) *redis.Client {
return redis.NewClient(&redis.Options{
Addr: "localhost:6379",
DB: 0,
Protocol: protocolVersion,
UnstableResp3: true,
})
}
AfterEach(func() {
Expect(client.Close()).NotTo(HaveOccurred())
if client != nil {
client.FlushDB(ctx)
client.Close()
}
})
protocols := []int{2, 3}
for _, protocol := range protocols {
BeforeEach(func() {
client = setupRedisClient(protocol)
Expect(client.FlushAll(ctx).Err()).NotTo(HaveOccurred())
})
Describe("arrays", Label("arrays"), func() {
@ -657,4 +673,146 @@ var _ = Describe("JSON Commands", Label("json"), func() {
Expect(cmd2.Val()[0]).To(Or(Equal([]interface{}{"boolean"}), Equal("boolean")))
})
})
}
})
var _ = Describe("Go-Redis Advanced JSON and RediSearch Tests", func() {
var client *redis.Client
var ctx = context.Background()
setupRedisClient := func(protocolVersion int) *redis.Client {
return redis.NewClient(&redis.Options{
Addr: "localhost:6379",
DB: 0,
Protocol: protocolVersion, // Setting RESP2 or RESP3 protocol
UnstableResp3: true, // Enable RESP3 features
})
}
AfterEach(func() {
if client != nil {
client.FlushDB(ctx)
client.Close()
}
})
Context("when testing with RESP2 and RESP3", func() {
protocols := []int{2, 3}
for _, protocol := range protocols {
When("using protocol version", func() {
BeforeEach(func() {
client = setupRedisClient(protocol)
})
It("should perform complex JSON and RediSearch operations", func() {
jsonDoc := map[string]interface{}{
"person": map[string]interface{}{
"name": "Alice",
"age": 30,
"status": true,
"address": map[string]interface{}{
"city": "Wonderland",
"postcode": "12345",
},
"contacts": []map[string]interface{}{
{"type": "email", "value": "alice@example.com"},
{"type": "phone", "value": "+123456789"},
{"type": "fax", "value": "+987654321"},
},
"friends": []map[string]interface{}{
{"name": "Bob", "age": 35, "status": true},
{"name": "Charlie", "age": 28, "status": false},
},
},
"settings": map[string]interface{}{
"notifications": map[string]interface{}{
"email": true,
"sms": false,
"alerts": []string{"low battery", "door open"},
},
"theme": "dark",
},
}
setCmd := client.JSONSet(ctx, "person:1", ".", jsonDoc)
Expect(setCmd.Err()).NotTo(HaveOccurred(), "JSON.SET failed")
getCmdRaw := client.JSONGet(ctx, "person:1", ".")
rawJSON, err := getCmdRaw.Result()
Expect(err).NotTo(HaveOccurred(), "JSON.GET (raw) failed")
GinkgoWriter.Printf("Raw JSON: %s\n", rawJSON)
getCmdExpanded := client.JSONGet(ctx, "person:1", ".")
expandedJSON, err := getCmdExpanded.Expanded()
Expect(err).NotTo(HaveOccurred(), "JSON.GET (expanded) failed")
GinkgoWriter.Printf("Expanded JSON: %+v\n", expandedJSON)
Expect(rawJSON).To(MatchJSON(jsonMustMarshal(expandedJSON)))
arrAppendCmd := client.JSONArrAppend(ctx, "person:1", "$.person.contacts", `{"type": "social", "value": "@alice_wonder"}`)
Expect(arrAppendCmd.Err()).NotTo(HaveOccurred(), "JSON.ARRAPPEND failed")
arrLenCmd := client.JSONArrLen(ctx, "person:1", "$.person.contacts")
arrLen, err := arrLenCmd.Result()
Expect(err).NotTo(HaveOccurred(), "JSON.ARRLEN failed")
Expect(arrLen).To(Equal([]int64{4}), "Array length mismatch after append")
arrInsertCmd := client.JSONArrInsert(ctx, "person:1", "$.person.friends", 1, `{"name": "Diana", "age": 25, "status": true}`)
Expect(arrInsertCmd.Err()).NotTo(HaveOccurred(), "JSON.ARRINSERT failed")
start := 0
stop := 1
arrTrimCmd := client.JSONArrTrimWithArgs(ctx, "person:1", "$.person.friends", &redis.JSONArrTrimArgs{Start: start, Stop: &stop})
Expect(arrTrimCmd.Err()).NotTo(HaveOccurred(), "JSON.ARRTRIM failed")
mergeData := map[string]interface{}{
"status": false,
"nickname": "WonderAlice",
"lastLogin": time.Now().Format(time.RFC3339),
}
mergeCmd := client.JSONMerge(ctx, "person:1", "$.person", jsonMustMarshal(mergeData))
Expect(mergeCmd.Err()).NotTo(HaveOccurred(), "JSON.MERGE failed")
typeCmd := client.JSONType(ctx, "person:1", "$.person.nickname")
nicknameType, err := typeCmd.Result()
Expect(err).NotTo(HaveOccurred(), "JSON.TYPE failed")
Expect(nicknameType[0]).To(Equal([]interface{}{"string"}), "JSON.TYPE mismatch for nickname")
createIndexCmd := client.Do(ctx, "FT.CREATE", "person_idx", "ON", "JSON",
"PREFIX", "1", "person:", "SCHEMA",
"$.person.name", "AS", "name", "TEXT",
"$.person.age", "AS", "age", "NUMERIC",
"$.person.address.city", "AS", "city", "TEXT",
"$.person.contacts[*].value", "AS", "contact_value", "TEXT",
)
Expect(createIndexCmd.Err()).NotTo(HaveOccurred(), "FT.CREATE failed")
searchCmd := client.FTSearchWithArgs(ctx, "person_idx", "@contact_value:(alice\\@example\\.com alice_wonder)", &redis.FTSearchOptions{Return: []redis.FTSearchReturn{{FieldName: "$.person.name"}, {FieldName: "$.person.age"}, {FieldName: "$.person.address.city"}}})
searchResult, err := searchCmd.Result()
Expect(err).NotTo(HaveOccurred(), "FT.SEARCH failed")
GinkgoWriter.Printf("Advanced Search result: %+v\n", searchResult)
incrCmd := client.JSONNumIncrBy(ctx, "person:1", "$.person.age", 5)
incrResult, err := incrCmd.Result()
Expect(err).NotTo(HaveOccurred(), "JSON.NUMINCRBY failed")
Expect(incrResult).To(Equal("[35]"), "Age increment mismatch")
delCmd := client.JSONDel(ctx, "person:1", "$.settings.notifications.email")
Expect(delCmd.Err()).NotTo(HaveOccurred(), "JSON.DEL failed")
typeCmd = client.JSONType(ctx, "person:1", "$.settings.notifications.email")
typeResult, err := typeCmd.Result()
Expect(err).ToNot(HaveOccurred())
Expect(typeResult[0]).To(BeEmpty(), "Expected JSON.TYPE to be empty for deleted field")
})
})
}
})
})
// Helper function to marshal data into JSON for comparisons
func jsonMustMarshal(v interface{}) string {
bytes, err := json.Marshal(v)
Expect(err).NotTo(HaveOccurred())
return string(bytes)
}

View File

@ -16,7 +16,7 @@ type SearchCmdable interface {
FTAliasAdd(ctx context.Context, index string, alias string) *StatusCmd
FTAliasDel(ctx context.Context, alias string) *StatusCmd
FTAliasUpdate(ctx context.Context, index string, alias string) *StatusCmd
FTAlter(ctx context.Context, index string, skipInitalScan bool, definition []interface{}) *StatusCmd
FTAlter(ctx context.Context, index string, skipInitialScan bool, definition []interface{}) *StatusCmd
FTConfigGet(ctx context.Context, option string) *MapMapStringInterfaceCmd
FTConfigSet(ctx context.Context, option string, value interface{}) *StatusCmd
FTCreate(ctx context.Context, index string, options *FTCreateOptions, schema ...*FieldSchema) *StatusCmd
@ -57,7 +57,7 @@ type FTCreateOptions struct {
NoFields bool
NoFreqs bool
StopWords []interface{}
SkipInitalScan bool
SkipInitialScan bool
}
type FieldSchema struct {
@ -70,7 +70,7 @@ type FieldSchema struct {
NoIndex bool
PhoneticMatcher string
Weight float64
Seperator string
Separator string
CaseSensitive bool
WithSuffixtrie bool
VectorArgs *FTVectorArgs
@ -285,7 +285,7 @@ type FTSearchSortBy struct {
type FTSearchOptions struct {
NoContent bool
Verbatim bool
NoStopWrods bool
NoStopWords bool
WithScores bool
WithPayloads bool
WithSortKeys bool
@ -808,13 +808,13 @@ func (c cmdable) FTAliasUpdate(ctx context.Context, index string, alias string)
}
// FTAlter - Alters the definition of an existing index.
// The 'index' parameter specifies the index to alter, and the 'skipInitalScan' parameter specifies whether to skip the initial scan.
// The 'index' parameter specifies the index to alter, and the 'skipInitialScan' parameter specifies whether to skip the initial scan.
// The 'definition' parameter specifies the new definition for the index.
// For more information, please refer to the Redis documentation:
// [FT.ALTER]: (https://redis.io/commands/ft.alter/)
func (c cmdable) FTAlter(ctx context.Context, index string, skipInitalScan bool, definition []interface{}) *StatusCmd {
func (c cmdable) FTAlter(ctx context.Context, index string, skipInitialScan bool, definition []interface{}) *StatusCmd {
args := []interface{}{"FT.ALTER", index}
if skipInitalScan {
if skipInitialScan {
args = append(args, "SKIPINITIALSCAN")
}
args = append(args, "SCHEMA", "ADD")
@ -907,7 +907,7 @@ func (c cmdable) FTCreate(ctx context.Context, index string, options *FTCreateOp
args = append(args, "STOPWORDS", len(options.StopWords))
args = append(args, options.StopWords...)
}
if options.SkipInitalScan {
if options.SkipInitialScan {
args = append(args, "SKIPINITIALSCAN")
}
}
@ -1003,8 +1003,8 @@ func (c cmdable) FTCreate(ctx context.Context, index string, options *FTCreateOp
if schema.Weight > 0 {
args = append(args, "WEIGHT", schema.Weight)
}
if schema.Seperator != "" {
args = append(args, "SEPERATOR", schema.Seperator)
if schema.Separator != "" {
args = append(args, "SEPARATOR", schema.Separator)
}
if schema.CaseSensitive {
args = append(args, "CASESENSITIVE")
@ -1694,7 +1694,7 @@ func FTSearchQuery(query string, options *FTSearchOptions) SearchQuery {
if options.Verbatim {
queryArgs = append(queryArgs, "VERBATIM")
}
if options.NoStopWrods {
if options.NoStopWords {
queryArgs = append(queryArgs, "NOSTOPWORDS")
}
if options.WithScores {
@ -1808,7 +1808,7 @@ func (c cmdable) FTSearchWithArgs(ctx context.Context, index string, query strin
if options.Verbatim {
args = append(args, "VERBATIM")
}
if options.NoStopWrods {
if options.NoStopWords {
args = append(args, "NOSTOPWORDS")
}
if options.WithScores {

View File

@ -637,11 +637,11 @@ var _ = Describe("RediSearch commands Resp 2", Label("search"), func() {
})
It("should FTSearch SkipInitalScan", Label("search", "ftsearch"), func() {
It("should FTSearch SkipInitialScan", Label("search", "ftsearch"), func() {
client.HSet(ctx, "doc1", "foo", "bar")
text1 := &redis.FieldSchema{FieldName: "foo", FieldType: redis.SearchFieldTypeText}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{SkipInitalScan: true}, text1).Result()
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{SkipInitialScan: true}, text1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")

View File

@ -2,5 +2,5 @@ package redis
// Version is the current release version.
func Version() string {
return "9.6.1"
return "9.6.2"
}