Пример #1
0
 int Ardb::Keys(Context& ctx, RedisCommandFrame& cmd)
 {
     KeysOptions opt;
     opt.op = OP_GET;
     opt.pattern = cmd.GetArguments()[0];
     uint32 limit = 100000; //return max 100000 keys one time
     if (cmd.GetArguments().size() > 1)
     {
         for (uint32 i = 1; i < cmd.GetArguments().size(); i++)
         {
             if (!strcasecmp(cmd.GetArguments()[i].c_str(), "limit"))
             {
                 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
             {
                 fill_error_reply(ctx.reply, "Syntax error, try KEYS ");
                 return 0;
             }
         }
     }
     opt.limit = limit;
     KeysOperation(ctx, opt);
     return 0;
 }
Пример #2
0
Файл: geo.cpp Проект: cvan/ardb
    /*
     *  GEOADD key MERCATOR|WGS84 x y value [x y value....]
     */
    int Ardb::GeoAdd(Context& ctx, RedisCommandFrame& cmd)
    {
        GeoAddOptions options;
        std::string err;
        if (0 != options.Parse(cmd.GetArguments(), err, 1))
        {
            fill_error_reply(ctx.reply, "%s", err.c_str());
            return 0;
        }
        GeoHashRange lat_range, lon_range;
        GeoHashHelper::GetCoordRange(options.coord_type, lat_range, lon_range);

        KeyLockerGuard keylock(m_key_lock, ctx.currentDB, cmd.GetArguments()[0]);
        ValueObject meta;
        int ret = GetMetaValue(ctx, cmd.GetArguments()[0], ZSET_META, meta);
        CHECK_ARDB_RETURN_VALUE(ctx.reply, ret);

        RedisCommandFrame zadd("zadd");
        zadd.AddArg(cmd.GetArguments()[0]);
        BatchWriteGuard guard(GetKeyValueEngine());
        GeoPointArray::iterator git = options.points.begin();
        uint32 count = 0;
        while (git != options.points.end())
        {
            GeoPoint& point = *git;
            if (point.x < lon_range.min || point.x > lon_range.max || point.y < lat_range.min
                    || point.y > lat_range.max)
            {
                guard.MarkFailed();
                break;
            }
            GeoHashBits hash;
            geohash_encode(&lat_range, &lon_range, point.y, point.x, 30, &hash);
            GeoHashFix60Bits score = hash.bits;
            Data score_value;
            score_value.SetInt64((int64) score);
            Data element;
            element.SetString(point.value, true);
            count += ZSetAdd(ctx, meta, element, score_value, NULL);

            std::string tmp;
            score_value.GetDecodeString(tmp);
            zadd.AddArg(tmp);
            element.GetDecodeString(tmp);
            zadd.AddArg(tmp);
            git++;
        }
        if (guard.Success())
        {
            SetKeyValue(ctx, meta);
            RewriteClientCommand(ctx, zadd);
            fill_int_reply(ctx.reply, count);
        }
        else
        {
            fill_error_reply(ctx.reply, "Invalid arguments");
        }
        return 0;
    }
Пример #3
0
 int Ardb::BRPop(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;
     }
     for (uint32 i = 0; i < cmd.GetArguments().size() - 1; i++)
     {
         if (ListPop(ctx, cmd.GetArguments()[i], false) == 0 && ctx.reply.type == REDIS_REPLY_STRING)
         {
             RedisReply& r1 = ctx.reply.AddMember();
             RedisReply& r2 = ctx.reply.AddMember();
             fill_str_reply(r1, cmd.GetArguments()[i]);
             fill_str_reply(r2, ctx.reply.str);
             return 0;
         }
     }
     for (uint32 i = 0; i < cmd.GetArguments().size() - 1; i++)
     {
         AddBlockKey(ctx, cmd.GetArguments()[i]);
     }
     if (NULL != ctx.client)
     {
         ctx.client->DetachFD();
         if (timeout > 0)
         {
             ctx.block->blocking_timer_task_id = ctx.client->GetService().GetTimer().ScheduleHeapTask(
                     new BlockConnectionTimeout(&ctx), timeout, -1, SECONDS);
         }
     }
     return 0;
 }
Пример #4
0
 int Ardb::BRPopLPush(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;
     }
     RPopLPush(ctx, cmd);
     if (ctx.reply.type == REDIS_REPLY_NIL)
     {
         //block;
         AddBlockKey(ctx, cmd.GetArguments()[0]);
         if (NULL != ctx.client)
         {
             ctx.client->DetachFD();
             if (timeout > 0)
             {
                 ctx.block->blocking_timer_task_id = ctx.client->GetService().GetTimer().ScheduleHeapTask(
                         new BlockConnectionTimeout(&ctx), timeout, -1, SECONDS);
             }
         }
         ctx.reply.type = 0;
     }
     return 0;
 }
