Пример #1
0
 RedisReplyArray* CoroRedisClient::SyncMultiCall(RedisCommandFrameArray& cmds, int timeout)
 {
     Clear();
     m_expected_multi_reply_count = cmds.size();
     for (size_t i = 0; i < cmds.size(); i++)
     {
         m_ch->Write(cmds[i]);
     }
     CreateTimeoutTask(timeout);
     if (0 != WaitCoro())
     {
         return NULL;
     }
     if (!m_connect_success)
     {
         m_error_reply.SetErrorReason("client connection closed.");
         FillErrorReply();
         return &m_multi_replies;
     }
     if (IsTimeout())
     {
         m_error_reply.SetErrorReason("server timeout.");
         FillErrorReply();
         return &m_multi_replies;
     }
     CancelTimeoutTask();
     return &m_multi_replies;
 }
Пример #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;
 }
Пример #3
0
OP_NAMESPACE_BEGIN

    int Comms::LIndex(Context& ctx, RedisCommandFrame& cmd)
    {
        int64 index;
        if (!GetInt64Value(ctx, cmd.GetArguments()[1], index))
        {
            return 0;
        }
        std::string v;
        int err = m_kv_store->LIndex(ctx.currentDB, cmd.GetArguments()[0], index, v);
        if (err >= 0)
        {
            fill_str_reply(ctx.reply, v);
        }
        else if (mmkv::ERR_OFFSET_OUTRANGE == err)
        {
            ctx.reply.type = REDIS_REPLY_NIL;
        }
        else
        {
            FillErrorReply(ctx, err);
        }
        return 0;
    }
Пример #4
0
 int Comms::LInsert(Context& ctx, RedisCommandFrame& cmd)
 {
     bool before_or_after = false;
     if (!strcasecmp(cmd.GetArguments()[1].c_str(), "before"))
     {
         before_or_after = true;
     }
     else if (!strcasecmp(cmd.GetArguments()[1].c_str(), "after"))
     {
         before_or_after = false;
     }
     else
     {
         fill_error_reply(ctx.reply, "Syntax error");
         return 0;
     }
     int err = m_kv_store->LInsert(ctx.currentDB, cmd.GetArguments()[0], before_or_after, cmd.GetArguments()[2],
             cmd.GetArguments()[3]);
     if (err >= 0 || -1 == err)
     {
         fill_int_reply(ctx.reply, err);
         if (err > 0)
         {
             FireKeyChangedEvent(ctx, cmd.GetArguments()[0]);
         }
     }
     else
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }
Пример #5
0
 int Comms::Del(Context& ctx, RedisCommandFrame& cmd)
 {
     mmkv::DataArray fs;
     for (uint32 i = 0; i < cmd.GetArguments().size(); i++)
     {
         fs.push_back(cmd.GetArguments()[i]);
     }
     int err = m_kv_store->Del(ctx.currentDB, fs);
     if (err >= 0)
     {
         if (err > 0)
         {
             for (uint32 i = 0; i < cmd.GetArguments().size(); i++)
             {
                 FireKeyChangedEvent(ctx, cmd.GetArguments()[i]);
             }
         }
         fill_int_reply(ctx.reply, err);
     }
     else
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }
Пример #6
0
 int Comms::LLen(Context& ctx, RedisCommandFrame& cmd)
 {
     int err = m_kv_store->LLen(ctx.currentDB, cmd.GetArguments()[0]);
     if (err >= 0)
     {
         fill_int_reply(ctx.reply, err);
     }
     else
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }
Пример #7
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;
    }
