diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..43ceded --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,50 @@ +name: Go + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + + build: + name: Build + runs-on: ubuntu-latest + + services: + # Label used to access the service container + redis: + # Docker Hub image + image: redis + # Set health checks to wait until redis has started + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + # Maps port 6379 on service container to the host + - 6379:6379 + steps: + + - name: Set up Go 1.x + uses: actions/setup-go@v2 + with: + go-version: ^1.14 + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + go get -v -t -d ./... + if [ -f Gopkg.toml ]; then + curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh + dep ensure + fi + - name: Install golangci + run: | + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.31.0 + - name: Test + run: make diff --git a/commands.go b/commands.go index 8a08f61..79698ba 100644 --- a/commands.go +++ b/commands.go @@ -168,6 +168,8 @@ type Cmdable interface { LInsertAfter(ctx context.Context, key string, pivot, value interface{}) *IntCmd LLen(ctx context.Context, key string) *IntCmd LPop(ctx context.Context, key string) *StringCmd + LPos(ctx context.Context, key string, value string, args LPosArgs) *IntCmd + LPosCount(ctx context.Context, key string, value string, count int64, args LPosArgs) *IntSliceCmd LPush(ctx context.Context, key string, values ...interface{}) *IntCmd LPushX(ctx context.Context, key string, values ...interface{}) *IntCmd LRange(ctx context.Context, key string, start, stop int64) *StringSliceCmd @@ -1188,6 +1190,37 @@ func (c cmdable) LPop(ctx context.Context, key string) *StringCmd { return cmd } +type LPosArgs struct { + Rank, MaxLen int64 +} + +func (c cmdable) LPos(ctx context.Context, key string, value string, a LPosArgs) *IntCmd { + args := []interface{}{"lpos", key, value} + if a.Rank != 0 { + args = append(args, "rank", a.Rank) + } + if a.MaxLen != 0 { + args = append(args, "maxlen", a.MaxLen) + } + + cmd := NewIntCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + +func (c cmdable) LPosCount(ctx context.Context, key string, value string, count int64, a LPosArgs) *IntSliceCmd { + args := []interface{}{"lpos", key, value, "count", count} + if a.Rank != 0 { + args = append(args, "rank", a.Rank) + } + if a.MaxLen != 0 { + args = append(args, "maxlen", a.MaxLen) + } + cmd := NewIntSliceCmd(ctx, args...) + _ = c(ctx, cmd) + return cmd +} + func (c cmdable) LPush(ctx context.Context, key string, values ...interface{}) *IntCmd { args := make([]interface{}, 2, 2+len(values)) args[0] = "lpush" diff --git a/commands_test.go b/commands_test.go index 4e6e955..b5855c6 100644 --- a/commands_test.go +++ b/commands_test.go @@ -1691,6 +1691,62 @@ var _ = Describe("Commands", func() { Expect(lRange.Val()).To(Equal([]string{"two", "three"})) }) + It("should LPos", func() { + rPush := client.RPush(ctx, "list", "a") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "b") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "c") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "b") + Expect(rPush.Err()).NotTo(HaveOccurred()) + + lPos := client.LPos(ctx, "list", "b", redis.LPosArgs{}) + Expect(lPos.Err()).NotTo(HaveOccurred()) + Expect(lPos.Val()).To(Equal(int64(1))) + + lPos = client.LPos(ctx, "list", "b", redis.LPosArgs{Rank: 2}) + Expect(lPos.Err()).NotTo(HaveOccurred()) + Expect(lPos.Val()).To(Equal(int64(3))) + + lPos = client.LPos(ctx, "list", "b", redis.LPosArgs{Rank: -2}) + Expect(lPos.Err()).NotTo(HaveOccurred()) + Expect(lPos.Val()).To(Equal(int64(1))) + + lPos = client.LPos(ctx, "list", "b", redis.LPosArgs{Rank: 2, MaxLen: 1}) + Expect(lPos.Err()).To(Equal(redis.Nil)) + + lPos = client.LPos(ctx, "list", "z", redis.LPosArgs{}) + Expect(lPos.Err()).To(Equal(redis.Nil)) + }) + + It("should LPosCount", func() { + rPush := client.RPush(ctx, "list", "a") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "b") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "c") + Expect(rPush.Err()).NotTo(HaveOccurred()) + rPush = client.RPush(ctx, "list", "b") + Expect(rPush.Err()).NotTo(HaveOccurred()) + + lPos := client.LPosCount(ctx, "list", "b", 2, redis.LPosArgs{}) + Expect(lPos.Err()).NotTo(HaveOccurred()) + Expect(lPos.Val()).To(Equal([]int64{1, 3})) + + lPos = client.LPosCount(ctx, "list", "b", 2, redis.LPosArgs{Rank: 2}) + Expect(lPos.Err()).NotTo(HaveOccurred()) + Expect(lPos.Val()).To(Equal([]int64{3})) + + lPos = client.LPosCount(ctx, "list", "b", 1, redis.LPosArgs{Rank: 1, MaxLen: 1}) + Expect(lPos.Err()).NotTo(HaveOccurred()) + Expect(lPos.Val()).To(Equal([]int64{})) + + lPos = client.LPosCount(ctx, "list", "b", 1, redis.LPosArgs{Rank: 1, MaxLen: 0}) + Expect(lPos.Err()).NotTo(HaveOccurred()) + Expect(lPos.Val()).To(Equal([]int64{1})) + }) + It("should LPush", func() { lPush := client.LPush(ctx, "list", "World") Expect(lPush.Err()).NotTo(HaveOccurred())