GEOADD key [CH] [NX|XX] long lat name [long2 lat2 name2 ... longN latN nameN] */
| 436 | |
| 437 | /* GEOADD key [CH] [NX|XX] long lat name [long2 lat2 name2 ... longN latN nameN] */ |
| 438 | void geoaddCommand(client *c) { |
| 439 | int xx = 0, nx = 0, longidx = 2; |
| 440 | int i; |
| 441 | |
| 442 | /* Parse options. At the end 'longidx' is set to the argument position |
| 443 | * of the longitude of the first element. */ |
| 444 | while (longidx < c->argc) { |
| 445 | char *opt = c->argv[longidx]->ptr; |
| 446 | if (!strcasecmp(opt,"nx")) nx = 1; |
| 447 | else if (!strcasecmp(opt,"xx")) xx = 1; |
| 448 | else if (!strcasecmp(opt,"ch")) {} |
| 449 | else break; |
| 450 | longidx++; |
| 451 | } |
| 452 | |
| 453 | if ((c->argc - longidx) % 3 || (xx && nx)) { |
| 454 | /* Need an odd number of arguments if we got this far... */ |
| 455 | addReplyErrorObject(c,shared.syntaxerr); |
| 456 | return; |
| 457 | } |
| 458 | |
| 459 | /* Set up the vector for calling ZADD. */ |
| 460 | int elements = (c->argc - longidx) / 3; |
| 461 | int argc = longidx+elements*2; /* ZADD key [CH] [NX|XX] score ele ... */ |
| 462 | robj **argv = zcalloc(argc*sizeof(robj*)); |
| 463 | argv[0] = createRawStringObject("zadd",4); |
| 464 | for (i = 1; i < longidx; i++) { |
| 465 | argv[i] = c->argv[i]; |
| 466 | incrRefCount(argv[i]); |
| 467 | } |
| 468 | |
| 469 | /* Create the argument vector to call ZADD in order to add all |
| 470 | * the score,value pairs to the requested zset, where score is actually |
| 471 | * an encoded version of lat,long. */ |
| 472 | for (i = 0; i < elements; i++) { |
| 473 | double xy[2]; |
| 474 | |
| 475 | if (extractLongLatOrReply(c, (c->argv+longidx)+(i*3),xy) == C_ERR) { |
| 476 | for (i = 0; i < argc; i++) |
| 477 | if (argv[i]) decrRefCount(argv[i]); |
| 478 | zfree(argv); |
| 479 | return; |
| 480 | } |
| 481 | |
| 482 | /* Turn the coordinates into the score of the element. */ |
| 483 | GeoHashBits hash; |
| 484 | geohashEncodeWGS84(xy[0], xy[1], GEO_STEP_MAX, &hash); |
| 485 | GeoHashFix52Bits bits = geohashAlign52Bits(hash); |
| 486 | robj *score = createObject(OBJ_STRING, sdsfromlonglong(bits)); |
| 487 | robj *val = c->argv[longidx + i * 3 + 2]; |
| 488 | argv[longidx+i*2] = score; |
| 489 | argv[longidx+1+i*2] = val; |
| 490 | incrRefCount(val); |
| 491 | } |
| 492 | |
| 493 | /* Finally call ZADD that will do the work for us. */ |
| 494 | replaceClientCommandVector(c,argc,argv); |
| 495 | zaddCommand(c); |
nothing calls this directly
no test coverage detected