GEOADD - add [CH] [NX|XX] options (#8227)
New command flags similar to what SADD already has. Co-authored-by: huangwei03 <huangwei03@kuaishou.com> Co-authored-by: Itamar Haber <itamar@redislabs.com> Co-authored-by: Oran Agra <oran@redislabs.com>
This commit is contained in:
parent
91690a2920
commit
33fb617053
42
src/geo.c
42
src/geo.c
@ -428,31 +428,45 @@ static int sort_gp_desc(const void *a, const void *b) {
|
|||||||
* Commands
|
* Commands
|
||||||
* ==================================================================== */
|
* ==================================================================== */
|
||||||
|
|
||||||
/* GEOADD key long lat name [long2 lat2 name2 ... longN latN nameN] */
|
/* GEOADD key [CH] [NX|XX] long lat name [long2 lat2 name2 ... longN latN nameN] */
|
||||||
void geoaddCommand(client *c) {
|
void geoaddCommand(client *c) {
|
||||||
/* Check arguments number for sanity. */
|
int xx = 0, nx = 0, longidx = 2;
|
||||||
if ((c->argc - 2) % 3 != 0) {
|
int i;
|
||||||
|
|
||||||
|
/* Parse options. At the end 'longidx' is set to the argument position
|
||||||
|
* of the longitude of the first element. */
|
||||||
|
while (longidx < c->argc) {
|
||||||
|
char *opt = c->argv[longidx]->ptr;
|
||||||
|
if (!strcasecmp(opt,"nx")) nx = 1;
|
||||||
|
else if (!strcasecmp(opt,"xx")) xx = 1;
|
||||||
|
else if (!strcasecmp(opt,"ch")) {}
|
||||||
|
else break;
|
||||||
|
longidx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((c->argc - longidx) % 3 || (xx && nx)) {
|
||||||
/* Need an odd number of arguments if we got this far... */
|
/* Need an odd number of arguments if we got this far... */
|
||||||
addReplyError(c, "syntax error. Try GEOADD key [x1] [y1] [name1] "
|
addReplyErrorObject(c,shared.syntaxerr);
|
||||||
"[x2] [y2] [name2] ... ");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int elements = (c->argc - 2) / 3;
|
/* Set up the vector for calling ZADD. */
|
||||||
int argc = 2+elements*2; /* ZADD key score ele ... */
|
int elements = (c->argc - longidx) / 3;
|
||||||
|
int argc = longidx+elements*2; /* ZADD key [CH] [NX|XX] score ele ... */
|
||||||
robj **argv = zcalloc(argc*sizeof(robj*));
|
robj **argv = zcalloc(argc*sizeof(robj*));
|
||||||
argv[0] = createRawStringObject("zadd",4);
|
argv[0] = createRawStringObject("zadd",4);
|
||||||
argv[1] = c->argv[1]; /* key */
|
for (i = 1; i < longidx; i++) {
|
||||||
incrRefCount(argv[1]);
|
argv[i] = c->argv[i];
|
||||||
|
incrRefCount(argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the argument vector to call ZADD in order to add all
|
/* Create the argument vector to call ZADD in order to add all
|
||||||
* the score,value pairs to the requested zset, where score is actually
|
* the score,value pairs to the requested zset, where score is actually
|
||||||
* an encoded version of lat,long. */
|
* an encoded version of lat,long. */
|
||||||
int i;
|
|
||||||
for (i = 0; i < elements; i++) {
|
for (i = 0; i < elements; i++) {
|
||||||
double xy[2];
|
double xy[2];
|
||||||
|
|
||||||
if (extractLongLatOrReply(c, (c->argv+2)+(i*3),xy) == C_ERR) {
|
if (extractLongLatOrReply(c, (c->argv+longidx)+(i*3),xy) == C_ERR) {
|
||||||
for (i = 0; i < argc; i++)
|
for (i = 0; i < argc; i++)
|
||||||
if (argv[i]) decrRefCount(argv[i]);
|
if (argv[i]) decrRefCount(argv[i]);
|
||||||
zfree(argv);
|
zfree(argv);
|
||||||
@ -464,9 +478,9 @@ void geoaddCommand(client *c) {
|
|||||||
geohashEncodeWGS84(xy[0], xy[1], GEO_STEP_MAX, &hash);
|
geohashEncodeWGS84(xy[0], xy[1], GEO_STEP_MAX, &hash);
|
||||||
GeoHashFix52Bits bits = geohashAlign52Bits(hash);
|
GeoHashFix52Bits bits = geohashAlign52Bits(hash);
|
||||||
robj *score = createObject(OBJ_STRING, sdsfromlonglong(bits));
|
robj *score = createObject(OBJ_STRING, sdsfromlonglong(bits));
|
||||||
robj *val = c->argv[2 + i * 3 + 2];
|
robj *val = c->argv[longidx + i * 3 + 2];
|
||||||
argv[2+i*2] = score;
|
argv[longidx+i*2] = score;
|
||||||
argv[3+i*2] = val;
|
argv[longidx+1+i*2] = val;
|
||||||
incrRefCount(val);
|
incrRefCount(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,49 @@ start_server {tags {"geo"}} {
|
|||||||
r geoadd nyc -73.9454966 40.747533 "lic market"
|
r geoadd nyc -73.9454966 40.747533 "lic market"
|
||||||
} {0}
|
} {0}
|
||||||
|
|
||||||
|
test {GEOADD update with CH option} {
|
||||||
|
assert_equal 1 [r geoadd nyc CH 40.747533 -73.9454966 "lic market"]
|
||||||
|
lassign [lindex [r geopos nyc "lic market"] 0] x1 y1
|
||||||
|
assert {abs($x1) - 40.747 < 0.001}
|
||||||
|
assert {abs($y1) - 73.945 < 0.001}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
test {GEOADD update with NX option} {
|
||||||
|
assert_equal 0 [r geoadd nyc NX -73.9454966 40.747533 "lic market"]
|
||||||
|
lassign [lindex [r geopos nyc "lic market"] 0] x1 y1
|
||||||
|
assert {abs($x1) - 40.747 < 0.001}
|
||||||
|
assert {abs($y1) - 73.945 < 0.001}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
test {GEOADD update with XX option} {
|
||||||
|
assert_equal 0 [r geoadd nyc XX -83.9454966 40.747533 "lic market"]
|
||||||
|
lassign [lindex [r geopos nyc "lic market"] 0] x1 y1
|
||||||
|
assert {abs($x1) - 83.945 < 0.001}
|
||||||
|
assert {abs($y1) - 40.747 < 0.001}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
test {GEOADD update with CH NX option} {
|
||||||
|
r geoadd nyc CH NX -73.9454966 40.747533 "lic market"
|
||||||
|
} {0}
|
||||||
|
|
||||||
|
test {GEOADD update with CH XX option} {
|
||||||
|
r geoadd nyc CH XX -73.9454966 40.747533 "lic market"
|
||||||
|
} {1}
|
||||||
|
|
||||||
|
test {GEOADD update with XX NX option will return syntax error} {
|
||||||
|
catch {
|
||||||
|
r geoadd nyc xx nx -73.9454966 40.747533 "lic market"
|
||||||
|
} err
|
||||||
|
set err
|
||||||
|
} {ERR*syntax*}
|
||||||
|
|
||||||
|
test {GEOADD update with invalid option} {
|
||||||
|
catch {
|
||||||
|
r geoadd nyc ch xx foo -73.9454966 40.747533 "lic market"
|
||||||
|
} err
|
||||||
|
set err
|
||||||
|
} {ERR*syntax*}
|
||||||
|
|
||||||
test {GEOADD invalid coordinates} {
|
test {GEOADD invalid coordinates} {
|
||||||
catch {
|
catch {
|
||||||
r geoadd nyc -73.9454966 40.747533 "lic market" \
|
r geoadd nyc -73.9454966 40.747533 "lic market" \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user