Пример #5
0
 int Ardb::HMSet(Context& ctx, RedisCommandFrame& cmd)
 {
     if (m_cfg.replace_for_hmset)
     {
         HReplace(ctx, cmd);
         return 0;
     }
     if ((cmd.GetArguments().size() - 1) % 2 != 0)
     {
         fill_error_reply(ctx.reply, "wrong number of arguments for HMSet");
         return 0;
     }
     ValueObject meta;
     int err = GetMetaValue(ctx, cmd.GetArguments()[0], HASH_META, meta);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     DataMap fs;
     for (uint32 i = 1; i < cmd.GetArguments().size(); i += 2)
     {
         Data f(cmd.GetArguments()[i]), v(cmd.GetArguments()[i + 1]);
         fs[f] = v;
     }
     HashMultiSet(ctx, meta, fs);
     fill_status_reply(ctx.reply, "OK");
     return 0;
 }
Пример #6
0
 int Ardb::HIncrbyFloat(Context& ctx, RedisCommandFrame& cmd)
 {
     double increment, val = 0;
     if (!GetDoubleValue(ctx, cmd.GetArguments()[2], increment))
     {
         return 0;
     }
     ValueObject meta;
     int err = GetMetaValue(ctx, cmd.GetArguments()[0], HASH_META, meta);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     Data value;
     Data field(cmd.GetArguments()[1]);
     if (0 == err)
     {
         HashGet(ctx, meta, field, value);
         if (!value.GetDouble(val))
         {
             fill_error_reply(ctx.reply, "value is not a float or out of range");
             return 0;
         }
     }
     val += increment;
     std::string tmp;
     fast_dtoa(val, 10, tmp);
     value.SetString(tmp, false);
     HashSet(ctx, meta, field, value);
     fill_str_reply(ctx.reply, tmp);
     return 0;
 }
Пример #7
0
 int Ardb::HIncrby(Context& ctx, RedisCommandFrame& cmd)
 {
     int64 increment, val = 0;
     if (!GetInt64Value(ctx, cmd.GetArguments()[2], increment))
     {
         return 0;
     }
     ValueObject meta;
     int err = GetMetaValue(ctx, cmd.GetArguments()[0], HASH_META, meta);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, err);
     Data field(cmd.GetArguments()[1]);
     Data value;
     if (err == 0)
     {
         err = HashGet(ctx, meta, field, value);
     }
     if (err == ERR_NOT_EXIST)
     {
         value.SetInt64(increment);
     }
     else
     {
         if (!value.GetInt64(val))
         {
             fill_error_reply(ctx.reply, "value is not a integer or out of range");
             return 0;
         }
         value.SetInt64(val + increment);
     }
     HashSet(ctx, meta, field, value);
     fill_int_reply(ctx.reply, val + increment);
     return 0;
 }
Пример #8
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;
 }
Пример #9
0
 int ArdbServer::Auth(ArdbConnContext& ctx, RedisCommandFrame& cmd)
 {
     if (m_cfg.requirepass.empty())
     {
         fill_error_reply(ctx.reply, "Client sent AUTH, but no password is set");
     }
     else if (m_cfg.requirepass != cmd.GetArguments()[0])
     {
         ctx.authenticated = false;
         fill_error_reply(ctx.reply, "invalid password");
     }
     else
     {
         ctx.authenticated = true;
         fill_status_reply(ctx.reply, "OK");
     }
     return 0;
 }
Пример #10
0
 int Ardb::HMIncrby(Context& ctx, RedisCommandFrame& cmd)
 {
     if ((cmd.GetArguments().size() - 1) % 2 != 0)
     {
         fill_error_reply(ctx.reply, "wrong number of arguments for HMIncrby");
         return 0;
     }
     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;
     DataMap fs;
     Int64Array vs;
     for (uint32 i = 1; i < cmd.GetArguments().size(); i += 2)
     {
         int64 inc = 0;
         if (!GetInt64Value(ctx, cmd.GetArguments()[i + 1], inc))
         {
             return 0;
         }
         Data field(cmd.GetArguments()[i]);
         if (err == ERR_NOT_EXIST)
         {
             fs[field].SetInt64(inc);
             vs.push_back(inc);
         }
         else
         {
             Data value;
             HashGet(ctx, meta, field, value);
             int64 val = 0;
             if (!value.GetInt64(val))
             {
                 fill_error_reply(ctx.reply, "value is not a float or out of range");
                 return 0;
             }
             fs[field].SetInt64(inc + val);
             vs.push_back(inc + val);
         }
     }
     HashMultiSet(ctx, meta, fs);
     fill_int_array_reply(ctx.reply, vs);
     return 0;
 }
