| 1477 | } |
| 1478 | |
| 1479 | void renameGenericCommand(client *c, int nx) { |
| 1480 | robj *o; |
| 1481 | int samekey = 0; |
| 1482 | |
| 1483 | /* When source and dest key is the same, no operation is performed, |
| 1484 | * if the key exists, however we still return an error on unexisting key. */ |
| 1485 | if (sdscmp(szFromObj(c->argv[1]),szFromObj(c->argv[2])) == 0) samekey = 1; |
| 1486 | |
| 1487 | if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr)) == NULL) |
| 1488 | return; |
| 1489 | |
| 1490 | if (samekey) { |
| 1491 | addReply(c,nx ? shared.czero : shared.ok); |
| 1492 | return; |
| 1493 | } |
| 1494 | |
| 1495 | incrRefCount(o); |
| 1496 | |
| 1497 | if (lookupKeyWrite(c->db,c->argv[2]) != NULL) { |
| 1498 | if (nx) { |
| 1499 | decrRefCount(o); |
| 1500 | addReply(c,shared.czero); |
| 1501 | return; |
| 1502 | } |
| 1503 | /* Overwrite: delete the old key before creating the new one |
| 1504 | * with the same name. */ |
| 1505 | dbDelete(c->db,c->argv[2]); |
| 1506 | } |
| 1507 | bool fExpires = o->FExpires(); |
| 1508 | long long whenT = o->expire.when(); |
| 1509 | dbDelete(c->db,c->argv[1]); |
| 1510 | o->SetFExpires(fExpires); |
| 1511 | dbAddCore(c->db,szFromObj(c->argv[2]),o,true /*fUpdateMvcc*/,true/*fAssumeNew*/,nullptr,true/*fValExpires*/); |
| 1512 | serverAssert(whenT == o->expire.when()); // dbDelete and dbAdd must not modify the expire, just the FExpire bit |
| 1513 | signalModifiedKey(c,c->db,c->argv[1]); |
| 1514 | signalModifiedKey(c,c->db,c->argv[2]); |
| 1515 | notifyKeyspaceEvent(NOTIFY_GENERIC,"rename_from", |
| 1516 | c->argv[1],c->db->id); |
| 1517 | notifyKeyspaceEvent(NOTIFY_GENERIC,"rename_to", |
| 1518 | c->argv[2],c->db->id); |
| 1519 | g_pserver->dirty++; |
| 1520 | addReply(c,nx ? shared.cone : shared.ok); |
| 1521 | } |
| 1522 | |
| 1523 | void renameCommand(client *c) { |
| 1524 | renameGenericCommand(c,0); |
no test coverage detected