Пример #8
0
 int Comms::Rename(Context& ctx, RedisCommandFrame& cmd)
 {
     int err = m_kv_store->Rename(ctx.currentDB, cmd.GetArguments()[0], cmd.GetArguments()[1]);
     if (err >= 0)
     {
         FireKeyChangedEvent(ctx, cmd.GetArguments()[0]);
         FireKeyChangedEvent(ctx, cmd.GetArguments()[1]);
         fill_ok_reply(ctx.reply);
     }
     else
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }
Пример #9
0
 int Comms::LRange(Context& ctx, RedisCommandFrame& cmd)
 {
     int64 start, end;
     if (!GetInt64Value(ctx, cmd.GetArguments()[1], start) || !GetInt64Value(ctx, cmd.GetArguments()[2], end))
     {
         return 0;
     }
     ctx.reply.type = REDIS_REPLY_ARRAY;
     mmkv::StringArrayResult vs(ReplyResultStringAlloc, &ctx.reply);
     int err = m_kv_store->LRange(ctx.currentDB, cmd.GetArguments()[0], start, end, vs);
     if (err < 0)
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }
Пример #10
0
 void Comms::WakeBlockedList(Context& ctx, const std::string& key)
 {
     std::string v;
     int err =
             ctx.GetBlockContext().lpop ?
                     m_kv_store->LPop(ctx.currentDB, key, v) : m_kv_store->RPop(ctx.currentDB, key, v);
     if (0 == err && !v.empty())
     {
         if (ctx.GetBlockContext().push_key.empty())
         {
             RedisReply& r1 = ctx.reply.AddMember();
             RedisReply& r2 = ctx.reply.AddMember();
             fill_str_reply(r1, key);
             fill_str_reply(r2, v);
             if (!ctx.flags.no_wal)
             {
                 RedisCommandFrame list_pop(ctx.GetBlockContext().lpop ? "lpop" : "rpop");
                 list_pop.AddArg(key);
                 m_repl.WriteWAL(ctx.currentDB, list_pop);
             }
         }
         else
         {
             err = m_kv_store->RPush(ctx.currentDB, ctx.GetBlockContext().push_key, v);
             if (err < 0)
             {
                 ctx.GetBlockContext().lpop ?
                         m_kv_store->LPush(ctx.currentDB, key, v) : m_kv_store->RPush(ctx.currentDB, key, v);
                 FillErrorReply(ctx, err);
             }
             else
             {
                 fill_str_reply(ctx.reply, v);
                 if (!ctx.flags.no_wal)
                 {
                     RedisCommandFrame rpoplpush("rpoplpush");
                     rpoplpush.AddArg(key);
                     m_repl.WriteWAL(ctx.currentDB, rpoplpush);
                 }
             }
         }
         ctx.client->Write(ctx.reply);
         ctx.client->AttachFD();
         ClearBlockKeys(ctx);
     }
 }
Пример #11
0
 int Comms::Persist(Context& ctx, RedisCommandFrame& cmd)
 {
     int err = m_kv_store->Persist(ctx.currentDB, cmd.GetArguments()[0]);
     if (err >= 0)
     {
         if (err > 0)
         {
             FireKeyChangedEvent(ctx, cmd.GetArguments()[0]);
         }
         fill_int_reply(ctx.reply, err);
     }
     else
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }
Пример #12
0
 int Comms::LSet(Context& ctx, RedisCommandFrame& cmd)
 {
     int64 index;
     if (!GetInt64Value(ctx, cmd.GetArguments()[1], index))
     {
         return 0;
     }
     int err = m_kv_store->LSet(ctx.currentDB, cmd.GetArguments()[0], index, cmd.GetArguments()[2]);
     if (err >= 0)
     {
         fill_ok_reply(ctx.reply);
         FireKeyChangedEvent(ctx, cmd.GetArguments()[0]);
     }
     else
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }
Пример #13
0
 int Comms::LTrim(Context& ctx, RedisCommandFrame& cmd)
 {
     int64 start, end;
     if (!GetInt64Value(ctx, cmd.GetArguments()[1], start) || !GetInt64Value(ctx, cmd.GetArguments()[2], end))
     {
         return 0;
     }
     int err = m_kv_store->LTrim(ctx.currentDB, cmd.GetArguments()[0], start, end);
     if (err >= 0)
     {
         fill_ok_reply(ctx.reply);
         FireKeyChangedEvent(ctx, cmd.GetArguments()[0]);
     }
     else
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }
Пример #14
0
 int Comms::RPush(Context& ctx, RedisCommandFrame& cmd)
 {
     mmkv::DataArray fs;
     for (uint32 i = 1; i < cmd.GetArguments().size(); i++)
     {
         fs.push_back(cmd.GetArguments()[i]);
     }
     int err = m_kv_store->RPush(ctx.currentDB, cmd.GetArguments()[0], fs);
     if (err >= 0)
     {
         fill_int_reply(ctx.reply, err);
         FireKeyChangedEvent(ctx, cmd.GetArguments()[0]);
         WakeBlockingListsByKey(ctx, cmd.GetArguments()[0]);
     }
     else
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }
Пример #15
0
 int Comms::Expireat(Context& ctx, RedisCommandFrame& cmd)
 {
     uint64 v = 0;
     if (!check_uint64_arg(ctx.reply, cmd.GetArguments()[1], v))
     {
         return 0;
     }
     int err = m_kv_store->PExpireat(ctx.currentDB, cmd.GetArguments()[0], v * 1000);
     if (err >= 0)
     {
         if (err > 0)
         {
             FireKeyChangedEvent(ctx, cmd.GetArguments()[0]);
         }
         fill_int_reply(ctx.reply, err);
     }
     else
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }
Пример #16
0
 int Comms::RPop(Context& ctx, RedisCommandFrame& cmd)
 {
     std::string v;
     int err = m_kv_store->RPop(ctx.currentDB, cmd.GetArguments()[0], v);
     if (err >= 0)
     {
         fill_str_reply(ctx.reply, v);
         FireKeyChangedEvent(ctx, cmd.GetArguments()[0]);
     }
     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;
 }
