void ExpireCheck::ExpireCheckCallback(const DBID& db, const Slice& key, void* data) { ExpireCheck* e = (ExpireCheck*) data; ArgumentArray args; args.push_back("del"); args.push_back(std::string(key.data(), key.size())); RedisCommandFrame cmd(args); e->m_server->GetMaster().FeedSlaves(NULL, db, cmd); }
int OnRawKeyValue(const Slice& key, const Slice& value) { ArgumentArray args; args.push_back("__SET__"); args.push_back(std::string(key.data(), key.size())); args.push_back(std::string(value.data(), value.size())); RedisCommandFrame cmd(args); conn.conn->Write(cmd); count++; if (count % 10000 == 0) { conn.conn->GetService().Continue(); } return 0; }
inline void FillNextArgument(Buffer& buf, size_t len) { const char* str = buf.GetRawReadBuffer(); buf.AdvanceReadIndex(len); if (m_cmd_seted) { m_args.push_back(std::string(str, len)); } else { m_cmd.append(str, len); m_cmd_seted = true; } }
RedisCommandFrame(const char* fmt, ...) : type(REDIS_CMD_INVALID), m_is_inline(false), m_cmd_seted(false), m_raw_data_size(0) { va_list ap; va_start(ap, fmt); char buf[1024]; vsnprintf(buf, sizeof(buf) - 1, fmt, ap); va_end(ap); char * pch; pch = strtok(buf, " "); while (pch != NULL) { m_args.push_back(std::string(pch)); pch = strtok(NULL, " "); } m_cmd = m_args.front(); m_args.pop_front(); }
Command::ArgumentArray Command::getEffectiveArguments() const { uint effectiveArgumentsStart; switch (_subTypeDesc->controlFlowType) { case kFlowEnd: effectiveArgumentsStart = 0; break; case kFlowNormal: effectiveArgumentsStart = 1; break; case kFlowBranch: effectiveArgumentsStart = 2; break; default: error("Unhandled control flow type '%d'", _subTypeDesc->controlFlowType); } ArgumentArray effectiveArguments; for (uint i = effectiveArgumentsStart; i < _arguments.size(); i++) { effectiveArguments.push_back(_arguments[i]); } return effectiveArguments; }
int LUAInterpreter::CallArdb(lua_State *lua, bool raise_error) { int j, argc = lua_gettop(lua); ArgumentArray cmdargs; /* Require at least one argument */ if (argc == 0) { luaPushError(lua, "Please specify at least one argument for redis.call()"); return 1; } /* Build the arguments vector */ for (j = 0; j < argc; j++) { if (!lua_isstring(lua, j + 1)) break; std::string arg; arg.append(lua_tostring(lua, j + 1), lua_strlen(lua, j + 1)); cmdargs.push_back(arg); } /* Check if one of the arguments passed by the Lua script * is not a string or an integer (lua_isstring() return true for * integers as well). */ if (j != argc) { luaPushError(lua, "Lua redis() command arguments must be strings or integers"); return 1; } /* Setup our fake client for command execution */ RedisCommandFrame cmd(cmdargs); Ardb::RedisCommandHandlerSetting* setting = g_db->FindRedisCommandHandlerSetting(cmd); /* Command lookup */ if (NULL == setting) { luaPushError(lua, "Unknown Redis command called from Lua script"); return -1; } /* There are commands that are not allowed inside scripts. */ if (!setting->IsAllowedInScript()) { luaPushError(lua, "This Redis command is not allowed from scripts"); return -1; } LuaExecContext* ctx = g_lua_exec_ctx.GetValue(); /* Write commands are forbidden against read-only slaves, or if a * command marked as non-deterministic was already called in the context * of this script. */ if (setting->IsWriteCommand()) { if (!g_db->GetConf().master_host.empty() && g_db->GetConf().slave_readonly && !g_db->IsLoadingData() && !(ctx->caller->flags.slave)) { luaPushError(lua, "-READONLY You can't write against a read only slave."); return -1; } } Context& lua_ctx = ctx->exec; RedisReply& reply = lua_ctx.GetReply(); reply.Clear(); lua_ctx.ClearFlags(); lua_ctx.flags.lua = 1; g_db->DoCall(lua_ctx, *setting, cmd); if (raise_error && reply.type != REDIS_REPLY_ERROR) { raise_error = 0; } redisProtocolToLuaType(lua, reply); if (raise_error) { /* If we are here we should have an error in the stack, in the * form of a table with an "err" field. Extract the string to * return the plain error. */ lua_pushstring(lua, "err"); lua_gettable(lua, -2); return lua_error(lua); } return 1; }