| 577 | } |
| 578 | |
| 579 | void incrDecrCommand(client *c, long long incr) { |
| 580 | long long value, oldvalue; |
| 581 | robj *o, *new; |
| 582 | |
| 583 | o = lookupKeyWrite(c->db,c->argv[1]); |
| 584 | if (checkType(c,o,OBJ_STRING)) return; |
| 585 | if (getLongLongFromObjectOrReply(c,o,&value,NULL) != C_OK) return; |
| 586 | |
| 587 | oldvalue = value; |
| 588 | if ((incr < 0 && oldvalue < 0 && incr < (LLONG_MIN-oldvalue)) || |
| 589 | (incr > 0 && oldvalue > 0 && incr > (LLONG_MAX-oldvalue))) { |
| 590 | addReplyError(c,"increment or decrement would overflow"); |
| 591 | return; |
| 592 | } |
| 593 | value += incr; |
| 594 | |
| 595 | if (o && o->refcount == 1 && o->encoding == OBJ_ENCODING_INT && |
| 596 | (value < 0 || value >= OBJ_SHARED_INTEGERS) && |
| 597 | value >= LONG_MIN && value <= LONG_MAX) |
| 598 | { |
| 599 | new = o; |
| 600 | o->ptr = (void*)((long)value); |
| 601 | } else { |
| 602 | new = createStringObjectFromLongLongForValue(value); |
| 603 | if (o) { |
| 604 | dbOverwrite(c->db,c->argv[1],new); |
| 605 | } else { |
| 606 | dbAdd(c->db,c->argv[1],new); |
| 607 | } |
| 608 | } |
| 609 | signalModifiedKey(c,c->db,c->argv[1]); |
| 610 | notifyKeyspaceEvent(NOTIFY_STRING,"incrby",c->argv[1],c->db->id); |
| 611 | server.dirty++; |
| 612 | addReply(c,shared.colon); |
| 613 | addReply(c,new); |
| 614 | addReply(c,shared.crlf); |
| 615 | } |
| 616 | |
| 617 | void incrCommand(client *c) { |
| 618 | incrDecrCommand(c,1); |
no test coverage detected