Пример #17
0
 int Comms::LRem(Context& ctx, RedisCommandFrame& cmd)
 {
     int64 count;
     if (!GetInt64Value(ctx, cmd.GetArguments()[1], count))
     {
         return 0;
     }
     int err = m_kv_store->LRem(ctx.currentDB, cmd.GetArguments()[0], count, cmd.GetArguments()[2]);
     if (err >= 0)
     {
         fill_int_reply(ctx.reply, err);
         if (err > 0)
         {
             FireKeyChangedEvent(ctx, cmd.GetArguments()[0]);
         }
     }
     else
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }
Пример #18
0
 int Comms::Move(Context& ctx, RedisCommandFrame& cmd)
 {
     DBID dst = 0;
     if (!string_touint32(cmd.GetArguments()[1], dst))
     {
         fill_error_reply(ctx.reply, "value is not an integer or out of range");
         return 0;
     }
     int err = m_kv_store->Move(ctx.currentDB, cmd.GetArguments()[0], dst);
     if (err >= 0)
     {
         if (err > 0)
         {
             FireKeyChangedEvent(ctx, cmd.GetArguments()[0]);
             FireKeyChangedEvent(ctx, dst, cmd.GetArguments()[0]);
         }
         fill_int_reply(ctx.reply, err);
     }
     else
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }
Пример #19
0
 int Comms::Sort(Context& ctx, RedisCommandFrame& cmd)
 {
     bool is_desc = false, with_alpha = false, with_limit = false;
     const ArgumentArray& args = cmd.GetArguments();
     const std::string& key = args[0];
     std::string by, store_dst;
     mmkv::StringArray get_patterns;
     int limit_offset = 0, limit_count = -1;
     for (uint32 i = 1; i < args.size(); i++)
     {
         if (!strcasecmp(args[i].c_str(), "asc"))
         {
             is_desc = false;
         }
         else if (!strcasecmp(args[i].c_str(), "desc"))
         {
             is_desc = true;
         }
         else if (!strcasecmp(args[i].c_str(), "alpha"))
         {
             with_alpha = true;
         }
         else if (!strcasecmp(args[i].c_str(), "limit") && (i + 2) < args.size())
         {
             with_limit = true;
             if (!string_toint32(args[i + 1], limit_offset) || !string_toint32(args[i + 2], limit_count))
             {
                 return false;
             }
             i += 2;
         }
         else if (!strcasecmp(args[i].c_str(), "store") && i < args.size() - 1)
         {
             store_dst = args[i + 1];
             i++;
         }
         else if (!strcasecmp(args[i].c_str(), "by") && i < args.size() - 1)
         {
             by = args[i + 1];
             i++;
         }
         else if (!strcasecmp(args[i].c_str(), "get") && i < args.size() - 1)
         {
             get_patterns.push_back(args[i + 1].c_str());
             i++;
         }
         else
         {
             DEBUG_LOG("Invalid sort option:%s", args[i].c_str());
             return false;
         }
     }
     int err = 0;
     if (store_dst.empty())
     {
         ctx.reply.type = REDIS_REPLY_ARRAY;
         mmkv::StringArrayResult results(ReplyResultStringAlloc, &ctx.reply);
         err = m_kv_store->Sort(ctx.currentDB, key, by, limit_offset, limit_count, get_patterns, is_desc, with_alpha,
                 store_dst, results);
     }
     else
     {
         ctx.reply.type = REDIS_REPLY_INTEGER;
         mmkv::StringArrayResult results;
         err = m_kv_store->Sort(ctx.currentDB, key, by, limit_offset, limit_count, get_patterns, is_desc, with_alpha,
                 store_dst, results);
         ctx.reply.integer = err >= 0 ? err : 0;
         if(err > 0)
         {
             FireKeyChangedEvent(ctx, store_dst);
         }
     }
     if (err < 0)
     {
         FillErrorReply(ctx, err);
     }
     return 0;
 }