Пример #11
0
 int ArdbServer::Decrby(ArdbConnContext& ctx, RedisCommandFrame& cmd)
 {
     int64 decrement, val;
     if (!string_toint64(cmd.GetArguments()[1], decrement))
     {
         fill_error_reply(ctx.reply, "value is not an integer or out of range");
         return 0;
     }
     int ret = m_db->Decrby(ctx.currentDB, cmd.GetArguments()[0], decrement, val);
     if (ret == 0)
     {
         fill_int_reply(ctx.reply, val);
     }
     else
     {
         fill_error_reply(ctx.reply, "value is not an integer or out of range");
     }
     return 0;
 }
Пример #12
0
 int ArdbServer::IncrbyFloat(ArdbConnContext& ctx, RedisCommandFrame& cmd)
 {
     double increment, val;
     if (!string_todouble(cmd.GetArguments()[1], increment))
     {
         fill_error_reply(ctx.reply, "value is not a float or out of range");
         return 0;
     }
     int ret = m_db->IncrbyFloat(ctx.currentDB, cmd.GetArguments()[0], increment, val);
     if (ret == 0)
     {
         fill_double_reply(ctx.reply, val);
     }
     else
     {
         fill_error_reply(ctx.reply, "value is not a float or out of range");
     }
     return 0;
 }
Пример #13
0
 /*
  * CACHE LOAD|EVICT|STATUS key
  */
 int Ardb::Cache(Context& ctx, RedisCommandFrame& cmd)
 {
     int ret = 0;
     if (!strcasecmp(cmd.GetArguments()[0].c_str(), "load"))
     {
         KeyType type = KEY_END;
         GetType(ctx, cmd.GetArguments()[1], type);
         if (type != KEY_END)
         {
             CacheLoadOptions options;
             options.deocode_geo = true;
             ret = m_cache.Load(ctx.currentDB, cmd.GetArguments()[1], type, options);
         }
         else
         {
             ret = ERR_INVALID_TYPE;
         }
     }
     else if (!strcasecmp(cmd.GetArguments()[0].c_str(), "evict"))
     {
         ret = m_cache.Evict(ctx.currentDB, cmd.GetArguments()[1]);
     }
     else if (!strcasecmp(cmd.GetArguments()[0].c_str(), "status"))
     {
         std::string status = m_cache.Status(ctx.currentDB, cmd.GetArguments()[1]);
         fill_str_reply(ctx.reply, status);
         return 0;
     }
     else
     {
         fill_error_reply(ctx.reply, "Syntax error, try CACHE (LOAD | EVICT | STATUS) key");
         return 0;
     }
     if (ret == 0)
     {
         fill_status_reply(ctx.reply, "OK");
     }
     else
     {
         fill_error_reply(ctx.reply, "Failed to cache load/evict/status key:%s", cmd.GetArguments()[1].c_str());
     }
     return 0;
 }
Пример #14
0
 int ArdbServer::Select(ArdbConnContext& ctx, RedisCommandFrame& cmd)
 {
     if (!string_touint32(cmd.GetArguments()[0], ctx.currentDB) || ctx.currentDB > 0xFFFFFF)
     {
         fill_error_reply(ctx.reply, "value is not an integer or out of range");
         return 0;
     }
     m_clients_holder.ChangeCurrentDB(ctx.conn, ctx.currentDB);
     fill_status_reply(ctx.reply, "OK");
     return 0;
 }
Пример #15
0
 int Ardb::Discard(Context& ctx, RedisCommandFrame& cmd)
 {
     if (!ctx.InTransc())
     {
         fill_error_reply(ctx.reply, "DISCARD without MULTI");
         return 0;
     }
     ctx.ClearTransc();
     fill_status_reply(ctx.reply, "OK");
     return 0;
 }
Пример #16
0
 int Ardb::Multi(Context& ctx, RedisCommandFrame& cmd)
 {
     if (ctx.InTransc())
     {
         fill_error_reply(ctx.reply, "MULTI calls can not be nested");
         return 0;
     }
     ctx.GetTransc().in_transc = true;
     fill_status_reply(ctx.reply, "OK");
     return 0;
 }
