Repository: go-redis/redis
Pull request #2354 (2023-01-18 11:29:42)

feat: add SORT_RO command
Add support for [sort read only](https://redis.io/commands/sort_ro/) command, as suggested in discussion https://github.com/go-redis/redis/discussions/2352#discussioncomment-4715670


Patch:
diff --git a/commands.go b/commands.go
index 2e37d73..9077d09 100644
--- a/commands.go
+++ b/commands.go
@@ -116,6 +116,7 @@ type Cmdable interface {
 	Restore(ctx context.Context, key string, ttl time.Duration, value string) *StatusCmd
 	RestoreReplace(ctx context.Context, key string, ttl time.Duration, value string) *StatusCmd
 	Sort(ctx context.Context, key string, sort *Sort) *StringSliceCmd
+	SortRO(ctx context.Context, key string, sort *Sort) *StringSliceCmd
 	SortStore(ctx context.Context, key, store string, sort *Sort) *IntCmd
 	SortInterfaces(ctx context.Context, key string, sort *Sort) *SliceCmd
 	Touch(ctx context.Context, keys ...string) *IntCmd
@@ -710,8 +711,9 @@ type Sort struct {
 	Alpha         bool
 }
 
-func (sort *Sort) args(key string) []interface{} {
-	args := []interface{}{"sort", key}
+func (sort *Sort) args(command, key string) []interface{} {
+	args := []interface{}{command, key}
+
 	if sort.By != "" {
 		args = append(args, "by", sort.By)
 	}
@@ -730,14 +732,20 @@ func (sort *Sort) args(key string) []interface{} {
 	return args
 }
 
+func (c cmdable) SortRO(ctx context.Context, key string, sort *Sort) *StringSliceCmd {
+	cmd := NewStringSliceCmd(ctx, sort.args("sort_ro", key)...)
+	_ = c(ctx, cmd)
+	return cmd
+}
+
 func (c cmdable) Sort(ctx context.Context, key string, sort *Sort) *StringSliceCmd {
-	cmd := NewStringSliceCmd(ctx, sort.args(key)...)
+	cmd := NewStringSliceCmd(ctx, sort.args("sort", key)...)
 	_ = c(ctx, cmd)
 	return cmd
 }
 
 func (c cmdable) SortStore(ctx context.Context, key, store string, sort *Sort) *IntCmd {
-	args := sort.args(key)
+	args := sort.args("sort", key)
 	if store != "" {
 		args = append(args, "store", store)
 	}
@@ -747,7 +755,7 @@ func (c cmdable) SortStore(ctx context.Context, key, store string, sort *Sort) *
 }
 
 func (c cmdable) SortInterfaces(ctx context.Context, key string, sort *Sort) *SliceCmd {
-	cmd := NewSliceCmd(ctx, sort.args(key)...)
+	cmd := NewSliceCmd(ctx, sort.args("sort", key)...)
 	_ = c(ctx, cmd)
 	return cmd
 }


Test patch:
diff --git a/commands_test.go b/commands_test.go
index 01bc4e0..def9d7f 100644
--- a/commands_test.go
+++ b/commands_test.go
@@ -668,6 +668,28 @@ var _ = Describe("Commands", func() {
 			Expect(val).To(Equal("hello"))
 		})
 
+		It("should Sort RO", func() {
+			size, err := client.LPush(ctx, "list", "1").Result()
+			Expect(err).NotTo(HaveOccurred())
+			Expect(size).To(Equal(int64(1)))
+
+			size, err = client.LPush(ctx, "list", "3").Result()
+			Expect(err).NotTo(HaveOccurred())
+			Expect(size).To(Equal(int64(2)))
+
+			size, err = client.LPush(ctx, "list", "2").Result()
+			Expect(err).NotTo(HaveOccurred())
+			Expect(size).To(Equal(int64(3)))
+
+			els, err := client.SortRO(ctx, "list", &redis.Sort{
+				Offset: 0,
+				Count:  2,
+				Order:  "ASC",
+			}).Result()
+			Expect(err).NotTo(HaveOccurred())
+			Expect(els).To(Equal([]string{"1", "2"}))
+		})
+
 		It("should Sort", func() {
 			size, err := client.LPush(ctx, "list", "1").Result()
 			Expect(err).NotTo(HaveOccurred())