int Ardb::HashGetAll(Context& ctx, const Slice& key, RedisReply& reply) { ValueObject meta; int err = GetMetaValue(ctx, key, HASH_META, meta); CHECK_ARDB_RETURN_VALUE(ctx.reply, err); reply.type = REDIS_REPLY_ARRAY; if (0 != err) { return 0; } HashIterator iter; err = HashIter(ctx, meta, "", iter, true); CHECK_ARDB_RETURN_VALUE(ctx.reply, err); reply.type = REDIS_REPLY_ARRAY; while (iter.Valid()) { const Data* field = iter.Field(); Data* value = iter.Value(); RedisReply& r = reply.AddMember(); fill_value_reply(r, *field); RedisReply& r1 = reply.AddMember(); fill_value_reply(r1, *value); iter.Next(); } return 0; }
int Ardb::RenameHash(Context& ctx, DBID srcdb, const std::string& srckey, DBID dstdb, const std::string& dstkey) { Context tmpctx; tmpctx.currentDB = srcdb; ValueObject v; int err = GetMetaValue(tmpctx, srckey, HASH_META, v); CHECK_ARDB_RETURN_VALUE(ctx.reply, err); if (0 != err) { fill_error_reply(ctx.reply, "no such key or some error"); return 0; } if (v.meta.encoding == COLLECTION_ECODING_ZIPMAP) { DelKeyValue(tmpctx, v.key); v.key.encode_buf.Clear(); v.key.db = dstdb; v.key.key = dstkey; v.meta.expireat = 0; SetKeyValue(ctx, v); } else { HashIterator iter; HashIter(ctx, v, "", iter, false); tmpctx.currentDB = dstdb; ValueObject dstmeta; dstmeta.key.type = KEY_META; dstmeta.key.key = dstkey; dstmeta.type = HASH_META; dstmeta.meta.encoding = COLLECTION_ECODING_ZIPMAP; BatchWriteGuard guard(GetKeyValueEngine()); while (iter.Valid()) { HashSet(tmpctx, dstmeta, *(iter.Field()), *(iter.Value())); iter.Next(); } SetKeyValue(tmpctx, dstmeta); tmpctx.currentDB = srcdb; DeleteKey(tmpctx, srckey); } ctx.data_change = true; return 0; }
int Ardb::HKeys(Context& ctx, RedisCommandFrame& cmd) { ValueObject meta; int err = GetMetaValue(ctx, cmd.GetArguments()[0], HASH_META, meta); CHECK_ARDB_RETURN_VALUE(ctx.reply, err); ctx.reply.type = REDIS_REPLY_ARRAY; if (0 != err) { return 0; } HashIterator iter; err = HashIter(ctx, meta, "", iter, true); CHECK_ARDB_RETURN_VALUE(ctx.reply, err); ctx.reply.type = REDIS_REPLY_ARRAY; while (iter.Valid()) { const Data* value = iter.Field(); RedisReply& r = ctx.reply.AddMember(); std::string tmp; fill_str_reply(r, value->GetDecodeString(tmp)); iter.Next(); } return 0; }
int Ardb::HScan(Context& ctx, RedisCommandFrame& cmd) { std::string pattern; uint32 limit = 10000; //return max 10000 keys one time if (cmd.GetArguments().size() > 2) { for (uint32 i = 2; i < cmd.GetArguments().size(); i++) { if (!strcasecmp(cmd.GetArguments()[i].c_str(), "count")) { if (i + 1 >= cmd.GetArguments().size() || !string_touint32(cmd.GetArguments()[i + 1], limit)) { fill_error_reply(ctx.reply, "value is not an integer or out of range"); return 0; } i++; } else if (!strcasecmp(cmd.GetArguments()[i].c_str(), "match")) { if (i + 1 >= cmd.GetArguments().size()) { fill_error_reply(ctx.reply, "'MATCH' need one args followed"); return 0; } pattern = cmd.GetArguments()[i + 1]; i++; } else { fill_error_reply(ctx.reply, "Syntax error, try scan 0 "); return 0; } } } ValueObject meta; int err = GetMetaValue(ctx, cmd.GetArguments()[0], HASH_META, meta); CHECK_ARDB_RETURN_VALUE(ctx.reply, err); RedisReply& r1 = ctx.reply.AddMember(); RedisReply& r2 = ctx.reply.AddMember(); r2.type = REDIS_REPLY_ARRAY; if (0 != err) { fill_str_reply(r1, "0"); return 0; } const std::string& cursor = cmd.GetArguments()[1]; HashIterator iter; HashIter(ctx, meta, cursor == "0" ? "" : cursor, iter, true); while (iter.Valid()) { const Data* field = iter.Field(); std::string tmp; field->GetDecodeString(tmp); if ((pattern.empty() || fnmatch(pattern.c_str(), tmp.c_str(), 0) == 0)) { RedisReply& rr1 = r2.AddMember(); RedisReply& rr2 = r2.AddMember(); fill_str_reply(rr1, tmp); fill_value_reply(rr2, *(iter.Value())); } if (r2.MemberSize() >= (limit * 2)) { break; } iter.Next(); } if (iter.Valid()) { iter.Next(); const Data* next_field = iter.Field(); std::string tmp; fill_str_reply(r1, next_field->GetDecodeString(tmp)); } else { fill_str_reply(r1, "0"); } return 0; }