From 191391d66db3ed078660a6a73c9996ca866d07d6 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Fri, 9 Aug 2019 15:04:56 +0300 Subject: [PATCH] Add writing version of GeoRadius commands --- command.go | 12 ++++++++---- commands.go | 44 +++++++++++++++++++++++++++++++++----------- commands_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/command.go b/command.go index b8f69771..833a12b6 100644 --- a/command.go +++ b/command.go @@ -1580,6 +1580,13 @@ type GeoLocationCmd struct { var _ Cmder = (*GeoLocationCmd)(nil) func NewGeoLocationCmd(q *GeoRadiusQuery, args ...interface{}) *GeoLocationCmd { + return &GeoLocationCmd{ + baseCmd: baseCmd{_args: geoLocationArgs(q, args...)}, + q: q, + } +} + +func geoLocationArgs(q *GeoRadiusQuery, args ...interface{}) []interface{} { args = append(args, q.Radius) if q.Unit != "" { args = append(args, q.Unit) @@ -1609,10 +1616,7 @@ func NewGeoLocationCmd(q *GeoRadiusQuery, args ...interface{}) *GeoLocationCmd { args = append(args, "storedist") args = append(args, q.StoreDist) } - return &GeoLocationCmd{ - baseCmd: baseCmd{_args: args}, - q: q, - } + return args } func (cmd *GeoLocationCmd) Val() []GeoLocation { diff --git a/commands.go b/commands.go index ec2d4c9a..51bad639 100644 --- a/commands.go +++ b/commands.go @@ -282,9 +282,9 @@ type Cmdable interface { GeoAdd(key string, geoLocation ...*GeoLocation) *IntCmd GeoPos(key string, members ...string) *GeoPosCmd GeoRadius(key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd - GeoRadiusRO(key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd + GeoRadiusStore(key string, longitude, latitude float64, query *GeoRadiusQuery) *IntCmd GeoRadiusByMember(key, member string, query *GeoRadiusQuery) *GeoLocationCmd - GeoRadiusByMemberRO(key, member string, query *GeoRadiusQuery) *GeoLocationCmd + GeoRadiusByMemberStore(key, member string, query *GeoRadiusQuery) *IntCmd GeoDist(key string, member1, member2, unit string) *FloatCmd GeoHash(key string, members ...string) *StringSliceCmd ReadOnly() *StatusCmd @@ -2513,26 +2513,48 @@ func (c cmdable) GeoAdd(key string, geoLocation ...*GeoLocation) *IntCmd { return cmd } +// GeoRadius is a read-only GEORADIUS_RO command. func (c cmdable) GeoRadius(key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd { - cmd := NewGeoLocationCmd(query, "georadius", key, longitude, latitude) - _ = c(cmd) - return cmd -} - -func (c cmdable) GeoRadiusRO(key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd { cmd := NewGeoLocationCmd(query, "georadius_ro", key, longitude, latitude) + if query.Store != "" || query.StoreDist != "" { + cmd.setErr(errors.New("GeoRadius does not support Store or StoreDist")) + return cmd + } _ = c(cmd) return cmd } +// GeoRadiusStore is a writing GEORADIUS command. +func (c cmdable) GeoRadiusStore(key string, longitude, latitude float64, query *GeoRadiusQuery) *IntCmd { + args := geoLocationArgs(query, "georadius", key, longitude, latitude) + cmd := NewIntCmd(args...) + if query.Store == "" && query.StoreDist == "" { + cmd.setErr(errors.New("GeoRadiusStore requires Store or StoreDist")) + return cmd + } + _ = c(cmd) + return cmd +} + +// GeoRadius is a read-only GEORADIUSBYMEMBER_RO command. func (c cmdable) GeoRadiusByMember(key, member string, query *GeoRadiusQuery) *GeoLocationCmd { - cmd := NewGeoLocationCmd(query, "georadiusbymember", key, member) + cmd := NewGeoLocationCmd(query, "georadiusbymember_ro", key, member) + if query.Store != "" || query.StoreDist != "" { + cmd.setErr(errors.New("GeoRadiusByMember does not support Store or StoreDist")) + return cmd + } _ = c(cmd) return cmd } -func (c cmdable) GeoRadiusByMemberRO(key, member string, query *GeoRadiusQuery) *GeoLocationCmd { - cmd := NewGeoLocationCmd(query, "georadiusbymember_ro", key, member) +// GeoRadiusByMemberStore is a writing GEORADIUSBYMEMBER command. +func (c cmdable) GeoRadiusByMemberStore(key, member string, query *GeoRadiusQuery) *IntCmd { + args := geoLocationArgs(query, "georadiusbymember", key, member) + cmd := NewIntCmd(args...) + if query.Store == "" && query.StoreDist == "" { + cmd.setErr(errors.New("GeoRadiusByMemberStore requires Store or StoreDist")) + return cmd + } _ = c(cmd) return cmd } diff --git a/commands_test.go b/commands_test.go index d1bb6eda..c84452f6 100644 --- a/commands_test.go +++ b/commands_test.go @@ -3733,6 +3733,46 @@ var _ = Describe("Commands", func() { Expect(res[1].Name).To(Equal("Catania")) }) + It("should geo radius and store the result", func() { + n, err := client.GeoRadiusStore("Sicily", 15, 37, &redis.GeoRadiusQuery{ + Radius: 200, + Store: "result", + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(n).To(Equal(int64(2))) + + res, err := client.ZRangeWithScores("result", 0, -1).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(res).To(ContainElement(redis.Z{ + Score: 3.479099956230698e+15, + Member: "Palermo", + })) + Expect(res).To(ContainElement(redis.Z{ + Score: 3.479447370796909e+15, + Member: "Catania", + })) + }) + + It("should geo radius and store dist", func() { + n, err := client.GeoRadiusStore("Sicily", 15, 37, &redis.GeoRadiusQuery{ + Radius: 200, + StoreDist: "result", + }).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(n).To(Equal(int64(2))) + + res, err := client.ZRangeWithScores("result", 0, -1).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(res).To(ContainElement(redis.Z{ + Score: 190.44242984775784, + Member: "Palermo", + })) + Expect(res).To(ContainElement(redis.Z{ + Score: 56.4412578701582, + Member: "Catania", + })) + }) + It("should search geo radius with options", func() { res, err := client.GeoRadius("Sicily", 15, 37, &redis.GeoRadiusQuery{ Radius: 200,