You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 line
4.9 KiB

  1. package redis
  2. import (
  3. "context"
  4. "errors"
  5. )
  6. type GeoCmdable interface {
  7. GeoAdd(ctx context.Context, key string, geoLocation ...*GeoLocation) *IntCmd
  8. GeoPos(ctx context.Context, key string, members ...string) *GeoPosCmd
  9. GeoRadius(ctx context.Context, key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd
  10. GeoRadiusStore(ctx context.Context, key string, longitude, latitude float64, query *GeoRadiusQuery) *IntCmd
  11. GeoRadiusByMember(ctx context.Context, key, member string, query *GeoRadiusQuery) *GeoLocationCmd
  12. GeoRadiusByMemberStore(ctx context.Context, key, member string, query *GeoRadiusQuery) *IntCmd
  13. GeoSearch(ctx context.Context, key string, q *GeoSearchQuery) *StringSliceCmd
  14. GeoSearchLocation(ctx context.Context, key string, q *GeoSearchLocationQuery) *GeoSearchLocationCmd
  15. GeoSearchStore(ctx context.Context, key, store string, q *GeoSearchStoreQuery) *IntCmd
  16. GeoDist(ctx context.Context, key string, member1, member2, unit string) *FloatCmd
  17. GeoHash(ctx context.Context, key string, members ...string) *StringSliceCmd
  18. }
  19. func (c cmdable) GeoAdd(ctx context.Context, key string, geoLocation ...*GeoLocation) *IntCmd {
  20. args := make([]interface{}, 2+3*len(geoLocation))
  21. args[0] = "geoadd"
  22. args[1] = key
  23. for i, eachLoc := range geoLocation {
  24. args[2+3*i] = eachLoc.Longitude
  25. args[2+3*i+1] = eachLoc.Latitude
  26. args[2+3*i+2] = eachLoc.Name
  27. }
  28. cmd := NewIntCmd(ctx, args...)
  29. _ = c(ctx, cmd)
  30. return cmd
  31. }
  32. // GeoRadius is a read-only GEORADIUS_RO command.
  33. func (c cmdable) GeoRadius(
  34. ctx context.Context, key string, longitude, latitude float64, query *GeoRadiusQuery,
  35. ) *GeoLocationCmd {
  36. cmd := NewGeoLocationCmd(ctx, query, "georadius_ro", key, longitude, latitude)
  37. if query.Store != "" || query.StoreDist != "" {
  38. cmd.SetErr(errors.New("GeoRadius does not support Store or StoreDist"))
  39. return cmd
  40. }
  41. _ = c(ctx, cmd)
  42. return cmd
  43. }
  44. // GeoRadiusStore is a writing GEORADIUS command.
  45. func (c cmdable) GeoRadiusStore(
  46. ctx context.Context, key string, longitude, latitude float64, query *GeoRadiusQuery,
  47. ) *IntCmd {
  48. args := geoLocationArgs(query, "georadius", key, longitude, latitude)
  49. cmd := NewIntCmd(ctx, args...)
  50. if query.Store == "" && query.StoreDist == "" {
  51. cmd.SetErr(errors.New("GeoRadiusStore requires Store or StoreDist"))
  52. return cmd
  53. }
  54. _ = c(ctx, cmd)
  55. return cmd
  56. }
  57. // GeoRadiusByMember is a read-only GEORADIUSBYMEMBER_RO command.
  58. func (c cmdable) GeoRadiusByMember(
  59. ctx context.Context, key, member string, query *GeoRadiusQuery,
  60. ) *GeoLocationCmd {
  61. cmd := NewGeoLocationCmd(ctx, query, "georadiusbymember_ro", key, member)
  62. if query.Store != "" || query.StoreDist != "" {
  63. cmd.SetErr(errors.New("GeoRadiusByMember does not support Store or StoreDist"))
  64. return cmd
  65. }
  66. _ = c(ctx, cmd)
  67. return cmd
  68. }
  69. // GeoRadiusByMemberStore is a writing GEORADIUSBYMEMBER command.
  70. func (c cmdable) GeoRadiusByMemberStore(
  71. ctx context.Context, key, member string, query *GeoRadiusQuery,
  72. ) *IntCmd {
  73. args := geoLocationArgs(query, "georadiusbymember", key, member)
  74. cmd := NewIntCmd(ctx, args...)
  75. if query.Store == "" && query.StoreDist == "" {
  76. cmd.SetErr(errors.New("GeoRadiusByMemberStore requires Store or StoreDist"))
  77. return cmd
  78. }
  79. _ = c(ctx, cmd)
  80. return cmd
  81. }
  82. func (c cmdable) GeoSearch(ctx context.Context, key string, q *GeoSearchQuery) *StringSliceCmd {
  83. args := make([]interface{}, 0, 13)
  84. args = append(args, "geosearch", key)
  85. args = geoSearchArgs(q, args)
  86. cmd := NewStringSliceCmd(ctx, args...)
  87. _ = c(ctx, cmd)
  88. return cmd
  89. }
  90. func (c cmdable) GeoSearchLocation(
  91. ctx context.Context, key string, q *GeoSearchLocationQuery,
  92. ) *GeoSearchLocationCmd {
  93. args := make([]interface{}, 0, 16)
  94. args = append(args, "geosearch", key)
  95. args = geoSearchLocationArgs(q, args)
  96. cmd := NewGeoSearchLocationCmd(ctx, q, args...)
  97. _ = c(ctx, cmd)
  98. return cmd
  99. }
  100. func (c cmdable) GeoSearchStore(ctx context.Context, key, store string, q *GeoSearchStoreQuery) *IntCmd {
  101. args := make([]interface{}, 0, 15)
  102. args = append(args, "geosearchstore", store, key)
  103. args = geoSearchArgs(&q.GeoSearchQuery, args)
  104. if q.StoreDist {
  105. args = append(args, "storedist")
  106. }
  107. cmd := NewIntCmd(ctx, args...)
  108. _ = c(ctx, cmd)
  109. return cmd
  110. }
  111. func (c cmdable) GeoDist(
  112. ctx context.Context, key string, member1, member2, unit string,
  113. ) *FloatCmd {
  114. if unit == "" {
  115. unit = "km"
  116. }
  117. cmd := NewFloatCmd(ctx, "geodist", key, member1, member2, unit)
  118. _ = c(ctx, cmd)
  119. return cmd
  120. }
  121. func (c cmdable) GeoHash(ctx context.Context, key string, members ...string) *StringSliceCmd {
  122. args := make([]interface{}, 2+len(members))
  123. args[0] = "geohash"
  124. args[1] = key
  125. for i, member := range members {
  126. args[2+i] = member
  127. }
  128. cmd := NewStringSliceCmd(ctx, args...)
  129. _ = c(ctx, cmd)
  130. return cmd
  131. }
  132. func (c cmdable) GeoPos(ctx context.Context, key string, members ...string) *GeoPosCmd {
  133. args := make([]interface{}, 2+len(members))
  134. args[0] = "geopos"
  135. args[1] = key
  136. for i, member := range members {
  137. args[2+i] = member
  138. }
  139. cmd := NewGeoPosCmd(ctx, args...)
  140. _ = c(ctx, cmd)
  141. return cmd
  142. }