Example #1
0
    int Comms::BLPop(Context& ctx, RedisCommandFrame& cmd)
    {
        uint32 timeout;
        if (!string_touint32(cmd.GetArguments()[cmd.GetArguments().size() - 1], timeout))
        {
            fill_error_reply(ctx.reply, "timeout is not an integer or out of range");
            return 0;
        }
        bool lpop = cmd.GetType() == REDIS_CMD_BLPOP;
        for (uint32 i = 0; i < cmd.GetArguments().size() - 1; i++)
        {
            std::string v;
            int err =
                    lpop ? m_kv_store->LPop(ctx.currentDB, cmd.GetArguments()[i], v) : m_kv_store->RPop(ctx.currentDB,
                                   cmd.GetArguments()[i], v);
            if (0 == err && !v.empty())
            {
                RedisReply& r1 = ctx.reply.AddMember();
                RedisReply& r2 = ctx.reply.AddMember();
                fill_str_reply(r1, cmd.GetArguments()[i]);
                fill_str_reply(r2, v);

                FireKeyChangedEvent(ctx, ctx.currentDB, cmd.GetArguments()[i]);
                RedisCommandFrame list_pop(lpop ? "lpop" : "rpop");
                list_pop.AddArg(cmd.GetArguments()[i]);
                RewriteClientCommand(ctx, list_pop);
                return 0;
            }
            if (err != 0 && err != mmkv::ERR_ENTRY_NOT_EXIST && err != mmkv::ERR_DB_NOT_EXIST)
            {
                FillErrorReply(ctx, err);
                return 0;
            }
        }
        if (NULL != ctx.client)
        {
            ctx.client->DetachFD();
            ctx.GetBlockContext().lpop = cmd.GetType() == REDIS_CMD_BLPOP;
            if (timeout > 0)
            {
                ctx.block->blocking_timer_task_id = ctx.client->GetService().GetTimer().ScheduleHeapTask(
                        new BlockListTimeout(&ctx), timeout, -1, SECONDS);
            }
        }
        for (uint32 i = 0; i < cmd.GetArguments().size() - 1; i++)
        {
            AddBlockKey(ctx, cmd.GetArguments()[i]);
        }
        return 0;
    }
Example #2
0
 int Comms::RPopLPush(Context& ctx, RedisCommandFrame& cmd)
 {
     std::string v;
     int err = m_kv_store->RPopLPush(ctx.currentDB, cmd.GetArguments()[0], cmd.GetArguments()[1], v);
     if (err >= 0)
     {
         fill_str_reply(ctx.reply, v);
         FireKeyChangedEvent(ctx, cmd.GetArguments()[0]);
         FireKeyChangedEvent(ctx, cmd.GetArguments()[1]);
         if (cmd.GetType() == REDIS_CMD_BRPOPLPUSH)
         {
             ctx.current_cmd->SetCommand("rpoplpush");
         }
     }
     else
     {
         if (err == mmkv::ERR_ENTRY_NOT_EXIST || err == mmkv::ERR_DB_NOT_EXIST)
         {
             ctx.reply.type = REDIS_REPLY_NIL;
         }
         else
         {
             FillErrorReply(ctx, err);
         }
     }
     return 0;
 }
Example #3
0
	void Master::WriteSlaves(const DBID& dbid, RedisCommandFrame& cmd)
	{
		//DEBUG_LOG("WriteSlaves cmd:%s %u", cmd.ToString().c_str(), cmd.GetType());
		switch (cmd.GetType())
		{
			case REDIS_CMD_SELECT:
			{
				DBID id = 0;
				string_touint32(cmd.GetArguments()[0], id);
				m_backlog.SetCurrentDBID(id);
				break;
			}
			case REDIS_CMD_PING:
			{
				break;
			}
			default:
			{

				if (m_backlog.GetCurrentDBID() != dbid)
				{
					if (!m_server->m_cfg.master_host.empty())
					{
						ERROR_LOG("Can NOT happen since slave instance can NOT generate select command.");
					} else
					{
						RedisCommandFrame select("select %u", dbid);
						select.SetType(REDIS_CMD_SELECT);
						m_backlog.SetCurrentDBID(dbid);
						WriteCmdToSlaves(select);
					}
				}
				break;
			}
		}
		WriteCmdToSlaves(cmd);
	}
