int value_convert_to_number(ValueObject& v) { if (v.type == EMPTY) { return -1; } if (v.type != RAW) { return 0; } int64_t intv; double dv; if (raw_toint64(v.v.raw->GetRawReadBuffer(), v.v.raw->ReadableBytes(), intv)) { v.Clear(); v.type = INTEGER; v.v.int_v = intv; return 1; } else if (raw_todouble(v.v.raw->GetRawReadBuffer(), v.v.raw->ReadableBytes(), dv)) { v.Clear(); v.type = DOUBLE; v.v.double_v = dv; return 1; } return -1; }
void smart_fill_value(const Slice& value, ValueObject& valueobject) { if (value.empty()) { valueobject.type = EMPTY; return; } int64_t intv; double doublev; char first_char = value.data()[0]; if (first_char != '+' && value.data()[0] != '-' && (first_char < '0' || first_char > '9')) { valueobject.type = RAW; char* v = const_cast<char*>(value.data()); valueobject.v.raw = new Buffer(v, 0, value.size()); } else { if (raw_toint64(value.data(), value.size(), intv)) { valueobject.type = INTEGER; valueobject.v.int_v = intv; } else if (raw_todouble(value.data(), value.size(), doublev)) { valueobject.type = DOUBLE; valueobject.v.double_v = doublev; } else { valueobject.type = RAW; char* v = const_cast<char*>(value.data()); valueobject.v.raw = new Buffer(v, 0, value.size()); } } }
int ArdbServer::Set(ArdbConnContext& ctx, RedisCommandFrame& cmd) { const std::string& key = cmd.GetArguments()[0]; const std::string& value = cmd.GetArguments()[1]; int ret = 0; if (cmd.GetArguments().size() == 2) { ret = m_db->Set(ctx.currentDB, key, value); } else { uint32 i = 0; uint64 px = 0, ex = 0; for (i = 2; i < cmd.GetArguments().size(); i++) { std::string tmp = string_tolower(cmd.GetArguments()[i]); if (tmp == "ex" || tmp == "px") { int64 iv; if (!raw_toint64(cmd.GetArguments()[i + 1].c_str(), cmd.GetArguments()[i + 1].size(), iv) || iv < 0) { fill_error_reply(ctx.reply, "value is not an integer or out of range"); return 0; } if (tmp == "px") { px = iv; } else { ex = iv; } i++; } else { break; } } bool hasnx = false, hasxx = false; bool syntaxerror = false; if (i < cmd.GetArguments().size() - 1) { syntaxerror = true; } if (i == cmd.GetArguments().size() - 1) { std::string cmp = string_tolower(cmd.GetArguments()[i]); if (cmp != "nx" && cmp != "xx") { syntaxerror = true; } else { hasnx = cmp == "nx"; hasxx = cmp == "xx"; } } if (syntaxerror) { fill_error_reply(ctx.reply, "syntax error"); return 0; } int nxx = 0; if (hasnx) { nxx = -1; } if (hasxx) { nxx = 1; } ret = m_db->Set(ctx.currentDB, key, value, ex, px, nxx); } if (0 == ret) { fill_status_reply(ctx.reply, "OK"); } else { switch (ret) { case ERR_INVALID_TYPE: { fill_error_reply(ctx.reply, "invalid type"); break; } case ERR_KEY_EXIST: case ERR_NOT_EXIST: { ctx.reply.type = REDIS_REPLY_NIL; break; } default: { fill_error_reply(ctx.reply, "set failed"); break; } } } return 0; }