Пример #17
0
 /*
  *  GEOADD key MERCATOR|WGS84 x y value  [attr_name attr_value ...]
  */
 int ArdbServer::GeoAdd(ArdbConnContext& ctx, RedisCommandFrame& cmd)
 {
     GeoAddOptions options;
     std::string err;
     if (0 != options.Parse(cmd.GetArguments(), err, 1))
     {
         fill_error_reply(ctx.reply, "%s", err.c_str());
         return 0;
     }
     int ret = m_db->GeoAdd(ctx.currentDB, cmd.GetArguments()[0], options);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, ret);
     if (ret >= 0)
     {
         fill_status_reply(ctx.reply, "OK");
     }
     else
     {
         fill_error_reply(ctx.reply, "Failed to %s", cmd.ToString().c_str());
     }
     return 0;
 }
Пример #18
0
 int ArdbServer::PSetEX(ArdbConnContext& ctx, RedisCommandFrame& cmd)
 {
     uint32 mills;
     if (!string_touint32(cmd.GetArguments()[1], mills))
     {
         fill_error_reply(ctx.reply, "value is not an integer or out of range");
         return 0;
     }
     m_db->PSetEx(ctx.currentDB, cmd.GetArguments()[0], cmd.GetArguments()[2], mills);
     fill_status_reply(ctx.reply, "OK");
     return 0;
 }
Пример #19
0
 int ArdbServer::SetRange(ArdbConnContext& ctx, RedisCommandFrame& cmd)
 {
     int32 offset;
     if (!string_toint32(cmd.GetArguments()[1], offset))
     {
         fill_error_reply(ctx.reply, "value is not an integer or out of range");
         return 0;
     }
     int ret = m_db->SetRange(ctx.currentDB, cmd.GetArguments()[0], offset, cmd.GetArguments()[2]);
     fill_int_reply(ctx.reply, ret);
     return 0;
 }
Пример #20
0
 int ArdbServer::GetRange(ArdbConnContext& ctx, RedisCommandFrame& cmd)
 {
     int32 start, end;
     if (!string_toint32(cmd.GetArguments()[1], start) || !string_toint32(cmd.GetArguments()[2], end))
     {
         fill_error_reply(ctx.reply, "value is not an integer or out of range");
         return 0;
     }
     std::string v;
     m_db->GetRange(ctx.currentDB, cmd.GetArguments()[0], start, end, v);
     fill_str_reply(ctx.reply, v);
     return 0;
 }
Пример #21
0
 int Ardb::Sort(Context& ctx, RedisCommandFrame& cmd)
 {
     DataArray vs;
     std::string key = cmd.GetArguments()[0];
     SortOptions options;
     if (!options.Parse(cmd.GetArguments(), 1))
     {
         fill_error_reply(ctx.reply, "Invalid SORT command or invalid state for SORT.");
         return 0;
     }
     int ret = SortCommand(ctx, key, options, vs);
     ctx.reply.Clear();
     if (ret < 0)
     {
         fill_error_reply(ctx.reply, "Invalid SORT command or invalid state for SORT.");
     }
     else
     {
         fill_array_reply(ctx.reply, vs);
     }
     return 0;
 }
Пример #22
0
 int Ardb::Exec(Context& ctx, RedisCommandFrame& cmd)
 {
     if (!ctx.InTransc())
     {
         fill_error_reply(ctx.reply, "EXEC without MULTI");
         return 0;
     }
     if (ctx.GetTransc().abort)
     {
         ctx.reply.type = REDIS_REPLY_NIL;
         ctx.ClearTransc();
         return 0;
     }
     LockGuard<ThreadMutex> guard(g_transc_mutex); //only one transc allowed exec at the same time in multi threads
     RedisCommandFrameArray::iterator it = ctx.GetTransc().cached_cmds.begin();
     Context transc_ctx;
     transc_ctx.currentDB = ctx.currentDB;
     while (it != ctx.GetTransc().cached_cmds.end())
     {
         RedisReply& r = ctx.reply.AddMember();
         RedisCommandHandlerSetting* setting = FindRedisCommandHandlerSetting(*it);
         if(NULL != setting)
         {
             transc_ctx.reply.Clear();
             DoCall(transc_ctx, *setting, *it);
             r.Clone(transc_ctx.reply);
         }
         else
         {
             fill_error_reply(r, "unknown command '%s'", it->GetCommand().c_str());
         }
         it++;
     }
     ctx.currentDB = transc_ctx.currentDB;
     ctx.ClearTransc();
     UnwatchKeys(ctx);
     return 0;
 }
