summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2015-06-29 10:47:07 +0200
committerantirez <antirez@gmail.com>2015-06-29 10:47:07 +0200
commitaae0a1f9cce0ced9e6aa2e76977d6db72f6b4edc (patch)
tree906cd36b04c926dbc87268399f74808e7377c740
parentf6edd0cb933c1c82c3e9e9dd33597654602a1ba4 (diff)
downloadredis-aae0a1f9cce0ced9e6aa2e76977d6db72f6b4edc.tar.gz
Geo: GEOPOS command and tests.
-rw-r--r--src/geo.c33
-rw-r--r--src/redis.c1
-rw-r--r--src/redis.h1
-rw-r--r--tests/unit/geo.tcl17
4 files changed, 52 insertions, 0 deletions
diff --git a/src/geo.c b/src/geo.c
index 37d632815..18b0efac1 100644
--- a/src/geo.c
+++ b/src/geo.c
@@ -709,3 +709,36 @@ void geoHashCommand(redisClient *c) {
}
}
}
+
+/* GEOPOS key ele1 ele2 ... eleN
+ *
+ * Returns an array of two-items arrays representing the x,y position of each
+ * element specified in the arguments. For missing elements NULL is returned. */
+void geoposCommand(redisClient *c) {
+ int j;
+
+ /* Look up the requested zset */
+ robj *zobj = NULL;
+ if ((zobj = lookupKeyReadOrReply(c, c->argv[1], shared.emptymultibulk))
+ == NULL || checkType(c, zobj, REDIS_ZSET)) return;
+
+ /* Report elements one after the other, using a null bulk reply for
+ * missing elements. */
+ addReplyMultiBulkLen(c,c->argc-2);
+ for (j = 2; j < c->argc; j++) {
+ double score;
+ if (zsetScore(zobj, c->argv[j], &score) == REDIS_ERR) {
+ addReply(c,shared.nullmultibulk);
+ } else {
+ /* Decode... */
+ double xy[2];
+ if (!decodeGeohash(score,xy)) {
+ addReply(c,shared.nullmultibulk);
+ continue;
+ }
+ addReplyMultiBulkLen(c,2);
+ addReplyDouble(c,xy[0]);
+ addReplyDouble(c,xy[1]);
+ }
+ }
+}
diff --git a/src/redis.c b/src/redis.c
index 2221e128b..38430b82c 100644
--- a/src/redis.c
+++ b/src/redis.c
@@ -288,6 +288,7 @@ struct redisCommand redisCommandTable[] = {
{"geoencode",geoEncodeCommand,-3,"r",0,NULL,0,0,0,0,0},
{"geodecode",geoDecodeCommand,2,"r",0,NULL,0,0,0,0,0},
{"geohash",geoHashCommand,-2,"r",0,NULL,0,0,0,0,0},
+ {"geopos",geoposCommand,-2,"r",0,NULL,0,0,0,0,0},
{"pfselftest",pfselftestCommand,1,"r",0,NULL,0,0,0,0,0},
{"pfadd",pfaddCommand,-2,"wmF",0,NULL,1,1,1,0,0},
{"pfcount",pfcountCommand,-2,"r",0,NULL,1,1,1,0,0},
diff --git a/src/redis.h b/src/redis.h
index 4fd643ac1..8eca36d07 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -1564,6 +1564,7 @@ void geoRadiusByMemberCommand(redisClient *c);
void geoRadiusCommand(redisClient *c);
void geoAddCommand(redisClient *c);
void geoHashCommand(redisClient *c);
+void geoposCommand(redisClient *c);
void pfselftestCommand(redisClient *c);
void pfaddCommand(redisClient *c);
void pfcountCommand(redisClient *c);
diff --git a/tests/unit/geo.tcl b/tests/unit/geo.tcl
index c67334936..191f88c58 100644
--- a/tests/unit/geo.tcl
+++ b/tests/unit/geo.tcl
@@ -92,6 +92,23 @@ start_server {tags {"geo"}} {
lindex [r geohash points test] 0
} {ezs42e44yx0}
+ test {GEOPOS simple} {
+ r del points
+ r geoadd points 10 20 a 30 40 b
+ lassign [lindex [r geopos points a b] 0] x1 y1
+ lassign [lindex [r geopos points a b] 1] x2 y2
+ assert {abs($x1 - 10) < 0.001}
+ assert {abs($y1 - 20) < 0.001}
+ assert {abs($x2 - 30) < 0.001}
+ assert {abs($y2 - 40) < 0.001}
+ }
+
+ test {GEOPOS missing element} {
+ r del points
+ r geoadd points 10 20 a 30 40 b
+ lindex [r geopos points a x b] 1
+ } {}
+
test {GEOADD + GEORANGE randomized test} {
set attempt 10
while {[incr attempt -1]} {