Example #4
0
File: keys.cpp Project: boreys/ardb
    int Ardb::Rename(Context& ctx, RedisCommandFrame& cmd)
    {
        bool withnx = cmd.GetType() == REDIS_CMD_RENAMENX;
        if (withnx)
        {
            RedisCommandFrame exists("Exists");
            exists.AddArg(cmd.GetArguments()[1]);
            Exists(ctx, exists);
            if (ctx.reply.integer == 1)
            {
                fill_int_reply(ctx.reply, 0);
                return 0;
            }
        }
        else
        {
            DeleteKey(ctx, cmd.GetArguments()[1]);
        }

        KeyType type = KEY_END;
        GetType(ctx, cmd.GetArguments()[0], type);
        switch (type)
        {
            case SET_META:
            {
                RenameSet(ctx, ctx.currentDB, cmd.GetArguments()[0], ctx.currentDB, cmd.GetArguments()[1]);
                break;
            }
            case LIST_META:
            {
                RenameList(ctx, ctx.currentDB, cmd.GetArguments()[0], ctx.currentDB, cmd.GetArguments()[1]);
                break;
            }
            case ZSET_META:
            {
                RenameZSet(ctx, ctx.currentDB, cmd.GetArguments()[0], ctx.currentDB, cmd.GetArguments()[1]);
                break;
            }
            case HASH_META:
            {
                RenameHash(ctx, ctx.currentDB, cmd.GetArguments()[0], ctx.currentDB, cmd.GetArguments()[1]);
                break;
            }
            case STRING_META:
            {
                RenameString(ctx, ctx.currentDB, cmd.GetArguments()[0], ctx.currentDB, cmd.GetArguments()[1]);
                break;
            }
            case BITSET_META:
            {
                RenameBitset(ctx, ctx.currentDB, cmd.GetArguments()[0], ctx.currentDB, cmd.GetArguments()[1]);
                break;
            }
            default:
            {
                fill_error_reply(ctx.reply, "Invalid type to rename");
                break;
            }
        }
        if (withnx)
        {
            fill_int_reply(ctx.reply, 1);
        }
        else
        {
            fill_status_reply(ctx.reply, "OK");
        }
        return 0;
    }
Example #5
0
    int Comms::Scan(Context& ctx, RedisCommandFrame& cmd)
    {
        StringArray keys;
        std::string pattern;
        uint32 limit = 1000; //return max 1000 keys one time

        int arg_start = 0;
        if (cmd.GetType() != REDIS_CMD_SCAN)
        {
            arg_start = 1;
        }
        if (cmd.GetArguments().size() > arg_start + 1)
        {
            for (uint32 i = arg_start + 1; 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;
                }
            }
        }
        uint32 scan_count_limit = limit * 10;
        uint32 scan_count = 0;
        uint32 scan_cursor = 0;
        if (!string_touint32(cmd.GetArguments()[arg_start], scan_cursor))
        {
            fill_error_reply(ctx.reply, "value is not an integer or out of range");
            return 0;
        }

        RedisReply& r1 = ctx.reply.AddMember();
        RedisReply& r2 = ctx.reply.AddMember();
        r2.type = REDIS_REPLY_ARRAY;
        mmkv::StringArrayResult results(ReplyResultStringAlloc, &r2);
        int new_cursor = 0;
        switch (cmd.GetType())
        {
            case REDIS_CMD_SCAN:
            {
                new_cursor = m_kv_store->Scan(ctx.currentDB, scan_cursor, pattern, scan_count_limit, results);
                break;
            }
            case REDIS_CMD_SSCAN:
            {
                new_cursor = m_kv_store->SScan(ctx.currentDB, cmd.GetArguments()[0], scan_cursor, pattern,
                        scan_count_limit, results);
                break;
            }
            case REDIS_CMD_HSCAN:
            {
                new_cursor = m_kv_store->HScan(ctx.currentDB, cmd.GetArguments()[0], scan_cursor, pattern,
                        scan_count_limit, results);
                break;
            }
            case REDIS_CMD_ZSCAN:
            {
                new_cursor = m_kv_store->ZScan(ctx.currentDB, cmd.GetArguments()[0], scan_cursor, pattern,
                        scan_count_limit, results);
                break;
            }
            default:
            {
                new_cursor = 0;
                break;
            }
        }
        fill_int_reply(r1, new_cursor);
        return 0;
    }