| 897 | } |
| 898 | |
| 899 | void genericHgetallCommand(client *c, int flags) { |
| 900 | robj_roptr o; |
| 901 | hashTypeIterator *hi; |
| 902 | int length, count = 0; |
| 903 | AeLocker locker; |
| 904 | |
| 905 | robj *emptyResp = (flags & OBJ_HASH_KEY && flags & OBJ_HASH_VALUE) ? |
| 906 | shared.emptymap[c->resp] : shared.emptyarray; |
| 907 | if ((o = lookupKeyReadOrReply(c,c->argv[1],emptyResp,locker)) |
| 908 | == nullptr || checkType(c,o,OBJ_HASH)) return; |
| 909 | |
| 910 | /* We return a map if the user requested keys and values, like in the |
| 911 | * HGETALL case. Otherwise to use a flat array makes more sense. */ |
| 912 | length = hashTypeLength(o); |
| 913 | if (flags & OBJ_HASH_KEY && flags & OBJ_HASH_VALUE) { |
| 914 | addReplyMapLen(c, length); |
| 915 | } else { |
| 916 | addReplyArrayLen(c, length); |
| 917 | } |
| 918 | |
| 919 | hi = hashTypeInitIterator(o); |
| 920 | while (hashTypeNext(hi) != C_ERR) { |
| 921 | if (flags & OBJ_HASH_KEY) { |
| 922 | addHashIteratorCursorToReply(c, hi, OBJ_HASH_KEY); |
| 923 | count++; |
| 924 | } |
| 925 | if (flags & OBJ_HASH_VALUE) { |
| 926 | addHashIteratorCursorToReply(c, hi, OBJ_HASH_VALUE); |
| 927 | count++; |
| 928 | } |
| 929 | } |
| 930 | |
| 931 | hashTypeReleaseIterator(hi); |
| 932 | |
| 933 | /* Make sure we returned the right number of elements. */ |
| 934 | if (flags & OBJ_HASH_KEY && flags & OBJ_HASH_VALUE) count /= 2; |
| 935 | serverAssert(count == length); |
| 936 | } |
| 937 | |
| 938 | void hkeysCommand(client *c) { |
| 939 | genericHgetallCommand(c,OBJ_HASH_KEY); |
no test coverage detected