Skip to content

Commit e0c224d

Browse files
authored
Merge branch 'master' into ndyakov/token-based-auth
2 parents d0a8c76 + a7b4ce5 commit e0c224d

11 files changed

+682
-333
lines changed

.github/workflows/spellcheck.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
- name: Checkout
99
uses: actions/checkout@v4
1010
- name: Check Spelling
11-
uses: rojopolis/spellcheck-github-actions@0.47.0
11+
uses: rojopolis/spellcheck-github-actions@0.48.0
1212
with:
1313
config_path: .github/spellcheck-settings.yml
1414
task_name: Markdown

command.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -3831,7 +3831,8 @@ func (cmd *MapStringStringSliceCmd) readReply(rd *proto.Reader) error {
38313831
}
38323832

38333833
// -----------------------------------------------------------------------
3834-
// MapStringInterfaceCmd represents a command that returns a map of strings to interface{}.
3834+
3835+
// MapMapStringInterfaceCmd represents a command that returns a map of strings to interface{}.
38353836
type MapMapStringInterfaceCmd struct {
38363837
baseCmd
38373838
val map[string]interface{}

commands.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ func (info LibraryInfo) Validate() error {
330330
return nil
331331
}
332332

333-
// Hello Set the resp protocol used.
333+
// Hello sets the resp protocol used.
334334
func (c statefulCmdable) Hello(ctx context.Context,
335335
ver int, username, password, clientName string,
336336
) *MapStringInterfaceCmd {

doctests/home_json_example_test.go

+28
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,32 @@ func ExampleClient_search_json() {
152152
// >>> Tel Aviv
153153
// STEP_END
154154

155+
// STEP_START query2count_only
156+
citiesResult2, err := rdb.FTSearchWithArgs(
157+
ctx,
158+
"idx:users",
159+
"Paul",
160+
&redis.FTSearchOptions{
161+
Return: []redis.FTSearchReturn{
162+
{
163+
FieldName: "$.city",
164+
As: "city",
165+
},
166+
},
167+
CountOnly: true,
168+
},
169+
).Result()
170+
171+
if err != nil {
172+
panic(err)
173+
}
174+
175+
// The `Total` field has the correct number of docs found
176+
// by the query but the `Docs` slice is empty.
177+
fmt.Println(len(citiesResult2.Docs)) // >>> 0
178+
fmt.Println(citiesResult2.Total) // >>> 2
179+
// STEP_END
180+
155181
// STEP_START query3
156182
aggOptions := redis.FTAggregateOptions{
157183
GroupBy: []redis.FTAggregateGroupBy{
@@ -196,6 +222,8 @@ func ExampleClient_search_json() {
196222
// {1 [{user:3 <nil> <nil> <nil> map[$:{"age":35,"city":"Tel Aviv","email":"paul.zamir@example.com","name":"Paul Zamir"}]}]}
197223
// London
198224
// Tel Aviv
225+
// 0
226+
// 2
199227
// London - 1
200228
// Tel Aviv - 2
201229
}

hash_commands.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type HashCmdable interface {
1313
HGetDel(ctx context.Context, key string, fields ...string) *StringSliceCmd
1414
HGetEX(ctx context.Context, key string, fields ...string) *StringSliceCmd
1515
HGetEXWithArgs(ctx context.Context, key string, options *HGetEXOptions, fields ...string) *StringSliceCmd
16+
HIncrBy(ctx context.Context, key, field string, incr int64) *IntCmd
1617
HIncrByFloat(ctx context.Context, key, field string, incr float64) *FloatCmd
1718
HKeys(ctx context.Context, key string) *StringSliceCmd
1819
HLen(ctx context.Context, key string) *IntCmd
@@ -479,7 +480,7 @@ func (c cmdable) HGetEX(ctx context.Context, key string, fields ...string) *Stri
479480
return cmd
480481
}
481482

482-
// ExpirationType represents an expiration option for the HGETEX command.
483+
// HGetEXExpirationType represents an expiration option for the HGETEX command.
483484
type HGetEXExpirationType string
484485

485486
const (

internal_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -352,3 +352,27 @@ var _ = Describe("withConn", func() {
352352
Expect(client.connPool.Len()).To(Equal(1))
353353
})
354354
})
355+
356+
var _ = Describe("ClusterClient", func() {
357+
var client *ClusterClient
358+
359+
BeforeEach(func() {
360+
client = &ClusterClient{}
361+
})
362+
363+
Describe("cmdSlot", func() {
364+
It("select slot from args for GETKEYSINSLOT command", func() {
365+
cmd := NewStringSliceCmd(ctx, "cluster", "getkeysinslot", 100, 200)
366+
367+
slot := client.cmdSlot(context.Background(), cmd)
368+
Expect(slot).To(Equal(100))
369+
})
370+
371+
It("select slot from args for COUNTKEYSINSLOT command", func() {
372+
cmd := NewStringSliceCmd(ctx, "cluster", "countkeysinslot", 100)
373+
374+
slot := client.cmdSlot(context.Background(), cmd)
375+
Expect(slot).To(Equal(100))
376+
})
377+
})
378+
})

osscluster.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1859,7 +1859,7 @@ func (c *ClusterClient) cmdInfo(ctx context.Context, name string) *CommandInfo {
18591859

18601860
func (c *ClusterClient) cmdSlot(ctx context.Context, cmd Cmder) int {
18611861
args := cmd.Args()
1862-
if args[0] == "cluster" && args[1] == "getkeysinslot" {
1862+
if args[0] == "cluster" && (args[1] == "getkeysinslot" || args[1] == "countkeysinslot") {
18631863
return args[2].(int)
18641864
}
18651865

search_commands.go

+17-219
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ type SpellCheckTerms struct {
114114
}
115115

116116
type FTExplainOptions struct {
117+
// Dialect 1,3 and 4 are deprecated since redis 8.0
117118
Dialect string
118119
}
119120

@@ -261,7 +262,8 @@ type FTAggregateOptions struct {
261262
WithCursor bool
262263
WithCursorOptions *FTAggregateWithCursor
263264
Params map[string]interface{}
264-
DialectVersion int
265+
// Dialect 1,3 and 4 are deprecated since redis 8.0
266+
DialectVersion int
265267
}
266268

267269
type FTSearchFilter struct {
@@ -320,8 +322,12 @@ type FTSearchOptions struct {
320322
SortByWithCount bool
321323
LimitOffset int
322324
Limit int
323-
Params map[string]interface{}
324-
DialectVersion int
325+
// CountOnly sets LIMIT 0 0 to get the count - number of documents in the result set without actually returning the result set.
326+
// When using this option, the Limit and LimitOffset options are ignored.
327+
CountOnly bool
328+
Params map[string]interface{}
329+
// Dialect 1,3 and 4 are deprecated since redis 8.0
330+
DialectVersion int
325331
}
326332

327333
type FTSynDumpResult struct {
@@ -437,7 +443,8 @@ type IndexDefinition struct {
437443
type FTSpellCheckOptions struct {
438444
Distance int
439445
Terms *FTSpellCheckTerms
440-
Dialect int
446+
// Dialect 1,3 and 4 are deprecated since redis 8.0
447+
Dialect int
441448
}
442449

443450
type FTSpellCheckTerms struct {
@@ -1954,8 +1961,12 @@ func (c cmdable) FTSearchWithArgs(ctx context.Context, index string, query strin
19541961
args = append(args, "WITHCOUNT")
19551962
}
19561963
}
1957-
if options.LimitOffset >= 0 && options.Limit > 0 {
1958-
args = append(args, "LIMIT", options.LimitOffset, options.Limit)
1964+
if options.CountOnly {
1965+
args = append(args, "LIMIT", 0, 0)
1966+
} else {
1967+
if options.LimitOffset >= 0 && options.Limit > 0 || options.LimitOffset > 0 && options.Limit == 0 {
1968+
args = append(args, "LIMIT", options.LimitOffset, options.Limit)
1969+
}
19591970
}
19601971
if options.Params != nil {
19611972
args = append(args, "PARAMS", len(options.Params)*2)
@@ -2090,216 +2101,3 @@ func (c cmdable) FTTagVals(ctx context.Context, index string, field string) *Str
20902101
_ = c(ctx, cmd)
20912102
return cmd
20922103
}
2093-
2094-
// TODO: remove FTProfile
2095-
// type FTProfileResult struct {
2096-
// Results []interface{}
2097-
// Profile ProfileDetails
2098-
// }
2099-
2100-
// type ProfileDetails struct {
2101-
// TotalProfileTime string
2102-
// ParsingTime string
2103-
// PipelineCreationTime string
2104-
// Warning string
2105-
// IteratorsProfile []IteratorProfile
2106-
// ResultProcessorsProfile []ResultProcessorProfile
2107-
// }
2108-
2109-
// type IteratorProfile struct {
2110-
// Type string
2111-
// QueryType string
2112-
// Time interface{}
2113-
// Counter int
2114-
// Term string
2115-
// Size int
2116-
// ChildIterators []IteratorProfile
2117-
// }
2118-
2119-
// type ResultProcessorProfile struct {
2120-
// Type string
2121-
// Time interface{}
2122-
// Counter int
2123-
// }
2124-
2125-
// func parseFTProfileResult(data []interface{}) (FTProfileResult, error) {
2126-
// var result FTProfileResult
2127-
// if len(data) < 2 {
2128-
// return result, fmt.Errorf("unexpected data length")
2129-
// }
2130-
2131-
// // Parse results
2132-
// result.Results = data[0].([]interface{})
2133-
2134-
// // Parse profile details
2135-
// profileData := data[1].([]interface{})
2136-
// profileDetails := ProfileDetails{}
2137-
// for i := 0; i < len(profileData); i += 2 {
2138-
// switch profileData[i].(string) {
2139-
// case "Total profile time":
2140-
// profileDetails.TotalProfileTime = profileData[i+1].(string)
2141-
// case "Parsing time":
2142-
// profileDetails.ParsingTime = profileData[i+1].(string)
2143-
// case "Pipeline creation time":
2144-
// profileDetails.PipelineCreationTime = profileData[i+1].(string)
2145-
// case "Warning":
2146-
// profileDetails.Warning = profileData[i+1].(string)
2147-
// case "Iterators profile":
2148-
// profileDetails.IteratorsProfile = parseIteratorsProfile(profileData[i+1].([]interface{}))
2149-
// case "Result processors profile":
2150-
// profileDetails.ResultProcessorsProfile = parseResultProcessorsProfile(profileData[i+1].([]interface{}))
2151-
// }
2152-
// }
2153-
2154-
// result.Profile = profileDetails
2155-
// return result, nil
2156-
// }
2157-
2158-
// func parseIteratorsProfile(data []interface{}) []IteratorProfile {
2159-
// var iterators []IteratorProfile
2160-
// for _, item := range data {
2161-
// profile := item.([]interface{})
2162-
// iterator := IteratorProfile{}
2163-
// for i := 0; i < len(profile); i += 2 {
2164-
// switch profile[i].(string) {
2165-
// case "Type":
2166-
// iterator.Type = profile[i+1].(string)
2167-
// case "Query type":
2168-
// iterator.QueryType = profile[i+1].(string)
2169-
// case "Time":
2170-
// iterator.Time = profile[i+1]
2171-
// case "Counter":
2172-
// iterator.Counter = int(profile[i+1].(int64))
2173-
// case "Term":
2174-
// iterator.Term = profile[i+1].(string)
2175-
// case "Size":
2176-
// iterator.Size = int(profile[i+1].(int64))
2177-
// case "Child iterators":
2178-
// iterator.ChildIterators = parseChildIteratorsProfile(profile[i+1].([]interface{}))
2179-
// }
2180-
// }
2181-
// iterators = append(iterators, iterator)
2182-
// }
2183-
// return iterators
2184-
// }
2185-
2186-
// func parseChildIteratorsProfile(data []interface{}) []IteratorProfile {
2187-
// var iterators []IteratorProfile
2188-
// for _, item := range data {
2189-
// profile := item.([]interface{})
2190-
// iterator := IteratorProfile{}
2191-
// for i := 0; i < len(profile); i += 2 {
2192-
// switch profile[i].(string) {
2193-
// case "Type":
2194-
// iterator.Type = profile[i+1].(string)
2195-
// case "Query type":
2196-
// iterator.QueryType = profile[i+1].(string)
2197-
// case "Time":
2198-
// iterator.Time = profile[i+1]
2199-
// case "Counter":
2200-
// iterator.Counter = int(profile[i+1].(int64))
2201-
// case "Term":
2202-
// iterator.Term = profile[i+1].(string)
2203-
// case "Size":
2204-
// iterator.Size = int(profile[i+1].(int64))
2205-
// }
2206-
// }
2207-
// iterators = append(iterators, iterator)
2208-
// }
2209-
// return iterators
2210-
// }
2211-
2212-
// func parseResultProcessorsProfile(data []interface{}) []ResultProcessorProfile {
2213-
// var processors []ResultProcessorProfile
2214-
// for _, item := range data {
2215-
// profile := item.([]interface{})
2216-
// processor := ResultProcessorProfile{}
2217-
// for i := 0; i < len(profile); i += 2 {
2218-
// switch profile[i].(string) {
2219-
// case "Type":
2220-
// processor.Type = profile[i+1].(string)
2221-
// case "Time":
2222-
// processor.Time = profile[i+1]
2223-
// case "Counter":
2224-
// processor.Counter = int(profile[i+1].(int64))
2225-
// }
2226-
// }
2227-
// processors = append(processors, processor)
2228-
// }
2229-
// return processors
2230-
// }
2231-
2232-
// func NewFTProfileCmd(ctx context.Context, args ...interface{}) *FTProfileCmd {
2233-
// return &FTProfileCmd{
2234-
// baseCmd: baseCmd{
2235-
// ctx: ctx,
2236-
// args: args,
2237-
// },
2238-
// }
2239-
// }
2240-
2241-
// type FTProfileCmd struct {
2242-
// baseCmd
2243-
// val FTProfileResult
2244-
// }
2245-
2246-
// func (cmd *FTProfileCmd) String() string {
2247-
// return cmdString(cmd, cmd.val)
2248-
// }
2249-
2250-
// func (cmd *FTProfileCmd) SetVal(val FTProfileResult) {
2251-
// cmd.val = val
2252-
// }
2253-
2254-
// func (cmd *FTProfileCmd) Result() (FTProfileResult, error) {
2255-
// return cmd.val, cmd.err
2256-
// }
2257-
2258-
// func (cmd *FTProfileCmd) Val() FTProfileResult {
2259-
// return cmd.val
2260-
// }
2261-
2262-
// func (cmd *FTProfileCmd) readReply(rd *proto.Reader) (err error) {
2263-
// data, err := rd.ReadSlice()
2264-
// if err != nil {
2265-
// return err
2266-
// }
2267-
// cmd.val, err = parseFTProfileResult(data)
2268-
// if err != nil {
2269-
// cmd.err = err
2270-
// }
2271-
// return nil
2272-
// }
2273-
2274-
// // FTProfile - Executes a search query and returns a profile of how the query was processed.
2275-
// // The 'index' parameter specifies the index to search, the 'limited' parameter specifies whether to limit the results,
2276-
// // and the 'query' parameter specifies the search / aggreagte query. Please notice that you must either pass a SearchQuery or an AggregateQuery.
2277-
// // For more information, please refer to the Redis documentation:
2278-
// // [FT.PROFILE]: (https://redis.io/commands/ft.profile/)
2279-
// func (c cmdable) FTProfile(ctx context.Context, index string, limited bool, query interface{}) *FTProfileCmd {
2280-
// queryType := ""
2281-
// var argsQuery []interface{}
2282-
2283-
// switch v := query.(type) {
2284-
// case AggregateQuery:
2285-
// queryType = "AGGREGATE"
2286-
// argsQuery = v
2287-
// case SearchQuery:
2288-
// queryType = "SEARCH"
2289-
// argsQuery = v
2290-
// default:
2291-
// panic("FT.PROFILE: query must be either AggregateQuery or SearchQuery")
2292-
// }
2293-
2294-
// args := []interface{}{"FT.PROFILE", index, queryType}
2295-
2296-
// if limited {
2297-
// args = append(args, "LIMITED")
2298-
// }
2299-
// args = append(args, "QUERY")
2300-
// args = append(args, argsQuery...)
2301-
2302-
// cmd := NewFTProfileCmd(ctx, args...)
2303-
// _ = c(ctx, cmd)
2304-
// return cmd
2305-
// }

0 commit comments

Comments
 (0)