Пример #23
0
 int ArdbServer::Decr(ArdbConnContext& ctx, RedisCommandFrame& cmd)
 {
     int64_t val;
     int ret = m_db->Decr(ctx.currentDB, cmd.GetArguments()[0], val);
     if (ret == 0)
     {
         fill_int_reply(ctx.reply, val);
     }
     else
     {
         fill_error_reply(ctx.reply, "value is not an integer or out of range");
     }
     return 0;
 }
Пример #24
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;
    }
Пример #25
0
 int Ardb::Watch(Context& ctx, RedisCommandFrame& cmd)
 {
     if (ctx.InTransc())
     {
         fill_error_reply(ctx.reply, "WATCH inside MULTI is not allowed");
         return 0;
     }
     for (uint32 i = 0; i < cmd.GetArguments().size(); i++)
     {
         WatchForKey(ctx, cmd.GetArguments()[i]);
     }
     fill_status_reply(ctx.reply, "OK");
     return 0;
 }
Пример #26
0
 int ArdbServer::Append(ArdbConnContext& ctx, RedisCommandFrame& cmd)
 {
     const std::string& key = cmd.GetArguments()[0];
     const std::string& value = cmd.GetArguments()[1];
     int ret = m_db->Append(ctx.currentDB, key, value);
     if (ret > 0)
     {
         fill_int_reply(ctx.reply, ret);
     }
     else
     {
         fill_error_reply(ctx.reply, "failed to append key:%s", key.c_str());
     }
     return 0;
 }
Пример #27
0
 int ArdbServer::GeoSearch(ArdbConnContext& ctx, RedisCommandFrame& cmd)
 {
     GeoSearchOptions options;
     std::string err;
     if (0 != options.Parse(cmd.GetArguments(), err, 1))
     {
         fill_error_reply(ctx.reply, "%s", err.c_str());
         return 0;
     }
     ValueDataDeque res;
     int ret = m_db->GeoSearch(ctx.currentDB, cmd.GetArguments()[0], options, res);
     CHECK_ARDB_RETURN_VALUE(ctx.reply, ret);
     fill_array_reply(ctx.reply, res);
     return 0;
 }
Пример #28
0
 int Ardb::RenameList(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, LIST_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_ENCODING_ZIPLIST)
     {
         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
     {
         ListIterator iter;
         ListIter(ctx, v, iter, false);
         tmpctx.currentDB = dstdb;
         ValueObject dstmeta;
         dstmeta.key.type = KEY_META;
         dstmeta.key.key = dstkey;
         dstmeta.type = LIST_META;
         dstmeta.meta.SetFlag(COLLECTION_FLAG_SEQLIST);
         dstmeta.meta.SetEncoding(COLLECTION_ENCODING_ZIPLIST);
         BatchWriteGuard guard(GetKeyValueEngine());
         while (iter.Valid())
         {
             std::string tmpstr;
             ListInsert(tmpctx, dstmeta, NULL, iter.Element()->GetDecodeString(tmpstr), false, false);
             iter.Next();
         }
         SetKeyValue(tmpctx, dstmeta);
         tmpctx.currentDB = srcdb;
         DeleteKey(tmpctx, srckey);
     }
     ctx.data_change = true;
     return 0;
 }
Пример #29
0
 int Ardb::LInsert(Context& ctx, RedisCommandFrame& cmd)
 {
     bool head = false;
     if (!strcasecmp(cmd.GetArguments()[1].c_str(), "before"))
     {
         head = true;
     }
     else if (!strcasecmp(cmd.GetArguments()[1].c_str(), "after"))
     {
         head = false;
     }
     else
     {
         fill_error_reply(ctx.reply, "Syntax error");
         return 0;
     }
     return ListInsert(ctx, cmd.GetArguments()[0], &(cmd.GetArguments()[2]), cmd.GetArguments()[3], head, true);
 }
Пример #30
0
 int ArdbServer::MSet(ArdbConnContext& ctx, RedisCommandFrame& cmd)
 {
     if (cmd.GetArguments().size() % 2 != 0)
     {
         fill_error_reply(ctx.reply, "wrong number of arguments for MSET");
         return 0;
     }
     SliceArray keys;
     SliceArray vals;
     for (uint32 i = 0; i < cmd.GetArguments().size(); i += 2)
     {
         keys.push_back(cmd.GetArguments()[i]);
         vals.push_back(cmd.GetArguments()[i + 1]);
     }
     m_db->MSet(ctx.currentDB, keys, vals);
     fill_status_reply(ctx.reply, "OK");
     return 0;
 }